Java 结合两个 Jasper 报告

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24115885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:14:42  来源:igfitidea点击:

Combining two Jasper reports

javapdfjasper-reports

提问by Vicky

I have a web application with a dropdown from where user could select the type of report viz. report1, report2, report3, etc.

我有一个带有下拉菜单的 Web 应用程序,用户可以从中选择报告类型。报告 1、报告 2、报告 3 等

Based on the report selected, a Jasper report is compiled on the server and opens as a pop up in PDF format.

根据选择的报告,Jasper 报告将在服务器上编译并以 PDF 格式弹出窗口打开。

On the server side, I am implementing each report in a separate method using below code say for e.g. for report1:

在服务器端,我使用下面的代码以单独的方法实现每个报告,例如报告1:

JRBeanCollectionDataSource report1DataSource = new JRBeanCollectionDataSource(resultSetBeanListReport1);

InputStream inputStreamReport1 = new FileInputStream(request.getSession().getServletContext ().getRealPath(jrxmlFilePath + "report1.jrxml"));

JasperDesign jasperDesignReport1 = JRXmlLoader.load(inputStreamReport1);

JasperReport jasperReportReport1 = JasperCompileManager.compileReport(jasperDesignReport1);

bytes = JasperRunManager.runReportToPdf(jasperReportReport1, titleMapReport1,   report1DataSource);

Similarly, report2 is in a separate method with below code:

同样,report2 在一个单独的方法中,代码如下:

JRBeanCollectionDataSource invstSummDataSource = new JRBeanCollectionDataSource(resultSetBeanListInvstOfSumm);

InputStream inputStreamInvstSumm = new FileInputStream(request.getSession().getServletContext().getRealPath(jrxmlFilePath + "investSummary.jrxml"));

JasperDesign jasperDesignInvstSumm = JRXmlLoader.load(inputStreamInvstSumm);

JasperReport jasperReportInvstSumm = JasperCompileManager.compileReport(jasperDesignInvstSumm);

bytes = JasperRunManager.runReportToPdf(jasperReportInvstSumm, titleMapInvstSumm, invstSummDataSource);

Now I have a requirement that if report1 is selected from the dropdown, the resulting PDF should contain all the reports one after other in the same PDF.

现在我有一个要求,如果从下拉列表中选择了 report1,则生成的 PDF 应该在同一个 PDF 中一个接一个地包含所有报告。

How can I combine above two lines of codes to finally generate a single PDF?

如何将以上两行代码结合起来最终生成一个 PDF?

采纳答案by Sangram Jadhav

Here is sample code for combining multiple jasper prints

这是组合多个碧玉印花的示例代码

List<JasperPrint> jasperPrints = new ArrayList<JasperPrint>();
// Your code to get Jasperreport objects
JasperReport jasperReportReport1 = JasperCompileManager.compileReport(jasperDesignReport1);
jasperPrints.add(jasperReportReport1);
JasperReport jasperReportReport2 = JasperCompileManager.compileReport(jasperDesignReport2);
jasperPrints.add(jasperReportReport2);
JasperReport jasperReportReport3 = JasperCompileManager.compileReport(jasperDesignReport3);
jasperPrints.add(jasperReportReport3);

JRPdfExporter exporter = new JRPdfExporter();
//Create new FileOutputStream or you can use Http Servlet Response.getOutputStream() to get Servlet output stream
// Or if you want bytes create ByteArrayOutputStream
ByteArrayOutputStream out = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.JASPER_PRINT_LIST, jasperPrints);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
exporter.exportReport();
byte[] bytes = out.toByteArray();

回答by Abubakr Elkabany

You can either merge reports before generating PDFs using JasperPrintor after generating PDFs using iText.

您可以在JasperPrint使用 iText 生成 PDF之前或在生成 PDF 之后合并报告。

For the JasperPrintsolution: you will generate the 2 (or more) JasperPrints then get the content pages and concat them.

对于JasperPrint解决方案:您将生成 2 个(或更多),JasperPrint然后获取内容页面并将它们连接起来。

JasperPrint jp1 = JasperFillManager.fillReport(url.openStream(), parameters,
                    new JRBeanCollectionDataSource(inspBean));
JasperPrint jp2 = JasperFillManager.fillReport(url.openStream(), parameters,
                    new JRBeanCollectionDataSource(inspBean));

List pages = jp2 .getPages();
for (int j = 0; j < pages.size(); j++) {
    JRPrintPage object = (JRPrintPage)pages.get(j);
    jp1.addPage(object);
}
JasperViewer.viewReport(jp1,false);

For the iText solution after generating the PDFs:

对于生成 PDF 后的 iText 解决方案:

void concatPDFs(List<InputStream> streamOfPDFFiles, OutputStream outputStream, boolean paginate) {

    Document document = new Document();
    try {
      List<InputStream> pdfs = streamOfPDFFiles;
      List<PdfReader> readers = new ArrayList<PdfReader>();
      int totalPages = 0;
      Iterator<InputStream> iteratorPDFs = pdfs.iterator();

      // Create Readers for the pdfs.
      while (iteratorPDFs.hasNext()) {
        InputStream pdf = iteratorPDFs.next();
        PdfReader pdfReader = new PdfReader(pdf);
        readers.add(pdfReader);
        totalPages += pdfReader.getNumberOfPages();
      }
      // Create a writer for the outputstream
      PdfWriter writer = PdfWriter.getInstance(document, outputStream);

      document.open();
      BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
      PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
      // data

      PdfImportedPage page;
      int currentPageNumber = 0;
      int pageOfCurrentReaderPDF = 0;
      Iterator<PdfReader> iteratorPDFReader = readers.iterator();

      // Loop through the PDF files and add to the output.
      while (iteratorPDFReader.hasNext()) {
        PdfReader pdfReader = iteratorPDFReader.next();

        // Create a new page in the target for each source page.
        while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
          document.newPage();
          pageOfCurrentReaderPDF++;
          currentPageNumber++;
          page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
          cb.addTemplate(page, 0, 0);

          // Code for pagination.
          if (paginate) {
            cb.beginText();
            cb.setFontAndSize(bf, 9);
            cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "" + currentPageNumber + " of " + totalPages, 520, 5, 0);
            cb.endText();
          }
        }
        pageOfCurrentReaderPDF = 0;
      }
      outputStream.flush();
      document.close();
      outputStream.close();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (document.isOpen())
        document.close();
      try {
        if (outputStream != null)
          outputStream.close();
      } catch (IOException ioe) {
        ioe.printStackTrace();
      }
    }
  }

回答by Petter Friberg

This answer is to help user using latest version of Jasper-Report. In @Sangram Jadhavaccept answer the JRExporterParameter.JASPER_PRINT_LISTis deprecated

这个答案是为了帮助用户使用最新版本的 Jasper-Report。在 @Sangram Jadhav 中接受答案 JRExporterParameter.JASPER_PRINT_LIST弃用

The current codewould be:

当前的代码是:

Map<String, Object> paramMap = new HashMap<String, Object>();
List<JasperPrint> jasperPrintList = new ArrayList<JasperPrint>();
JasperPrint jasperPrint1 = JasperFillManager.fillReport(report1, paramMap);
jasperPrintList.add(jasperPrint1);
JasperPrint jasperPrint2 = JasperFillManager.fillReport(report2, paramMap);
jasperPrintList.add(jasperPrint2);

JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); //Set as export input my list with JasperPrint s
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput("pdf/output.pdf")); //or any other out streaam
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
configuration.setCreatingBatchModeBookmarks(true); //add this so your bookmarks work, you may set other parameters
exporter.setConfiguration(configuration);
exporter.exportReport();

回答by S.M.Fazle Rabbi

Here is my code which i use on grails code as well as java.Its gives me two different report in one pdf.

这是我在 grails 代码和 java.Its 上使用的代码。它在一个 pdf 中给了我两个不同的报告。

String reportDir = Util.getReportDirectory() // my report directory
Map reportParams = new LinkedHashMap()
Map reportParams1 = new LinkedHashMap()

String outputReportName="Test_Output_copy"

reportParams.put('parameter name',"parameter")
reportParams1.put('copy',"Customer's Copy")

JasperReportDef reportDef1 = new JasperReportDef(name: 'testBillReport.jasper', fileFormat: JasperExportFormat.PDF_FORMAT,
            parameters: reportParams, folder: reportDir)
JasperReportDef reportDef2 = new JasperReportDef(name: 'testBillReport.jasper', fileFormat: JasperExportFormat.PDF_FORMAT,
            parameters: reportParams1, folder: reportDir)

List<JasperReportDef> jasperPrintList = new ArrayList<JasperReportDef>();
    jasperPrintList.add(reportDef1);
    jasperPrintList.add(reportDef2);

ByteArrayOutputStream report1 = jasperService.generateReport(jasperPrintList);
    response.setHeader("Content-disposition", "inline;filename="+outputReportName+'.pdf')
    response.contentType = "application/pdf"
    response.outputStream << report1.toByteArray()

回答by Madhuka Dilhan

You can try this one this is work for me

你可以试试这个,这对我有用

JasperPrint jp1 = JasperFillManager.fillReport(reportFile1,reportParams,Connection);  
JasperPrint jp2 = JasperFillManager.fillReport(reportFile2,reportParams,Connection);  
for (int j = 0; j < jp1.getPages().size(); j++) {  
    //Add First report to second report
    jp2.addPage((JRPrintPage) jp1.getPages().get(j));  
}