SoFunction
Updated on 2025-04-24

Java uses itext5 implementation to generate multiple PDFs and merge

Batch generation and merge into 1 PDF

Single generation

    /**
      * Query data based on id
      * @param id Data id
      * @return
      */
    private Map<String, String> queryEntityDataById(String id) {
        //Query based on id        Box entity = (id);

        Map<String, String> data = new HashMap<String, String>();
        //Show content        //id
        ("id", ());
        //Dynamic generation of yymmddhh format of the current time        DateTimeFormatter formatter = ("yyMMddHH");
        String currentDate = ().format(formatter);
        ("date", currentDate);

        //QR code content        ("imsi", ());
        ("imei", ());

        String type = ();
        if (type == null || ()) {
            type = "A";
        }
        ("type", type);
        return data;
    }

    // Generate PDF based on the data    private void generatePdfForData(Map<String, String> data, ByteArrayOutputStream outputStream) throws Exception {
        // Load the PDF template
        InputStream templateStream = getClass().getResourceAsStream("/template/");
        PdfReader reader = new PdfReader(templateStream);
        PdfStamper stamper = new PdfStamper(reader, outputStream);

        AcroFields form = ();
        String fontPath =  + "font" +  + "";
        BaseFont bfChinese = (fontPath, BaseFont.IDENTITY_H, );
        Map<String, > fields = ();
        for (String k : ()) {
            (k, "textfont", bfChinese, null);
            (k, "textsize", ("55"), null);
            (k, "textstyle", , null);
            (k, "textalign", Element.ALIGN_MIDDLE, null);
        }
        //Reset the font size of the special text box        ("$serialnumber$", "textsize", ("40"), null);
        //Tag content        //ID
        ("$id$", ("id"));
        //date        ("$date$", ("date"));

        //QR code        String qrContent = (
                        "ID:%s\n" +
                        "IMSI:%s\n" +
                        "IMEI:%s\n" +
                        "type:%s",
                ("id"), ("imsi"), ("imei"),("type"));
        PdfContentByte cb = (1);
        generateQRcode(qrContent, cb);
        (true);
        ();
        ();
    }

Return to PDF

    /**
      * Generate pdf in batches and merge according to ID
      * @param ids ids collection
      * @return Direct access to pdf stream file
      */
    @GetMapping("/generateMergePdfStream")
    public ResponseEntity<ByteArrayResource> generateMergePdfStream(@RequestParam String ids) {
        long startTime = ();
        ("Start to generate PDF: " + startTime);
        try {
            String[] idArray = (",");
            ByteArrayOutputStream mergedOutputStream = new ByteArrayOutputStream();
            Document mergedDocument = new Document();
            PdfSmartCopy copy = new PdfSmartCopy(mergedDocument, mergedOutputStream);
            ();

            for (String id : idArray) {
                Map<String, String> data = queryEntityDataById(());

                ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
                generatePdfForData(data, pdfOutputStream);

                ("The generated PDF file size: " + ());

                PdfReader reader = new PdfReader(new ByteArrayInputStream(()));
                (reader);
                ();
                ();
            }

            ();

            ByteArrayResource resource = new ByteArrayResource(());

            HttpHeaders headers = new HttpHeaders();
            ("Content-Disposition", "inline; filename=");

            long generationEnd = ();
            ("PDF generation and merge completed, total time taken: " + (generationEnd - startTime) + "Milliseconds");

            return ()
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_PDF)
                    .body(resource);

        } catch (Exception e) {
            ();
            return (500).build();
        }
    }

The file is saved locally and accesses the pdf file through the http interface

#Accessing files of the same level at the jar package location can directly access the file name under http://IP:port/files-locations=file:./files/

Merge PDF and save

    /**
      * Generate the merged pdf file and save it to the server
      * The following needs to configure -locations=file:./files/
      * folder directory where jar package runs
      * @param ids ids collection
      * @return Direct access http://IP:Port/*.pdf
      */
    @GetMapping("/generateentityLogPdf")
    public ResponseEntity generateMergeSavePdf(@RequestParam String ids, HttpServletRequest request) {
        try {
            // Split ids            String[] idArray = (",");

            // Output stream            ByteArrayOutputStream mergedOutputStream = new ByteArrayOutputStream();
            Document mergedDocument = new Document();
            PdfCopy copy = new PdfCopy(mergedDocument, mergedOutputStream);
            ();

            for (String id : idArray) {
                //Query the required data for pdf based on id                Map<String, String> data = queryEntityDataById(());

                // Generate pdf data stream based on id                ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
                generatePdfForData(data, pdfOutputStream);

                // The generated pdf data stream                PdfReader reader = new PdfReader(new ByteArrayInputStream(()));
                (reader);
                ();
            }

            ();

            //Save file path            String currentDateDir = ().format(("yyyyMMdd"));
            // Get the files directory path in the running directory            String filePath = ("") +  + "files" +  + currentDateDir;
            File directory = new File(filePath);

            // Check whether the directory exists. If it does not exist, create it            if (!()) {
                ();
            }

            // Save the file name            Random random = new Random();
            int randomNumber = (1000);
            String fileName = () + "_" + randomNumber + ".pdf";

            File file = new File(directory, fileName);
            try (FileOutputStream fos = new FileOutputStream(file)) {
                (());
                ();
                ("File saving successfully:" + ());
            } catch (IOException e) {
                ();
            }
            //Return the URL that directly accesses PDF            String ip = ();
            int port = ();
            String fileUrl = "http://" + ip + ":" + port + "/" + currentDateDir + "/" + fileName;
            return (fileUrl);
        } catch (Exception e) {
            ();
            return (500).build();
        }
    }

There is a problem with the PDF file being too large

Solution:

Extract font subsets

This is the end of this article about Java using itext5 to generate multiple PDFs and merge them. For more related Java itext5 to generate PDFs, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!