我用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();
}
}
答案 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.