使用servlet和itext 7生成将多个pdf分组的zip文件

问题描述

我正在尝试使用itext7将多个生成的pdf放入servlet的zip中,我设法将一个pdf放入zip文件中,但没有更多。这是代码

private void printMore(HttpServletRequest req,HttpServletResponse resp) throws sqlException {
        String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
        try (PdfReader reader = new PdfReader(masterPath);
             ZipOutputStream zipFile = new ZipOutputStream(resp.getoutputStream());
             PdfWriter writer = new PdfWriter(zipFile);
             PdfDocument pdf = new PdfDocument(reader,writer);
             Document doc = new Document(pdf)) {

            List<Student> studentList = getFactoryDAO().getStatementDAO().selectStudentHasBalance();
            for (Student student : studentList){

                // Generate PDF for the student

                pdfpage page = pdf.getPage(1);
                PdfCanvas canvas = new PdfCanvas(page);

                FontProgram fontProgram = FontProgramFactory.createFont();
                PdfFont font = PdfFontFactory.createFont(fontProgram,"utf-8",true);
                canvas.setFontAndSize(font,10);

                canvas.beginText();

                canvas.setTextMatrix(178,650); // student code
                canvas.showtext(student.getS_Code());

                canvas.setTextMatrix(200,610); // Date of Statement
                canvas.showtext(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));

                canvas.endText();

                float[] pointsWidth = {60f,120f,70f,70f};
                Table table = new Table(pointsWidth);
                table.setMarginTop(280);
                table.setMarginLeft(70);
                table.setFont(font);
                table.setFontSize(10);
                table.setTextAlignment(TextAlignment.CENTER);
                //Header Table
                table.addCell(new Cell().add("Date Inscription"));
                table.addCell(new Cell().add("Name"));
                table.addCell(new Cell().add("Fees"));
                table.addCell(new Cell().add("Observation"));
                //Detail Table
                table.addCell(new Cell().add(student.getTxnDate()));
                table.addCell(new Cell().add(student.getS_FullName));
                table.addCell(new Cell().add(student.getFees));
                table.addCell(new Cell().add(student.getobservation));
                

                doc.add(table);


                ZipEntry zipEntry = new ZipEntry(student.getS_Code() + "_" + student.getS_LName() + ".pdf");
                zipFile.putNextEntry(zipEntry);
                //zipFile.write(); Shall I use it?

            }
        } catch (IOException e) {
            e.printstacktrace();
        }

        resp.setHeader("Content-disposition","attachement; filename=test.zip");
        resp.setContentType("application/zip");
    }

我已经基于此this postthis post,但是无法正常工作。我已经检查了更多类似this的帖子,但是itext7的版本没有提到的PdfWriter.getInstance。我已经尝试了更多的东西,但是无法继续前进。

已更新:

在Enterman建议之后,我像这样更新了它:

String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
        try (PdfReader reader = new PdfReader(masterPath);
             ZipOutputStream zipFile = new ZipOutputStream(resp.getoutputStream());
             PdfWriter writer = new PdfWriter(zipFile);
             PdfDocument pdf = new PdfDocument(reader,writer)
             ) {

            List<Student> studentList = getFactoryDAO().getStatementDAO().selectStudentHasBalance();
            for (Student student : studentList){

                try (Document doc = new Document(pdf)){
                       // Generate PDF for the student

                pdfpage page = pdf.getPage(1);
                PdfCanvas canvas = new PdfCanvas(page);

                FontProgram fontProgram = FontProgramFactory.createFont();
                PdfFont font = PdfFontFactory.createFont(fontProgram,70f};
                Table table = new Table(pointsWidth);
                table.setMarginTop(280);
                table.setMarginLeft(70);
                table.setFont(font);
                table.setFontSize(10);
                table.setTextAlignment(TextAlignment.CENTER);
                //Header Table
                table.addCell(new Cell().add("Date Inscription"));
                table.addCell(new Cell().add("Name"));
                table.addCell(new Cell().add("Fees"));
                table.addCell(new Cell().add("Observation"));
                //Detail Table
                table.addCell(new Cell().add(student.getTxnDate()));
                table.addCell(new Cell().add(student.getS_FullName));
                table.addCell(new Cell().add(student.getFees));
                table.addCell(new Cell().add(student.getobservation));
                

                doc.add(table);


                ZipEntry zipEntry = new ZipEntry(student.getS_Code() + "_" + student.getS_LName() + ".pdf");
                zipFile.putNextEntry(zipEntry);
                //zipFile.write(); Shall I use it?
                }

            }
        } catch (IOException e) {
            e.printstacktrace();
        }

        resp.setHeader("Content-disposition","attachement; filename=test.zip");
        resp.setContentType("application/zip");

但仍然没有运气。

欢迎您的帮助。

解决方法

您应该尝试使用FileInputStream,如下所示(我自己的代码,在生产中运行良好)

private File createZip(List<File> forZip,LocalDate date) {

    String zipName = Constants.ORDER_FILE_PATH + date.getYear() +"-" + date.getMonth().getValue() + "-" + date.getMonth().getDisplayName(TextStyle.FULL,Locale.FRENCH) + ".zip";

    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(zipName);
        ZipOutputStream zipOut = new ZipOutputStream(fos);
        for (File srcFile : forZip) {
            FileInputStream fis = new FileInputStream(srcFile);
            ZipEntry zipEntry = new ZipEntry(srcFile.getName());
            zipOut.putNextEntry(zipEntry);

            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes)) >= 0) {
                zipOut.write(bytes,length);
            }
            fis.close();
            //srcFile.delete();
        }
        zipOut.close();
        fos.close();
    } catch (IOException e) {
        logger.error("createZip",e);
    }

    return new File(zipName);
}
,

特别感谢BenjaminD,Enterman的支持以及所有堆栈社区。​​ p>

我将这个答案发布给那些与我面临同样问题的人。 (我被困了4天)。 “使用itext 7和servlet生成多个PDF”

正如Enterman所说:“需要文档的新实例”。另外还需要PdfDocument。并且按照BenjaminD的指示:“先将文件放入zip文件中,然后再生成PDF文件。”

String masterPath = req.getServletContext().getRealPath("/assets/template/templateStatement.pdf");
        try (ZipOutputStream zipOut = new ZipOutputStream(resp.getOutputStream())) {

            Liste<File> listFile = new ArrayList<>();
            List<Student> studentList = getFactoryDAO().getStatementDAO().selectStudentHasBalance();
            for (Student student : studentList){
                
                File file = new File(student.getS_Code()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".pdf");
                try (PdfDocument pdf = new PdfDocument(new PdfReader(masterPath),new PdfWriter(file.getName()))
                     Document doc = new Document(pdf)){
                       // Generate PDF for the student

                PdfPage page = pdf.getPage(1);
                PdfCanvas canvas = new PdfCanvas(page);

                FontProgram fontProgram = FontProgramFactory.createFont();
                PdfFont font = PdfFontFactory.createFont(fontProgram,"utf-8",true);
                canvas.setFontAndSize(font,10);

                canvas.beginText();

                canvas.setTextMatrix(178,650); // student code
                canvas.showText(student.getS_Code());

                canvas.setTextMatrix(200,610); // Date of Statement
                canvas.showText(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));

                canvas.endText();

                float[] pointsWidth = {60f,120f,70f,70f};
                Table table = new Table(pointsWidth);
                table.setMarginTop(280);
                table.setMarginLeft(70);
                table.setFont(font);
                table.setFontSize(10);
                table.setTextAlignment(TextAlignment.CENTER);
                //Header Table
                table.addCell(new Cell().add("Date Inscription"));
                table.addCell(new Cell().add("Name"));
                table.addCell(new Cell().add("Fees"));
                table.addCell(new Cell().add("Observation"));
                //Detail Table
                table.addCell(new Cell().add(student.getTxnDate()));
                table.addCell(new Cell().add(student.getS_FullName));
                table.addCell(new Cell().add(student.getFees));
                table.addCell(new Cell().add(student.getObservation));
                

                doc.add(table);


                listFile.add(file);
                }

            }
            
            File zipFile = createZip(listFile,newSimpleDateFormat("yyyy-MM-dd").format(new Date())); //BenjaminD source in answer

            ZipEntry zipEntry = new ZipEntry(zipFile.getName);
            zipEntry.putNextEntry(zipEntry);
            fileInputStream fis = new FileInputStream(zipFile);
            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes)) >= 0) {
                zipOut.write(bytes,length);
            }
            fis.close();

            resp.setHeader("Content-disposition","attachement; filename=" + zipFile);
            resp.setContentType("application/zip");

        } catch (IOException e) {
            e.printStackTrace();
        }     

它将zip放入zip中(可以直接使用FileOutpuStream而不将其再次放入zip中。)

再次感谢您。