2014-06-09 98 views
5

我有一个Web应用程序,从用户可以选择报告类型的下拉列表,报告1,报告2,报告3等。结合两个贾斯珀报告

根据所选报告,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); 

类似地,报告2是在与下面的代码单独的方法:

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

现在我有一个要求,即如果报告1被从下拉列表中选择的,所得到的PDF应该包含所有的在同一PDF中一个接一个地报告。

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

回答

7

这里是组合多个碧玉打印

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

您可以在使用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); 

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

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(); 
     } 
    } 
    } 
+0

JasperRunManager.runReportToPdf返回我从我的方法返回的字节数组。有没有办法将JRPrint页面列表转换为字节数组? – Nik

+1

请注意,此解决方案可能无法正确生成书签。 –

7

示例代码这个答案是为了帮助用户使用最新版本的杰士伯-报告。在 @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(); 
+0

是否有机会重新计算页码?我试过了,每个报告都以第1页开头。 – dur

+1

@dur我发表了关于这个主题的Q/A [这里](http://stackoverflow.com/questions/42426311/) –

0

这里是我的代码,我对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()