Search code examples
javajasper-reports

JasperReport image inside report jrxml on HTML src is missing?


I have a method in Java using the JasperReport to export a report in HTML like this:

public static byte[] exportToHtmlWithConn(String urlReport, Connection conn) throws JRException {

    Map<String, Object> parameters = new HashMap<>();

    String urlLogo = "/reports/image.PNG";

    String urlLogo2 = JasperUtilities.class.getResource(urlLogo).toString();

    parameters.put("CONTEXT", urlLogo2);

    JasperReport report = JasperCompileManager.compileReport(JasperUtilities.class.getResourceAsStream(urlReport));
    jasperPrint = JasperFillManager.fillReport(report, parameters, conn);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    HtmlExporter exporter = new HtmlExporter();
    exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
    exporter.setExporterOutput(new SimpleHtmlExporterOutput(baos));
    exporter.exportReport();

    return baos.toByteArray();
}

In the report I have one parameter like this:

<parameter name="CONTEXT" class="java.lang.String">
    <parameterDescription><![CDATA[CONTEXT]]></parameterDescription>
    <defaultValueExpression><![CDATA[0]]></defaultValueExpression>
</parameter>

And the idea is to show one image inside the report

<image>
    <reportElement x="180" y="-5" width="185" height="80" uuid="d8978cb8-9c4e-4d1b-83fb-a83356803128">
    <property name="com.jaspersoft.studio.unit.width" value="pixel"/>
    <property name="com.jaspersoft.studio.unit.height" value="pixel"/>
    </reportElement>
    <imageExpression><![CDATA[$P{CONTEXT}.toString()]]></imageExpression>
</image>

The problem is when I use this method to export a HTML the image is missing but when I use the same structure for example to export a PDF or xlsx the image works Ok.

Why not work in HTML? When I check the code in html the src is empty

<img src="" style="width: 185px" alt=""/>

Can someone help with any idea about this? I have seen many ways to do the same but this has been impossible to work. I also have used one parameters like java.io.InputStream and the image works in PDF and others formats. But in HTML doesn't work.

Also I have used others images but the same problem.


Solution

  • this is my solution:

    I need to export in PDF, xlsx and show the report in HTML. For each there are a method. But I had the problem with HTML the image missing. But the solution thanks to Narcis is like this:

    public static byte[] exportToHtmlWithConn(String urlReport, Connection conn) throws JRException {
    
        Map<String, Object> parameters = new HashMap<>();
    
        parameters = returnLogoPutAsParam();
    
        JasperReport report = JasperCompileManager.compileReport(JasperUtilities.class.getResourceAsStream(urlReport));
        jasperPrint = JasperFillManager.fillReport(report, parameters, conn);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
        HtmlExporter exporter = new HtmlExporter();
        exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
    
        SimpleHtmlExporterOutput htmlExporterOutput = new SimpleHtmlExporterOutput(baos);
        htmlExporterOutput.setImageHandler(new FileHtmlResourceHandler(new File("html_images"), "/web/resources/images/logo.png"));
    
        exporter.setExporterOutput(htmlExporterOutput);
        exporter.exportReport();
    
        return baos.toByteArray();
    }
    

    In this part htmlExporterOutput.setImageHandler(new FileHtmlResourceHandler(new File("html_images"), "/web/resources/images/logo.png")); I put the logo.png in one folder inside the resources in my frontend.

    I use the method returnLogoPutAsParam(); for return the image for PDF and xlsx

    public static Map<String, Object> returnLogoPutAsParam() {
        Map<String, Object> parameters = new HashMap<>();
        InputStream logo = returnLogoByte();
        parameters.put("logo", logo);
        return parameters;
    }
    

    And finally this:

    public static InputStream returnLogoByte() {
        InputStream is = null;
        try {
            byte[] imageByteArray;
            BufferedImage img = ImageIO.read(JasperUtilities.class.getResourceAsStream("/reports/logo.png"));
            ByteArrayOutputStream bas = new ByteArrayOutputStream();
            ImageIO.write(img, "bmp", bas);
            imageByteArray = bas.toByteArray();
            System.out.println("Byte[] logo:" + imageByteArray.length);
            is = new ByteArrayInputStream(imageByteArray);
            return is;
        } catch (Exception e) {
            System.out.println("Error reading logo.");
            e.printStackTrace();
        }
        return is;
    }
    

    Really I am not sure if this is the best solution but it works for one image.

    I hope this info help to someone.

    Cheers.