Я создал два отчета jrxml с отчетом jasper. В моей java-программе я объединяю два отчета в один PDF-файл с помощью iText. Проблема в том, что pdf содержит только один отчет плюс пустая страница. Я также сделал это доказательство: в моем отчете о создании Java-программы один отчет о создании два, слияние, и я вижу, что pdf содержит только отчет один плюс пустая страница в моем отчете о создании 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});
Примечание: Но, как упоминалось в комментарии Средиален, проще объединить два и более отчета Jasper, используя в качестве входных данных экземпляр JRPdfExporter и List<JasperPrint>.
Большое спасибо, это то, что я искал
Супер, я рада, что тебе помогли. Тогда, пожалуйста, принять ответ.
Привет, cgrim. Я попытался принять ваш ответ, щелкнув ссылку, но не уверен, что вы его получили. Не могли бы вы проверить?
Привет, ответ по-прежнему не помечен. Под стрелкой вниз рядом с ответом есть серая галочка, и когда вы нажимаете на нее, галочка становится зеленой.
Возможный дубликат Объединение двух отчетов Jasper