Java合并两个Jasper Report

时间:2018-09-17 08:30:00

标签: java jasper-reports itext

我用jasper report创建了两个报告jrxml。在我的Java程序中,我将两个报表与iText合并为一个PDF。 问题在于pdf仅包含一份报告和空白页。 我也做了这个证明: 在我的Java程序创建报告中,一个创建报告中,两个合并,我看到pdf containsig仅报告了一个加空白页 在我的Java程序创建报告两个中,然后在创建报告一个中,合并,我看到pdf仅包含报告两个加空白页

我必须同时获得两个报告的pdf文件 有人可以帮助我解决问题吗?

预先感谢

附加我的Java程序的代码:

@Name("pdfFactory")
public class PdfScalareFactory {

    private static final String JASPER_FILE_MOVIMENTI = "scalarePdf/pdf_movimenti.jrxml";
    private static final String JASPER_FILE_SCALARE = "scalarePdf/pdf_scalare.jrxml";

    @SuppressWarnings("rawtypes")
    public byte[] rawPdf(BeScalare beScalare, String codTabulato, String output) throws JRException, IOException {

        JRBeanArrayDataSource dataSource = new JRBeanArrayDataSource(new Object[]{beScalare}); 

        //report's list
        List<byte[]> pdfFilesAsByteArray = new ArrayList<byte[]>();

        //Report one
        Class cScalare = this.getClass();
        ClassLoader clScalare = cScalare.getClassLoader();
        InputStream isScalare = clScalare.getResourceAsStream(JASPER_FILE_SCALARE);
        JasperDesign jasDesignScalare = JRXmlLoader.load(isScalare);
        //compile report one
        JasperReport reportScalare = JasperCompileManager.compileReport(jasDesignScalare);      
        //parameters report one
        Map<String, Object> paramScalare = new HashMap<String, Object>();
        JRBeanCollectionDataSource itemsScalareSaldiPerValuta = new JRBeanCollectionDataSource(beScalare.getLstBeScalareSaldiPerValuta());
        paramScalare.put("scalareSaldiPerValuta", itemsScalareSaldiPerValuta);
        //fill report one
        JasperPrint jasperPrintScalare = JasperFillManager.fillReport(reportScalare, paramScalare, dataSource);
        pdfFilesAsByteArray.add(JasperExportManager.exportReportToPdf(jasperPrintScalare));

        //Report two
        Class c = this.getClass();
        ClassLoader cl = c.getClassLoader();
        InputStream is = cl.getResourceAsStream(JASPER_FILE_MOVIMENTI);
        JasperDesign jasDesign = JRXmlLoader.load(is);
        //compile report two
        JasperReport reportMovimenti = JasperCompileManager.compileReport(jasDesign);
        //parameters report two
        Map<String, Object> paramMovimenti = new HashMap<String, Object>();
        BufferedImage imgNumeroVerde = ImageIO.read(getClass().getResource("/scalarePdf/headphones.png"));
        paramMovimenti.put("numeroVerde", imgNumeroVerde);
        BufferedImage imgInternet = ImageIO.read(getClass().getResource("/scalarePdf/internet.png"));
        paramMovimenti.put("internet", imgInternet);        
        JRBeanCollectionDataSource itemsScalareMovimenti = new JRBeanCollectionDataSource(beScalare.getLstBeScalareMovimenti());
        paramMovimenti.put("scalareMovimenti", itemsScalareMovimenti);
        //fill report two
        JasperPrint jasperPrintMovimenti = JasperFillManager.fillReport(reportMovimenti, paramMovimenti, dataSource);
        pdfFilesAsByteArray.add(JasperExportManager.exportReportToPdf(jasperPrintMovimenti));

        //merge the two reports in one
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        Document document = null;
        PdfCopy writer = null;
        for (byte[] pdfByteArray : pdfFilesAsByteArray) {

            try {
                PdfReader reader = new PdfReader(pdfByteArray);
                int numberOfPages = reader.getNumberOfPages();

                if (document == null) {
                    document = new Document(reader.getPageSizeWithRotation(1));
                    writer = new PdfCopy(document, outStream); // new
                    document.open();
                }
                PdfImportedPage page;
                for (int i = 0; i < numberOfPages;) {
                    ++i;
                    page = writer.getImportedPage(reader, i);
                    writer.addPage(page);
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        document.close();
        outStream.close();
        return outStream.toByteArray();
    }
}

1 个答案:

答案 0 :(得分:0)

Problem is in the data source and not in merging. You create one data source for both reports but the first report will consume it and then the second report has data source with pointer at the end.

You use JRBeanArrayDataSource which implements JRRewindableDataSource so you can call the moveFirst() method to return data source pointer on the first position:

//Report two
dataSource.moveFirst();

Or you can create the data source again for the second report:

//Report two
dataSource = new JRBeanArrayDataSource(new Object[]{beScalare}); 

Note: But as Amongalen mentioned in the comment it is easier to merge two and more Jasper reports using JRPdfExporter and List<JasperPrint> instance as an input.