【问题标题】:JasperReport not displaying image when converted to pdfJasperReport 转换为 pdf 时不显示图像
【发布时间】:2017-08-10 12:15:16
【问题描述】:

我正在开发一个 spring-mvc 项目,并且我正在使用 JasperReports 进行报告。我有一个生成 pdf 格式报告的链接。链接工作正常并生成报告,但问题是 pdf 报告未显示图像。我的 jrxml 文件中的片段:

<frame>
    <reportElement x="0" y="0" width="70" height="67" uuid="0af2e978-7c0c-4805-afb4-4069d1297a12"/>
    <image onErrorType="Blank" evaluationTime="Report">
        <reportElement mode="Opaque" x="0" y="0" width="70" height="67" uuid="c572c836-8d67-480a-b1b1-d603940e6c74"/>
        <imageExpression><![CDATA["images/geLogo.jpg"]]></imageExpression>
    </image>
</frame>


我再次检查,图像出现在我项目的 webapp/images 文件夹中。我在我的 jsp 页面中使用了相同的图像,它正在工作。

用于从 JasperReport 生成 pdf 的代码:

try {
        JasperPrint print = service.loadReceipt(RECEIPT_NAME, paymentId);
        pdfFile = JasperExportManager.exportReportToPdf(print);
        OutputStream outStream = res.getOutputStream();
        res.setContentType("application/pdf");
        res.addHeader("Content-disposition", "inline; filename=Receipt.pdf");
        outStream.write(pdfFile);
        outStream.flush();
        outStream.close();
    } 

你能告诉我为什么图像没有出现在 pdf 中,尽管 JasperReport Designer 中显示的图像具有相同的路径。我在我的 Eclipse 中使用 JasperReports 插件来设计报告。我通过war文件将项目部署在jboss 6.4中。
提前谢谢您。

--------更新--------
我从@KDavid-Valerio 的回答中得到了检查战争中项目结构的想法。它与实际的项目结构不同。战争结构看起来像这样:

Project
    images
        image1.jpg
        image2.jpg
    WEB-INF
        classes
            reports
                report1.jrxml
                report2.jrxml


它似乎仍然不起作用。
-------更新--------
填充碧玉报告的代码:

public JasperPrint loadReceipt(String reportName, String paymentId, String imagePath) {
        HashMap<String, Object> params = new HashMap<String, Object>();
        JasperReport report = null;
        JasperPrint print = null;

        try {
            if (jrReportMap == null) {
                jrReportMap = new HashMap<String, JasperReport>();
            }           

            if (jrReportMap.get(reportName) == null) {
                report = JasperCompileManager.compileReport(reportManager.load(reportName));
                jrReportMap.put(reportName, report);
                log.info(Logger.EVENT_SUCCESS, "--- Report Compilation done --- " + reportName);
            } else {
                report = jrReportMap.get(reportName);
                log.info(Logger.EVENT_SUCCESS, "--- Report already Compiled --- " + reportName);
            }

            params.put("paymentId", paymentId);
            params.put("realPath", imagePath);

            try {
                Connection conn = reportDataSource.getConnection();
                print = JasperFillManager.fillReport(report, params, conn);
                conn.close();
            } catch (SQLException e) {
                System.err.println("--- SQL ERR - to get connection -----");
                log.error(Logger.EVENT_FAILURE, "--- Report already Compiled --- " + reportName);
                e.printStackTrace();
            }
        } catch (JRException e1) {
            log.error(Logger.EVENT_FAILURE, "Oops... Something wrong while rendering the report !!!");
            e1.printStackTrace();
        }
        return print;
    }

【问题讨论】:

  • JasperReport 在运行时使用的路径与设计者使用的路径不同。在您的 java 代码中,您必须将图像相对于 .jasper 文件的路径放在您的 WAR 中。
  • 我尝试了许多不同的路径。似乎没有任何效果。我什至尝试过像 C:/something 这样的外部路径。它不起作用。
  • 我要写一个答案来解释我是如何在我的项目中做到这一点的。我希望这可以帮助你。
  • 那太好了@KDavid-Valerio

标签: java jasper-reports


【解决方案1】:

而不是使用&lt;imageExpression&gt;&lt;![CDATA["images/geLogo.jpg"]]&gt;&lt;/imageExpression&gt;

使用参数。 例如:

<imageExpression><![CDATA[$P{imagePath}]]></imageExpression>

imagePath 它是一个字符串,包含 WAR 中图像的相对 URL。

例如,如果您的 WAR 具有以下结构:


 YourWebProject
      WebContent
           reports
                report1.jasper
                report2.jasper
                ...
                reportn.jasper
            images
                geLogo.jpg

当您填写 imagePath 参数时,您必须为其提供图像相对于报告路径的路径。如果你想使用 geLogo.jpg 图像,它将是:

String imagePath = "../images/geLogo.jpg";

【讨论】:

  • 我从来没想过在战争中检查项目的结构。现在查了一下,和我在eclipse工作区看到的不一样。
    下面是war里面的结构。
    Project images image1.jpg image2.jpg WEB-INF classes reports report1.jrxml report2.jrxml
  • @Waquar 如果你找到了有用的我的答案,请检查它是否有用:)
  • @Waquar 你能贴出填写报告的java代码吗?
  • 我更新了问题。结构在 cmets 中未正确显示。但这似乎对我不起作用。图片仍然没有出现在 pdf 中。
  • @Waquar 请同时添加生成报告的代码。也许在 loadReceipt 方法中?
【解决方案2】:

我找到了使用 ServletContext 解决此问题的方法。

@Autowired
ServletContext context;

自动装配此依赖项,然后使用其方法getRealPath() 获取项目部署后任何目录的真实路径。我发现每次我在 jboss 中部署代码时它都会不断变化。

生成pdf的代码:

 byte[] pdfFile = null;
    String realPath = context.getRealPath("/images/");
    try {
        JasperPrint print = service.loadReceipt(RECEIPT_NAME, paymentId, realPath);
        pdfFile = JasperExportManager.exportReportToPdf(print);
        OutputStream outStream = res.getOutputStream();
        res.setContentType("application/pdf");
        res.addHeader("Content-disposition", "inline; filename=Receipt.pdf");
        outStream.write(pdfFile);
        outStream.flush();
        outStream.close();
}

填写报告的代码:

public JasperPrint loadReceipt(String reportName, String paymentId, String realPath) {
        HashMap<String, Object> params = new HashMap<String, Object>();
        JasperReport report = null;
        JasperPrint print = null;

        try {
            if (jrReportMap == null) {
                jrReportMap = new HashMap<String, JasperReport>();
            }           

            if (jrReportMap.get(reportName) == null) {
                report = JasperCompileManager.compileReport(reportManager.load(reportName));
                jrReportMap.put(reportName, report);
                log.info(Logger.EVENT_SUCCESS, "--- Report Compilation done --- " + reportName);
            } else {
                report = jrReportMap.get(reportName);
                log.info(Logger.EVENT_SUCCESS, "--- Report already Compiled --- " + reportName);
            }

            params.put("paymentId", paymentId);
            params.put("realPath", realPath);

            try {
                Connection conn = reportDataSource.getConnection();
                print = JasperFillManager.fillReport(report, params, conn);
                conn.close();
            } catch (SQLException e) {
                System.err.println("--- SQL ERR - to get connection -----");
                log.error(Logger.EVENT_FAILURE, "--- Report already Compiled --- " + reportName);
                e.printStackTrace();
            }
        } catch (JRException e1) {
            log.error(Logger.EVENT_FAILURE, "Oops... Something wrong while rendering the report !!!");
            e1.printStackTrace();
        }
        return print;
    }

最后是 jrxml sn-p:

<frame>
    <reportElement x="0" y="0" width="70" height="67" uuid="0af2e978-7c0c-4805-afb4-4069d1297a12"/>
    <image onErrorType="Blank" evaluationTime="Report">
        <reportElement mode="Opaque" x="0" y="0" width="70" height="67" uuid="c572c836-8d67-480a-b1b1-d603940e6c74"/>
        <imageExpression><![CDATA[$P{realPath}+"/geLogo.jpg"]]></imageExpression>
    </image>
</frame>

【讨论】:

    猜你喜欢
    • 2011-09-28
    • 1970-01-01
    • 2013-07-03
    • 2019-12-04
    • 2015-10-26
    • 2021-10-28
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多