【问题标题】:Export to single HTML with embedded images using Jasper Report使用 Jasper Report 导出到带有嵌入图像的单个 HTML
【发布时间】:2011-10-20 00:28:30
【问题描述】:

Jasper 报告可以导出到带有嵌入图像的单个 HTML 吗?

我将碧玉报告输出为单个 Excel 文件、PDF、RTF。 但是多播放 HTML 文件。 对我来说,管理的不是单个报告文件,而是 HTML 案例中的许多文件和文件夹。

【问题讨论】:

    标签: java html jsp reporting jasper-reports


    【解决方案1】:

    我认为 jasper 报告没有内置对此的支持,因此您必须推出自己的实现。您可以使用此技术嵌入图像。

    <img src="data:image/png;base64,iVBORw0K... " />
    

    所以首先你会使用 java 的 xml 解析器来查找 html http://www.mkyong.com/tutorials/java-xml-tutorials/ 中的所有图像标签。然后您将读取所有文件,将它们转换为 base64 字符串 http://www.xinotes.org/notes/note/736/ 并将 img 的 src 替换为上述格式。

    【讨论】:

    • 标志 JasperExportManager.exportReportToXmlFile(jasperPrint, isEmbeddingImages);也许这与 HTML 类似
    • @kozla13 使用附加信息更新您的原始答案,而不是添加其他信息。
    【解决方案2】:

    正如 ilia 所指出的,直到最近数据 uri 还不能交叉兼容,因此您必须保存多个文件。可能想向 Jasper 提交增强请求,以请求将 html 保存为一个包含嵌入数据 uri 的文件的选项

    【讨论】:

      【解决方案3】:

      解决方案:

      Map<String, String> images = new HashMap<>();
      
      SimpleHtmlExporterOutput simpleHtmlExporterOutput = new SimpleHtmlExporterOutput(outputStream);
      simpleHtmlExporterOutput.setImageHandler(new HtmlResourceHandler() {
      
                  @Override
                  public void handleResource(String id, byte[] data) {
                      System.err.println("id" + id);
                      images.put(id, "data:image/jpg;base64," + Base64.encodeBytes(data));
                  }
      
                  @Override
                  public String getResourcePath(String id) {
                      return images.get(id);
                  }
              });
      

      完整代码:

      package com.test.report;
      
      import java.io.ByteArrayOutputStream;
      import java.io.File;
      import java.util.HashMap;
      import java.util.Map;
      
      import net.sf.jasperreports.engine.JasperFillManager;
      import net.sf.jasperreports.engine.JasperPrint;
      import net.sf.jasperreports.engine.JasperReport;
      import net.sf.jasperreports.engine.data.JRXmlDataSource;
      import net.sf.jasperreports.engine.export.HtmlExporter;
      import net.sf.jasperreports.engine.export.HtmlResourceHandler;
      import net.sf.jasperreports.export.SimpleExporterInput;
      import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
      import net.sf.jasperreports.export.SimpleHtmlReportConfiguration;
      
      import org.apache.commons.io.FileUtils;
      import org.junit.Test;
      import org.olap4j.impl.Base64;
      
      import com.artech.reportservice.reports.ReportType;
      
      public class ReportTest {
          Map<String, String> images = new HashMap<>();
      
          @Test
          public void test() throws Exception {
              // String outFileName = "test.html";
      
              String xmlFileLocation = "/Users/skozlic/dev/VacationToolProject/wokspace/ReportService/src/test/resources/machineReportTestFile.xml";
      
              JasperReport reportTemplate = ReportType.MPM.getReportTemplate();
              JRXmlDataSource jrxmlds = ReportType.MPM.getReportDateSource(xmlFileLocation);
              JasperPrint jasperPrint = JasperFillManager.fillReport(reportTemplate, null, jrxmlds);
      
              HtmlExporter exporterHTML = new HtmlExporter();
              SimpleExporterInput exporterInput = new SimpleExporterInput(jasperPrint);
              exporterHTML.setExporterInput(exporterInput);
              SimpleHtmlReportConfiguration reportExportConfiguration = new SimpleHtmlReportConfiguration();
      
              exporterHTML.setConfiguration(reportExportConfiguration);
              ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      
              SimpleHtmlExporterOutput simpleHtmlExporterOutput = new SimpleHtmlExporterOutput(outputStream);
              simpleHtmlExporterOutput.setImageHandler(new HtmlResourceHandler() {
      
                  @Override
                  public void handleResource(String id, byte[] data) {
                      System.err.println("id" + id);
                      images.put(id, "data:image/jpg;base64," + Base64.encodeBytes(data));
                  }
      
                  @Override
                  public String getResourcePath(String id) {
                      return images.get(id);
                  }
              });
              exporterHTML.setExporterOutput(simpleHtmlExporterOutput);
      
              exporterHTML.exportReport();
              FileUtils.writeByteArrayToFile(new File("test.html"), outputStream.toByteArray());
      
          }
      }
      

      【讨论】:

      • 这是我在将报告作为 HTML 格式导出到输出流时遇到的处理图像的最佳答案,谢谢!其他答案让我在我的 web.xml 中添加了一个 ImageServlet,但这一个是用代码完成的,并且使用的是最新的 Jasper API,所以没有弃用警告。
      • 您有用于示例的 Jasper XML 吗?
      • 是否可以对 Word 报告做同样的事情?我们在 HTML 中有一个带有 base64 编码的 img 的 HTML,我们想用 word 创建一个报告
      • 有没有办法通过操作资源id嵌入多张图片?
      • 嗨,任何正在运行的示例。请在这里分享,我也一样。
      【解决方案4】:

      对 Dave Jarvis 解决方案的小幅改进。

      而不是硬编码 mime 类型

      images.put(id, "data:image/jpg;base64," + Base64.encodeBytes(data));
      

      您可以尝试像这样发现 mime 类型:

      // Find out the mime type
      final ByteArrayInputStream bis = new ByteArrayInputStream( data );
      final String mimeType = URLConnection.guessContentTypeFromStream( bis );
      // Convert to an embedded "data" url.
      final String base64Data = "data:"+mimeType+";base64,"+Base64.encodeBytes( data );
      imagesMap.put( id, base64Data );
      

      【讨论】:

        【解决方案5】:

        这几天我一直在努力解决这个问题,终于解决了。我的报告在 Web 环境中运行,因此我能够使用 net.sf.jasperreports.j2ee.servlets.ImageServlet 来提供图像。不过,这需要一些设置。

        1. 使用JRImageRenderer 在报告本身中呈现图像:

          <image ... >
            ...
            <imageExpression>
              <![CDATA[net.sf.jasperreports.engine.JRImageRenderer.getInstance($F{image_data})]]>
            </imageExpression>
          </image>
          

          其中$F{image_data} 是二进制图像数据。

        2. 导出报告时,指定WebResourceHandler 作为 HTML 资源处理程序。

          SimpleHtmlExporterOutput exporterOutput = new SimpleHtmlExporterOutput(byteArrayOutputStream);
          HtmlResourceHandler imageHandler = new WebHtmlResourceHandler("https://www.mywebsite.com/report/image?image={0}");
          exporterOutput.setImageHandler(imageHandler);
          exporter.setExporterOutput(exporterOutput);
          exporter.exportReport();
          

          要检查,如果您现在生成 HTML 报告并检查源代码,您应该会看到类似 &lt;img href="http://www.mywebsite.com/report/image?image=img_0_0_2.png" /&gt; 的内容。

        3. 现在你需要激活ImageServlet,所以它可以 拦截并满足图像请求。将以下块添加到 你的web.xml 文件:

          <servlet>
            <servlet-name>JasperImageServlet</servlet-name>
            <servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class>
          </servlet>
          <servlet-mapping>
            <servlet-name>JasperImageServlet</servlet-name>
            <url-pattern>/report/image</url-pattern>
          </servlet-mapping>
          

          (请注意,/report/image 路径与我们传递给 WebHtmlResourceHandler 的 URL 参数匹配。)

          启动网络服务器并尝试再次生成 HTML 报告。当然,它仍然不起作用,但复制图像的 URL 并将其粘贴到浏览器中。您应该从ImageServlet 收到一条错误消息,即

          在 HTTP 会话中找不到 JasperPrint 文档。

        4. 最后要做的是将JasperPrint 对象添加到会话中,因此ImageServlet 知道要提供哪个图像。在 JSP 中可以这样做:

          JasperPrint jasperPrint = ...
          HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
          session.setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
          

        现在应该可以了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-22
          • 2013-06-19
          • 2017-04-22
          • 1970-01-01
          • 2012-09-26
          • 1970-01-01
          • 2011-09-19
          • 1970-01-01
          相关资源
          最近更新 更多