@[TOC] Recently there is a need to generate a new PDF based on the existing PDF template. There is a lot of information on the Internet

The first step is to create a template

Create a template from an existing PDF using Adobe Acrobat Pro

2 Go to www.pdfescape.com/open/ and create a template based on the existing PDF

The second step introduces the POM

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
Copy the code

Step 3 Generate a PDF from the template

JAVA uses IText to generate PDF documents from templates

 package com.pdf;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;

public class Test {
    public static void main(String[] args) throws Exception {
        export();
        System.out.println("Generated complete");
    }

    public static void export(a){
        try {
            // The path where the PDF template resides is the path where the PDF template is downloaded after the website is completed
            String fileName = "D:/testpdf.pdf";
            PdfReader reader = new PdfReader(fileName);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfStamper ps = new PdfStamper(reader, bos);

            // Use Chinese fonts
            BaseFont bf = BaseFont.createFont("STSong-Light"."UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
            fontList.add(bf);


            AcroFields fields = ps.getAcroFields();
            fields.setSubstitutionFonts(fontList);
            fillData(fields, data());

            // This must be called, otherwise the document will not be generated
            ps.setFormFlattening(true);
            ps.close();

            // The generated PDF path
            OutputStream fos = new FileOutputStream("D:/result.pdf");
            fos.write(bos.toByteArray());
            fos.flush();
            fos.close();
            bos.close();
        }catch(Exception e){ e.printStackTrace(); }}/** * Populates the data in the template */
    public static void fillData(AcroFields fields, Map<String, String> data) {
        try {
            for (String key : data.keySet()) {
                String value = data.get(key);
                // Assign a value to the field. Note that the field name is case sensitivefields.setField(key, value); }}catch(Exception e) { e.printStackTrace(); }}/** * populates the data source * where data holds the key value corresponding to the text field value in the PDF template */
    public static Map<String, String> data(a) {
        Map<String, String> data = new HashMap<String, String>();
        data.put("schoolName"."International test test \r\ N test test");
        data.put("userName"."yvioo");
        data.put("date"."2020/7");
        returndata; }}Copy the code

How to populate image data

    public static void fillImage(AcroFields fields, Map<String, String> imagesData, PdfStamper ps) throws IOException, DocumentException {
        for(String key : imagesData.keySet()) {
            String value = imagesData.get(key);
            // Get the template page corresponding to the current image field
            int pageNo = fields.getFieldPositions(key).get(0).page;
            // Get the position of the template corresponding to the current image field
            Rectangle signRect = fields.getFieldPositions(key).get(0).position;
            float x = signRect.getLeft();
            float y = signRect.getBottom();
            // Read the image from the path
            Image image = Image.getInstance(value);
            // Get the image page
            PdfContentByte pdfContentByte = ps.getOverContent(pageNo);
            // Image size ADAPTS
            image.scaleToFit(signRect.getWidth(), signRect.getHeight());
            // Add imagesimage.setAbsolutePosition(x, y); pdfContentByte.addImage(image); }}Copy the code

How do I wrap the filled data

    public static void fillChunkData(AcroFields fields, Map<String, String> data, PdfStamper ps) throws IOException, DocumentException {
        // Assign a value to the field. Note that the field name is case sensitive
        for (String key : data.keySet()) {
            // Get the template page corresponding to the current image field
            int page = fields.getFieldPositions(key).get(0).page;
            // Get the position of the template corresponding to the current image field
            Rectangle rectangle = fields.getFieldPositions(key).get(0).position;
            float left = rectangle.getLeft();
            float right = rectangle.getRight();
            float top = rectangle.getTop();
            float bottom = rectangle.getBottom();
            // Set the Chinese font
            BaseFont baseFont = BaseFont.createFont("STSong-Light"."UniGB-UCS2-H".false);
            // Set the font size and style
            Font font = new Font(baseFont, 10, Font.NORMAL);
            PdfContentByte pdfContentByte = ps.getOverContent(page);
            // Set the content and position of the fill field
            ColumnText columnText = new ColumnText(pdfContentByte);
            Rectangle r = new Rectangle(left, bottom, right, top);
            columnText.setSimpleColumn(r);

            // Split the data
            String checkInfo = data.get(key);
            String[] info = checkInfo.split("\ \ |");
            if (info.length == 2) {
                // Populate the first row of the field
                Chunk chunk = new Chunk("First row of data");
                Paragraph paragraph = new Paragraph(12, chunk);
                paragraph.setSpacingBefore(8);
                columnText.addText(paragraph);
                paragraph.setFont(font);
                // Set the content to the right
                //paragraph.setAlignment(Element.ALIGN_RIGHT);
                columnText.addElement(paragraph);
                Chunk chunk2 = new Chunk("Second row of data");
                Paragraph paragraph2 = new Paragraph(12, chunk2);
                paragraph2.setSpacingBefore(8); columnText.addText(paragraph2); paragraph2.setFont(font); columnText.addElement(paragraph2); } columnText.go(); }}Copy the code

conclusion

It is very easy to get started, mainly some special operations, such as newline, right, font color, size and so on style related issues, after all, need to be generated to see the effect. Note: 1. Itext-asian related JAR packages need to be introduced for Chinese support