【问题标题】:How to merge two jrxml jasper reports into a one single pdf output file如何将两个 jrxml jasper 报告合并为一个 pdf 输出文件
【发布时间】:2014-04-21 07:18:37
【问题描述】:

我有两个具有两个不同数据源的 JRXML 文件。 第一个 jasper 报告数据源是 JRXmlDataSource,第二个 jasper 报告数据源是 JRResultSetDataSource

try
{
            conn= objConnector.getConnection();
            conn.setAutoCommit(false);

            PreparedStatement ps = conn.prepareCall("{ call Sp_DEMO(?) }");
            ps.setString(1,condition);
            ResultSet rs = ps.executeQuery();

            JasperReport jreport1 = JasperCompileManager.compileReport("d:\\JRXML\\ECGImage.jrxml");
            JasperPrint jprint1 = JasperFillManager.fillReport(jreport1, new HashMap(), new JRResultSetDataSource(rs));
            jprintlist.add(jprint1);
            JasperReport jasperReport = JasperCompileManager.compileReport("d:\\JRXML\\RadiologyReport.jrxml");

                JRXmlDataSource xmlDataSource = new JRXmlDataSource("d:\\abc.xml"+, "/X-RayReport/Type");
                JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap(),xmlDataSource);
                jprintlist.add(jasperPrint);


            File file = new File("d:\\demo.pdf");
            if(file.exists())
            {
                file.delete();
            }
            JRExporter exporter = new JRPdfExporter();
            exporter.setParameter(JRPdfExporterParameter.JASPER_PRINT_LIST, jprintlist);
            OutputStream output = new FileOutputStream(new File("d:\\demo.pdf"));
            exporter.setParameter(JRPdfExporterParameter.OUTPUT_STREAM, output);
            exporter.exportReport();

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

我想创建单个 pdf 文件作为两个 jrxml 文件的输出。

【问题讨论】:

    标签: java jasper-reports


    【解决方案1】:

    嗯,这就是 JasperReport 子报表 的目的。您必须创建另一个 .jrxml 作为主报告,并将其他现有的两个包含在此报告中作为“子报告”。所以你会有一个单一的输出。

    要创建子报表(如果您不知道),请参考这些教程:JasperReports - Create SubReportsSubReports

    鉴于您有两个不同的数据源,我认为您可能也需要阅读以下内容:Pass parameter to subreports

    您可能需要它来将不同的数据源作为参数传递给子报表,因此不在您的 JasperPrint 对象实例中。

    【讨论】:

      【解决方案2】:

      你可以像这样合并上面两个pdf

      List pages = jasperPrint.getPages();
      for (int j = 0; j < pages.size(); j++) {
         JRPrintPage object = (JRPrintPage)pages.get(j);
         jprint1.addPage(object);
      }
      

      jprint1 将是您的单一输出。

      【讨论】:

        【解决方案3】:

        对于我如何正常执行此操作,我没有任何事实辩护或争论,所有这些都只是个人喜好问题,以及我在合并和后处理阶段为合并报告添加一些一般性附加内容的便利性,即页码、页眉、页脚等。

        正确的 jasper-report 方法是不要在 Java 中加入报表,而是先制作一个主报表,然后再向其中添加子报表。但是,如果您真的想在 Java 中执行此操作,您可以使用标记,然后再次对所有内容进行后处理,请查看 here

        不过,我只是不这样做。

        大多数时候,我更喜欢先以 pdf 格式生成和导出最终报告的不同部分,然后使用 PDFBox 将它们合并在一起。通过不遵循碧玉报告的方式,通常我会避免子报告层次结构的地狱,因为通常最终报告的每个部分都包含其他几个子报告。所以,我发现最好分别关注每个部分,然后再进行最终合并。

        我通常会这样做:

        public final class Report
        {
            List<File> MergingFiles;
            ReportData data;
        
            public Report(ReportData data)
            {
                // I prefer to pack all the data like, jrxml files path or 
                // the data that fills the report in a separate object -> ReportData
                this.data = data;
                MergingFiles = new ArrayList<>();
            }
        
            private void generateCoverPage() throws JRException
            {
                /* Setting up the data which needs to be passed to cover page
                   reading the cover page jrxml file
                   compiling the report */
                // and Exporting - I normally use JRPdfExporter for that
               exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(data.getCoverPageExportPath()));
               exporter.exportReport();
               MergingFiles.add(new File(data.getCoverPageExportPath()));
            }
        
            private void generateSecondPart() throws JRException
            {
                /* similar to generateCoverPage() to create another part of the report */
            }
            
            public void generateReport()
            {
                generateCoverPage();
                generateSecondPart();
                mergePDFFiles(MergingFiles, data.getPrintFileName());
                /* Do additional general post process i.e. page numbers, header, footer, etc. here 
                   and then clean up temp files */ 
            }
        
            private void mergePDFFiles(List<File> files, String mergedFileName) 
            {
                // all classes are imported from "org.apache.pdfbox"
                try 
                {
                    PDFMergerUtility pdfmerger = new PDFMergerUtility();
                    for (File file : files) 
                    {
                        PDDocument document;
                        document = PDDocument.load(file);
                        pdfmerger.setDestinationFileName(mergedFileName);
                        pdfmerger.addSource(file);
                        pdfmerger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
                        document.close();
                    }
                } 
                catch (IOException e) 
                {
                    System.out.println("Error to merge files. Error: " + e.getMessage());
                }
            }
        
        }
        

        // 只是我的旁注,但是 cmets 以/* */ 投降是你必须照顾的部分,以防你想使用我的方法。

        【讨论】:

          猜你喜欢
          • 2016-03-25
          • 1970-01-01
          • 2016-01-28
          • 1970-01-01
          • 2017-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多