Java объединить два отчета Jasper

Я создал два отчета 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();
    }
}

Возможный дубликат Объединение двух отчетов Jasper

Amongalen 17.09.2018 11:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
344
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в источнике данных, а не в слиянии. Вы создаете один источник данных для обоих отчетов, но первый отчет будет использовать его, а затем второй отчет будет иметь источник данных с указателем в конце.

Вы используете JRBeanArrayDataSource, который реализует JRRewindableDataSource, поэтому вы можете вызвать метод moveFirst() для возврата указателя источника данных в первой позиции:

//Report two
dataSource.moveFirst();

Или вы можете снова создать источник данных для второго отчета:

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

Примечание: Но, как упоминалось в комментарии Средиален, проще объединить два и более отчета Jasper, используя в качестве входных данных экземпляр JRPdfExporter и List<JasperPrint>.

Большое спасибо, это то, что я искал

user3310573 26.09.2018 14:01

Супер, я рада, что тебе помогли. Тогда, пожалуйста, принять ответ.

cgrim 26.09.2018 14:13

Привет, cgrim. Я попытался принять ваш ответ, щелкнув ссылку, но не уверен, что вы его получили. Не могли бы вы проверить?

user3310573 27.09.2018 11:21

Привет, ответ по-прежнему не помечен. Под стрелкой вниз рядом с ответом есть серая галочка, и когда вы нажимаете на нее, галочка становится зеленой.

cgrim 27.09.2018 11:30

Другие вопросы по теме