使用Jasper Report导出包含嵌入图像的单个HTML

Jasper Report可以导出到嵌入图像的单个HTML吗?

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

我不认为jasper报告已经内置了对此的支持,所以你必须推出自己的实现。 您可以使用此技术嵌入图像。

 

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

一个办法:

 Map 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 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()); } } 

最近几天我正在努力解决这个问题,最后解决了这个问题。 我的报告在Web环境中运行,因此我可以使用net.sf.jasperreports.j2ee.servlets.ImageServlet来提供图像。 这需要一些设置。

  1. 使用JRImageRenderer在报表中呈现图像:

      ...     

    其中$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报告并检查源,您应该看到类似

  3. 现在您需要激活ImageServlet ,以便它可以拦截并完成图像请求。 将以下块添加到web.xml文件中:

      JasperImageServlet net.sf.jasperreports.j2ee.servlets.ImageServlet   JasperImageServlet /report/image  

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

    启动Web服务器并尝试再次生成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); 

现在它应该工作。

正如ilia所说,直到最近数据uri还没有交叉兼容,所以你必须保存多个文件。 可能希望向Jasper提交增强请求以请求将html保存为具有嵌入数据uris的一个文件的选项

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 );