Jasper Reports作为Java应用程序的一部分

时间:2018-10-11 15:46:59

标签: java jasper-reports

我正在使用Java应用程序,该应用程序允许您添加用Java编写的扩展。我希望在扩展中运行JasperReports查看器。作为测试,我有以下代码:

package com.moneydance.modules.features.jasperreports;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JFrame;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.swing.JRViewer;

public class MyJasperReport extends JFrame{
    JasperReport report;
    public MyJasperReport(Main main)  throws JRException, IOException{
      String sourceFileName = "c://users/miker/workspace/JasperReports-6.7.0/test" + 
         "/jasper_report_template.jasper";
    Map<String,Object> parameters = new HashMap<>();
   JasperReport report =(JasperReport)JRLoader.loadObjectFromFile(sourceFileName);
   JRDataSource dataSource = new JREmptyDataSource();
   JasperPrint jasperPrint = null;
   JRViewer viewer = null;
   try {
       jasperPrint = JasperFillManager.fillReport(report, parameters,dataSource);
   }
   catch (JRException e) {
       e.printStackTrace();
   }
   if (jasperPrint != null) {
        viewer = new JRViewer(jasperPrint);
        if (viewer !=null) {
            getContentPane().add(viewer);
        }
    }
}

}

此操作失败,并在行上出现空指针异常:

        btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/sf/jasperreports/view/images/save.GIF")));

在类JRViewerToolBar内

如果我通过Eclipse在调试中运行它,那么它将起作用。如果我在代码中包含JRViewer和JRViewerToolBar类,并将代码更改为使用以下代码段:

    public Image getIcon(String action) {
    try {
        loader = getClass().getClassLoader();
        java.io.InputStream in = 
                loader.getResourceAsStream(action);
        if (in != null) {
            ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
            byte buf[] = new byte[256];
            int n = 0;
            while((n=in.read(buf, 0, buf.length))>=0)
                bout.write(buf, 0, n);
            return Toolkit.getDefaultToolkit().createImage(bout.toByteArray());
        }
    } catch (Throwable e) { }
    return null;
}

如果操作是“ /net/sf/jasperreports/view/images/save.GIF”,它也可以工作。

确定资源路径显然是一个问题。我怀疑我正在使用的应用程序使用其自己的类加载器加载我的扩展程序。

问题是:是否有一种加载JasperReports类的方式,以便它们表现出来?另外,我所看到的只是在扩展程序中具有JasperReports的修改版本,这将引入错误并成为维护的噩梦。

编辑

这不是文件解析器问题的重复项。这是关于用于从应用程序中加载Jasper类的类加载器。

1 个答案:

答案 0 :(得分:0)

问题是Moneydance的CLASS-PATH(正在扩展的应用程序)。该路径包含Moneydance的罐子和扩展本身,因为ClassLoader已经扩展。方法getResourceAsStream已被覆盖,但是方法getResource尚未覆盖,因此getResource找不到Jasper资源。我想出的解决方案是加载包含JasperReports代码的可执行jar(使用Spring Boot),并在该jar中构建接口。

我使用自定义类加载器加载包含Jasper类的后台任务。我可以拦截getResources方法并在jar中找到资源。