结合两份Jasper报告

时间:2014-06-09 07:48:41

标签: java pdf jasper-reports

我有一个带有下拉列表的Web应用程序,用户可以从中选择报告类型。 report1,report2,report3等

根据所选报告,在服务器上编译Jasper报告,并以PDF格式弹出。

在服务器端,我使用下面的代码以单独的方法实现每个报告,例如:报告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);

同样,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);

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

如何组合上面两行代码以最终生成单个PDF?

5 个答案:

答案 0 :(得分:14)

以下是组合多个jasper打印的示例代码

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();

答案 1 :(得分:12)

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

当前代码将是:

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();

答案 2 :(得分:1)

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

对于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);

生成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();
      }
    }
  }

答案 3 :(得分:1)

这是我在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()

答案 4 :(得分:0)

您可以尝试这个,这对我来说很有用

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));  
}