Export To Single Html With Embedded Images Using Jasper Report
Solution 1:
A solution:
Map<String, String> images = newHashMap<>();
SimpleHtmlExporterOutput simpleHtmlExporterOutput = newSimpleHtmlExporterOutput(outputStream);
simpleHtmlExporterOutput.setImageHandler(newHtmlResourceHandler() {
@OverridepublicvoidhandleResource(String id, byte[] data) {
System.err.println("id" + id);
images.put(id, "data:image/jpg;base64," + Base64.encodeBytes(data));
}
@OverridepublicStringgetResourcePath(String id) {
return images.get(id);
}
});
Full code:
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;
publicclassReportTest {
Map<String, String> images = newHashMap<>();
@Testpublicvoidtest()throws Exception {
// String outFileName = "test.html";StringxmlFileLocation="/Users/skozlic/dev/VacationToolProject/wokspace/ReportService/src/test/resources/machineReportTestFile.xml";
JasperReportreportTemplate= ReportType.MPM.getReportTemplate();
JRXmlDataSourcejrxmlds= ReportType.MPM.getReportDateSource(xmlFileLocation);
JasperPrintjasperPrint= JasperFillManager.fillReport(reportTemplate, null, jrxmlds);
HtmlExporterexporterHTML=newHtmlExporter();
SimpleExporterInputexporterInput=newSimpleExporterInput(jasperPrint);
exporterHTML.setExporterInput(exporterInput);
SimpleHtmlReportConfigurationreportExportConfiguration=newSimpleHtmlReportConfiguration();
exporterHTML.setConfiguration(reportExportConfiguration);
ByteArrayOutputStreamoutputStream=newByteArrayOutputStream();
SimpleHtmlExporterOutputsimpleHtmlExporterOutput=newSimpleHtmlExporterOutput(outputStream);
simpleHtmlExporterOutput.setImageHandler(newHtmlResourceHandler() {
@OverridepublicvoidhandleResource(String id, byte[] data) {
System.err.println("id" + id);
images.put(id, "data:image/jpg;base64," + Base64.encodeBytes(data));
}
@Overridepublic String getResourcePath(String id) {
return images.get(id);
}
});
exporterHTML.setExporterOutput(simpleHtmlExporterOutput);
exporterHTML.exportReport();
FileUtils.writeByteArrayToFile(newFile("test.html"), outputStream.toByteArray());
}
}
Solution 2:
I don't think that jasper reports has built in support for this, so you'd have to roll out your own implementation. You can use this technique to embed them images.
<imgsrc="data:image/png;base64,iVBORw0K... " />
So first you'd use java's xml parser to find all the image tags in the html http://www.mkyong.com/tutorials/java-xml-tutorials/. Then you'd read all the files, convert them to base64 string http://www.xinotes.org/notes/note/736/ and replace the img
's src with the above format.
Solution 3:
I was grappling with this for the last few days, and finally solved it. My reports run in a web environment, so I was able to use the net.sf.jasperreports.j2ee.servlets.ImageServlet
to serve the images. This requires a bit of setting up though.
Use the
JRImageRenderer
to render the images in the report itself:<image... > ... <imageExpression> <![CDATA[net.sf.jasperreports.engine.JRImageRenderer.getInstance($F{image_data})]]> </imageExpression></image>
where
$F{image_data}
is the binary image data.When exporting the report, nominate
WebResourceHandler
as the HTML resource handler.SimpleHtmlExporterOutputexporterOutput=newSimpleHtmlExporterOutput(byteArrayOutputStream); HtmlResourceHandlerimageHandler=newWebHtmlResourceHandler("https://www.mywebsite.com/report/image?image={0}"); exporterOutput.setImageHandler(imageHandler); exporter.setExporterOutput(exporterOutput); exporter.exportReport();
To check, if you now generate an HTML report and inspect the source, you should see something like
<img href="http://www.mywebsite.com/report/image?image=img_0_0_2.png" />
.Now you need to activate the
ImageServlet
, so it can intercept and fulfill the image requests. Add the following block to yourweb.xml
file:<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>
(Note that the
/report/image
path matches the URL argument we passed to theWebHtmlResourceHandler
.)Start the webserver and try to generate an HTML report once more. It still won't work of course, but copy the image's URL and paste it into your browser. You should get an error message from the
ImageServlet
thatNo JasperPrint documents found on the HTTP session.
The last thing to do is to add the
JasperPrint
object to the session, so theImageServlet
knows which image to serve. In JSP that can be done like this:JasperPrintjasperPrint= ... HttpSessionsession= (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true); session.setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
Now it should work.
Solution 4:
As noted by ilia, until recently data uri was not cross compatible, so you HAD to save multiple files. Might want to file an enhancement request with Jasper to request an option to save html as one file with embedded data uris
Solution 5:
A minor improvement to Dave Jarvis solution.
Instead of hard-coding the mime type in
images.put(id, "data:image/jpg;base64," + Base64.encodeBytes(data));
You can try to discover the mime type like this:
// Find out the mime typefinalByteArrayInputStreambis=newByteArrayInputStream( data );
finalStringmimeType= URLConnection.guessContentTypeFromStream( bis );
// Convert to an embedded "data" url.finalStringbase64Data="data:"+mimeType+";base64,"+Base64.encodeBytes( data );
imagesMap.put( id, base64Data );
Post a Comment for "Export To Single Html With Embedded Images Using Jasper Report"