【问题标题】:How to get jasper report to load from jar file?如何让 jasper 报告从 jar 文件中加载?
【发布时间】:2014-07-28 02:59:55
【问题描述】:

如何从 jar 文件中加载已编译的 jasper 报告,而不是通过硬盘驱动器上的特定路径?

我的报告在我的机器上运行良好,因为我设置了报告的路径:

jasperReport1 = (JasperReport) JRLoader.loadObjectFromFile("/Users/admin/Documents/HCCE/Semester 2/OOP/Projects2/TestApp/src/ie/test/OMACYTDReportFinalpg1.jasper");
jasperReport2 =(JasperReport) JRLoader.loadObjectFromFile("/Users/admin/Documents/HCCE/Semester 2/OOP/Projects2/TestApp/src/ie/test/OMACYTDReportFinalpg2.jasper");

但在另一台计算机上使用已完成的 jar 工作时,未加载报告。所以我试图使用输入流并将其传递给 JasperFillManager 但没有任何效果 - InputStream 没有找到文件。我是不是走错路了?

InputStream jasper1 = getClass().getResourceAsStream("src/ie/test/OMACYTDReportFinalpg1.jasper");
InputStream jasper2 = getClass().getResourceAsStream("src/ie/test/OMACYTDReportFinalpg2.jasper");

我原来的工作代码:

private void yTDReportBtnActionPerformed(java.awt.event.ActionEvent evt) {                                             
    try
    {
        JasperReport jasperReport1 = null;
        JasperReport jasperReport2 = null;
        JasperPrint jasperPrint = null;
        JasperDesign jasperDesign = null;
        Map parameters = new HashMap();
        SimpleDateFormat formatter = new SimpleDateFormat("dd-mmm-yyyy");  
        String today = formatter.format(new java.util.Date());

        //load just the compiled jasper files, to save time
        //First merge the two jasper reports into one to get page1 and page 2 in same document

        jasperReport1 = (JasperReport) JRLoader.loadObjectFromFile("/Users/admin/Documents/HCCE/Semester 2/OOP/Projects2/TestApp/src/ie/test/OMACYTDReportFinalpg1.jasper");
        jasperReport2 =(JasperReport) JRLoader.loadObjectFromFile("/Users/admin/Documents/HCCE/Semester 2/OOP/Projects2/TestApp/src/ie/test/OMACYTDReportFinalpg2.jasper");

        JasperPrint jp1 = JasperFillManager.fillReport(jasperReport1, parameters,new JRBeanCollectionDataSource(ie.test.BeanFactory.getCalcs()));
        JasperPrint jp2 = JasperFillManager.fillReport(jasperReport2, parameters, new JRBeanCollectionDataSource(ie.test.BeanFactory.getCalcs()));

        List pages = jp2 .getPages();
        for (int j = 0; j < pages.size(); j++) {
        JRPrintPage object = (JRPrintPage)pages.get(j);
        jp1.addPage(object);
        jp1.setName(unitNameLbl.getText() + " - Financial Year To Date - " + today );

}
        JasperViewer.viewReport(jp1, false);

    }
    catch(Exception ex)
    {
        System.out.println("EXCEPTION: "+ex.getMessage() + ex);
    }
}                        

现在更改的代码不起作用:

private void yTDReportBtnActionPerformed(java.awt.event.ActionEvent evt) {                                             
    try
    {
        JasperReport jasperReport1 = null;
        JasperReport jasperReport2 = null;
        JasperPrint jasperPrint = null;
        JasperDesign jasperDesign = null;
        Map parameters = new HashMap();
        SimpleDateFormat formatter = new SimpleDateFormat("dd-mmm-yyyy");  
        String today = formatter.format(new java.util.Date()); 

        //load just the compiled jasper files, to save time
        //First merge the two jasper reports into one to get page1 and page 2 in same document
        InputStream jasper1 = getClass().getResourceAsStream("src/ie/test/OMACYTDReportFinalpg1.jasper");
        InputStream jasper2 = getClass().getResourceAsStream("src/ie/test/OMACYTDReportFinalpg2.jasper");


        JasperPrint jp1 = JasperFillManager.fillReport(jasper1, parameters,new JRBeanCollectionDataSource(ie.test.BeanFactory.getCalcs()));
        JasperPrint jp2 = JasperFillManager.fillReport(jasper2, parameters, new JRBeanCollectionDataSource(ie.test.BeanFactory.getCalcs()));

        List pages = jp2 .getPages();
        for (int j = 0; j < pages.size(); j++) {
        JRPrintPage object = (JRPrintPage)pages.get(j);
        jp1.addPage(object);
        jp1.setName(unitNameLbl.getText() + " - Financial Year To Date - " + today );

}
        JasperViewer.viewReport(jp1, false);


    }
    catch(Exception ex)
    {
        System.out.println("EXCEPTION: "+ex.getMessage() + ex);
    }
}

非常感谢任何帮助!

好的更新:我通过创建一个名为“reports”的新包并使用来让 InputStreams 工作

InputStream jasper1 = getClass().getResourceAsStream("/reports/OMACYTDReportFinalpg1.jasper");
InputStream jasper2 = getClass().getResourceAsStream("/reports/OMACYTDReportFinalpg2.jasper");     

这在 Netbeans 中运行良好,但是当我编译为 jar 时它仍然不会加载文件!!?

任何想法我做错了什么?

【问题讨论】:

  • 两台计算机上的路径是否相同?此外,您可能必须避开这些空格。
  • 我不知道你说的路径是什么意思?我希望能够使用 jar 本身中的 jasper 文件运行此报告。就目前而言,它们在其本地文件夹位置被调用,这显然无法在单独的机器上运行。我认为使用 InputStreams 会起作用,但我不断收到空指针异常 - 似乎找不到文件!
  • 添加更新见上文
  • 编辑:从 jar 打开报告时,我仍然收到空指针异常...为什么看不到文件?我已经解压了 jar,reports 文件夹就在里面,里面有报告!真是令人费解!!!
  • 好吧,愚蠢的错误 - 似乎 Netbeans 不关心大小写字母,但 Jasper API 可以!我在 Netbeans 中的文件名中有几个大写字母,但是当我将它们更改为正确的大小写时,jasper 报告会看到该文件。但是现在我遇到了一个新问题——嵌入在报告中的图像的绝对路径在不同的机器上不起作用。我需要使它们相对,但不确定如何。

标签: java jasper-reports


【解决方案1】:
InputStream jasper1 = getClass().getResourceAsStream("src/ie/test/OMACYTDReportFinalpg1.jasper");
InputStream jasper2 = getClass().getResourceAsStream("src/ie/test/OMACYTDReportFinalpg2.jasper");

【讨论】:

  • 不错的代码。请添加一个简短的解释,以使您的答案有用。
  • 关于使用 Jasper Report API 的问题有一些问题。
【解决方案2】:

老话题,但可能有用。 我的东西在你的 jar 中没有 src 文件夹。

InputStream jasper2 = getClass().getResourceAsStream("/ie/test/OMACYTDReportFinalpg2.jasper");

哪里有更高级的方法: 将您的 jasper 报告、图像和其他资源放入 jar 中。

YourClass 放入 jar 文件中并使用 class.getResourceAsStream() 加载资源,您需要在加载资源之前添加加载器扩展

  (JasperReport) JRLoader.loadObject("stream or path");

  // DefaultJasperReportsContext user ExtensionsEnvironment
  ExtensionsEnvironment.setThreadExtensionsRegistry(LoaderExtention.INSTANCE);

以下加载资源示例

  public class LoaderService
    implements RepositoryService
  {
    public static final RepositoryService INSTANCE = new LoaderService();

    @Override
    public void setContext(RepositoryContext repositoryContext)
    {
    }

    @Override
    public void revertContext()
    {
    }

    @Override
    public InputStream getInputStream(String file)
    {
      LOGGER.fine(String.format("getInputStream('%s')", file));
      return <YourClass>.class.getResourceAsStream(file);
    }

    @Override
    public Resource getResource(String file)
    {
      LOGGER.fine(String.format("getResource('%s') not implemented", file));
      return null;
    }

    @Override
    public <K extends Resource> K getResource(String file, Class<K> cls)
    {
      LOGGER.fine(String.format("getResource('%s', %s)", file, cls != null? cls.getName(): null));

      try
      {
        if (cls == ReportResource.class)
        {
          InputStream resource = getInputStream(file);

          if (resource != null)
          {
            JasperReport report = (JasperReport) JRLoader.loadObject(resource);

            if (report != null)
            {
              ReportResource res = new ReportResource();
              res.setName(file);
              res.setReport(report);
              return (K) res;
            }
          }
        }
        else if (cls == InputStreamResource.class)
        {
          InputStream resource = getInputStream(file);

          if (resource != null)
          {
            InputStreamResource res = new InputStreamResource();
            res.setInputStream(resource);
            return (K) res;
          }
        }
      }
      catch (JRException e)
      {
      }

      return null;
    }

    @Override
    public void saveResource(String string, Resource resource)
    {
      // TODO Implement this method
    }
  }

  public class LoaderExtention
    implements ExtensionsRegistry
  {
    public static final LoaderExtention INSTANCE = new LoaderExtention();

    @Override
    public <T extends Object> List<T> getExtensions(Class<T> cls)
    {
      ExtensionsRegistry system = ExtensionsEnvironment.getSystemExtensionsRegistry();
      List<T> services = null;

      if (system != null)
        services = system.getExtensions(cls);

      if (cls == RepositoryService.class)
      {
        List<T> servicesAll = new ArrayList<T>();

        if (services != null)
          servicesAll.addAll(services);

        servicesAll.add((T) LoaderService.INSTANCE); // Try to use system resource loaders then my
        services = servicesAll;
      }

      LOGGER.fine(String.format("getExtensions(%s) = %s", cls.getName(), services));
      return services;
    }
  }

我使用 JasperReport 5.5 玩得开心。

【讨论】:

    【解决方案3】:

    你应该把碧玉报告放在

    yourapp/src/main/resources/reports

    然后您从 java 类调用该报告

    JasperReport jp = JasperCompileManager.compileReport(getClass().getResourceAsStream("/reports/yourReport.jrxml"));
    

    再见!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多