'How to put two jasperReports in one zip file to download?

public String generateReport()    {
 try

            {

                final FacesContext facesContext = FacesContext.getCurrentInstance();
                final HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
                response.reset();
                response.setHeader("Content-Disposition", "attachment; filename=\"" + "myReport.zip\";");
                final BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
                final ZipOutputStream zos = new ZipOutputStream(bos);

                for (final PeriodScale periodScale : Scale.getPeriodScales(this.startDate, this.endDate))
                {
                    final JasperPrint jasperPrint = JasperFillManager.fillReport(
                        this.reportsPath() + File.separator + "periodicScale.jasper",
                        this.parameters(this.reportsPath(), periodScale.getScale(),
                            periodScale.getStartDate(), periodScale.getEndDate()),
                        new JREmptyDataSource());

                    final byte[] bytes = JasperExportManager.exportReportToPdf(jasperPrint);
                    response.setContentLength(bytes.length);

                    final ZipEntry ze = new ZipEntry("periodicScale"+ periodScale.getStartDate() + ".pdf"); // periodicScale13032015.pdf for example
                    zos.putNextEntry(ze);
                    zos.write(bytes, 0, bytes.length);
                    zos.closeEntry();
                }
                zos.close();
                facesContext.responseComplete();
            }
            catch (final Exception e)
            {
                e.printStackTrace();
            }

            return "";
}

This is my action method in the managedBean which is called by the user to print a JasperReport, but when I try to put more than one report inside the zip file it's not working.

getPeriodScales are returning two objects and JasperFillManager.fillReport is running correctly as the reports print when I just generate data for one report, when I try to stream two reports though and open in WinRar only one appears and I get an "unexpedted end of archive", in 7zip both appear but the second is corrupted.

What am I doing wrong or is there a way to stream multiple reports without zipping it?



Solution 1:[1]

I figured out what was, I was setting the contentLenght of the response with bytes.length size, but it should be bytes.length * Scale.getPeriodScales(this.startDate, this.endDate).size()

Solution 2:[2]

public JasperPrint generatePdf(long consumerNo) {
    Consumer consumerByCustomerNo = consumerService.getConsumerByCustomerNo(consumerNo);
    consumerList.add(consumerByCustomerNo);

    BillHeaderIPOP billHeaderByConsumerNo = billHeaderService.getBillHeaderByConsumerNo(consumerNo);
    Long billNo = billHeaderByConsumerNo.getBillNo();

    List<BillLineItem> billLineItemByBilNo = billLineItemService.getBillLineItemByBilNo(billNo);

    System.out.println(billLineItemByBilNo);
    List<BillReadingLine> billReadingLineByBillNo = billReadingLineService.getBillReadingLineByBillNo(billNo);


    File jrxmlFile = ResourceUtils.getFile("classpath:demo.jrxml");
    JasperReport jasperReport = JasperCompileManager.compileReport(jrxmlFile.getAbsolutePath());


    pdfContainer.setName(consumerByCustomerNo.getName());
    pdfContainer.setTelephone(consumerByCustomerNo.getTelephone());
    pdfContainer.setFromDate(billLineItemByBilNo.get(0).getStartDate());
    pdfContainer.setToDate(billLineItemByBilNo.get(0).getEndDate());
    pdfContainer.setSupplyAddress(consumerByCustomerNo.getSupplyAddress());
    pdfContainer.setMeterNo(billReadingLineByBillNo.get(0).getMeterNo());
    pdfContainer.setBillType(billHeaderByConsumerNo.getBillType());
    pdfContainer.setReadingType(billReadingLineByBillNo.get(0).getReadingType());
    pdfContainer.setLastBilledReadingInKWH(billReadingLineByBillNo.stream().filter(billReadingLine -> billReadingLine.getRegister().contains("KWH")).collect(Collectors.toList()).get(0).getLastBilledReading());
    pdfContainer.setLastBilledReadingInKW(billReadingLineByBillNo.stream().filter(billReadingLine -> billReadingLine.getRegister().contains("KW")).collect(Collectors.toList()).get(0).getLastBilledReading());
    pdfContainer.setReadingType(billReadingLineByBillNo.get(0).getReadingType());
    pdfContainer.setRateCategory(billLineItemByBilNo.get(0).getRateCategory());

    List<PdfContainer> pdfContainerList = new ArrayList<>();
    pdfContainerList.add(pdfContainer);

    Map<String, Object> parameters = new HashMap<>();
    parameters.put("billLineItemByBilNo", billLineItemByBilNo);
    parameters.put("billReadingLineByBillNo", billReadingLineByBillNo);
    parameters.put("consumerList", consumerList);
    parameters.put("pdfContainerList", pdfContainerList);

    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());
    return jasperPrint;
}

//above code is accroding to my requirement , you just focus on the jasperPrint object which am returning , then jasperPrint object is being used for pdf generation , storing those pdf into a zip file .

@GetMapping("/batchpdf/{rangeFrom}/{rangeTo}")
    public String batchPdfBill(@PathVariable("rangeFrom") long rangeFrom, @PathVariable("rangeTo") long rangeTo) throws JRException, IOException {
        consumerNosInRange = consumerService.consumerNoByRange(rangeFrom, rangeTo);

        String zipFilePath = "C:\\Users\\Barada\\Downloads";
        FileOutputStream fos = new FileOutputStream(zipFilePath +"\\"+ rangeFrom +"-To-"+ rangeTo +"--"+ Math.random() + ".zip");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        ZipOutputStream outputStream = new ZipOutputStream(bos);
        try {
            for (long consumerNo : consumerNosInRange) {
                JasperPrint jasperPrint = generatePdf(consumerNo);
                byte[] bytes = JasperExportManager.exportReportToPdf(jasperPrint);
                outputStream.putNextEntry(new ZipEntry(consumerNo + ".pdf"));
                outputStream.write(bytes, 0, bytes.length);
                outputStream.closeEntry();
            }
        } finally {
            outputStream.close();
        }
        return "All Bills PDF Generated.. Extract ZIP file get all Bills";
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 StudioWorks
Solution 2 Tyler2P