2014-06-09 99 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()