Java合并了两个Jasper Report
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java合并了两个Jasper Report相关的知识,希望对你有一定的参考价值。
我用jasper报告创建了两个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();
}
}
答案
问题出在数据源中而不是合并中。您为两个报告创建一个数据源,但第一个报告将使用它,然后第二个报告的末尾有指针的数据源。
你使用实现JRBeanArrayDataSource
的JRRewindableDataSource
,所以你可以调用moveFirst()
方法在第一个位置返回数据源指针:
//Report two
dataSource.moveFirst();
或者,您可以再次为第二个报告创建数据源:
//Report two
dataSource = new JRBeanArrayDataSource(new Object[]{beScalare});
注意:但正如在注释中提到的那样,使用JRPdfExporter
和List<JasperPrint>
实例作为输入合并两个或更多Jasper报告更容易。
以上是关于Java合并了两个Jasper Report的主要内容,如果未能解决你的问题,请参考以下文章
如何将两个jrxml jasper报告合并为一个单独的pdf输出文件
Jasper report用JSON文件调试预览(附解决JSON报错)
如何将 Jasper Report 输出直接存储在数据库表中,中间没有任何步骤