首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java合并两个Jasper报表

Java合并两个Jasper报表
EN

Stack Overflow用户
提问于 2018-09-17 16:30:00
回答 1查看 362关注 0票数 0

我已经用jasper report创建了两个报告jrxml。在我的java程序中,我用iText将这两个报告合并成一个PDF。问题是pdf只包含一份报告和一张空白页。我还做了这样的证明:在我的java程序创建报告中,一个创建报告,合并,我看到pdf在我的java程序创建报告中只包含一个报告加空白页,然后创建报告一,合并,我看到pdf只包含报告二加空白页。

我必须获得两份报告的pdf文件,有人能帮我解决这个问题吗?

提前感谢

附上我的java程序的代码:

代码语言:javascript
复制
@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();
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-19 03:37:07

问题出在数据源,而不是合并。您为两个报告创建了一个数据源,但是第一个报告将使用它,然后第二个报告具有数据源,并在末尾使用指针。

您可以使用实现JRRewindableDataSourceJRBeanArrayDataSource,这样您就可以调用moveFirst()方法来返回第一个位置上的数据源指针:

代码语言:javascript
复制
//Report two
dataSource.moveFirst();

或者,您可以为第二个报告重新创建数据源:

代码语言:javascript
复制
//Report two
dataSource = new JRBeanArrayDataSource(new Object[]{beScalare}); 

注意:,但正如Amongalen在评论中提到的,使用JRPdfExporterList<JasperPrint>实例作为输入来合并两个或更多的Jasper报告会更容易。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52363640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档