Generate a new pdf file based on the pdf template (Java)

Generate a new pdf file based on the pdf template

1. Project dependencies

1. Maven version: 3.5.x
2. Pom file dependency

<!--itext的依赖jar-->
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
    <type>pom</type>
</dependency>

2. Tools used

package com.cloud.docment.pdf;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Description: 按照pdf模板动态生成pdf
 */
public class Template2PdfUtils {
    
    

    private static final Logger logger = LoggerFactory.getLogger(Template2PdfUtils.class);

    private Template2PdfUtils() {
    
     }
    /**企业营业执照模板*/
    public static final String COMPANY_TEMPLATE_PATH = "/com/cloud/docment/pdf/template/company_pdf_mb.pdf";
    /**个体户*/
    public static final String PERSONAL_TEMPLATE_PATH = "/com/cloud/docment/pdf/template/personal_pdf_mb.pdf";

    /** 字体路径(宋体) */
    private static final String DEFAULT_FONT_PATH = "/com/cloud/docment/picture/font/simsun.ttc,1";

    /**
     * 利用已有的pdf模板生成pdf(无图),外部模板中定义pdf表单域大小,位置以及允许换行等属性
     * @param templatePath 模板路径
     * @param newPdfPath 生成的新文件路径
     * @param data 封装数据
     */
    public static void outPdfFile(String templatePath, String newPdfPath, Map<String,String> data) {
    
    

        PdfReader reader = null;
        PdfStamper stamper = null;

        try(FileOutputStream out = new FileOutputStream(newPdfPath);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
    
    
            //设置字体com/cloud/docment/picture/font/simsun.ttc
            BaseFont bf = BaseFont.createFont(DEFAULT_FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            //设置字体大小
            /**Font chineseFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);*/

            // 读取pdf模板
            reader = new PdfReader(templatePath);
            stamper = new PdfStamper(reader, bos);

            /* 获取模版中的表单域字段 */
            AcroFields form = stamper.getAcroFields();

            //文字类的内容处理
            //设置表单域中的格式
            form.addSubstitutionFont(bf);
            textFill(data, form);

            // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
            stamper.setFormFlattening(true);
            stamper.close();

            tempCopyPdf(out, bos);

            /**out.write(bos.toByteArray());*/
            out.flush();
            logger.info("生成pdf处理完成");

        } catch (IOException e) {
    
    
            logger.info("outPdfFile生成本地,IO异常{}", e.getMessage());
        } catch (DocumentException e) {
    
    
            logger.info("outPdfFile生成本地,pdf操作异常{}", e.getMessage());
        }
    }

    /**
     * 利用已有的pdf模板生成pdf(无图),返回
     * @param templatePath 模板路径
     * @param data
     */
    /**
     * 利用已有的pdf模板生成pdf(无图),返回ByteArrayOutputStream
     * @param templatePath 模板路径(允许为空,为空时使用个体工商模板)
     * @param data 数据集
     * @return ByteArrayOutputStream数据
     */
    public static ByteArrayOutputStream outPdfFile(String templatePath, Map<String,String> data) {
    
    

        PdfReader reader = null;
        PdfStamper stamper = null;

        try(OutputStream out = new ByteArrayOutputStream(1024);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
    
    
            //设置字体com/cloud/docment/picture/font/simsun.ttc
            BaseFont bf = BaseFont.createFont(DEFAULT_FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            //设置字体大小
            /**Font chineseFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);*/

            // 读取pdf模板
            reader = new PdfReader(templatePath);
            stamper = new PdfStamper(reader, bos);

            /* 获取模版中的表单域字段 */
            AcroFields form = stamper.getAcroFields();

            //文字类的内容处理
            //设置表单域中的格式
            form.addSubstitutionFont(bf);
            textFill(data, form);

            // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
            stamper.setFormFlattening(true);
            stamper.close();

            tempCopyPdf(out, bos);
            out.flush();
            logger.info("pdf模板处理完成");
            return (ByteArrayOutputStream) out;
        } catch (IOException e) {
    
    
            logger.info("IO异常{}", e.getMessage());
        } catch (DocumentException e) {
    
    
            logger.info("pdf操作异常{}", e.getMessage());
        }
        return null;
    }

    /**
     * 通过提供的pdf模板,按照需要填充的文字信息和图片信息生成pdf
     * @param templatePath 模板对象
     * @param data 文本信息数据
     * @param imgMap 图片信息数据
     * @return
     */
    public static ByteArrayOutputStream outPdfFile(String templatePath, Map<String, String> data, Map<String, String> imgMap) {
    
    
        PdfReader reader = null;
        PdfStamper stamper = null;

        try(OutputStream out = new ByteArrayOutputStream(1024);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
    
    
            //设置字体com/cloud/docment/picture/font/simsun.ttc
            BaseFont bf = BaseFont.createFont(DEFAULT_FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            //设置字体大小
            /**Font chineseFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);*/

            // 读取pdf模板
            reader = new PdfReader(templatePath);
            stamper = new PdfStamper(reader, bos);

            /* 获取模版中的表单域字段 */
            AcroFields form = stamper.getAcroFields();
            //设置表单域中的格式
            form.addSubstitutionFont(bf);

            //文字类的内容处理
            textFill(data, form);

            //图片类处理
            imageFill(imgMap, stamper, form);

            // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
            stamper.setFormFlattening(true);
            stamper.close();

            tempCopyPdf(out, bos);

            /**out.write(bos.toByteArray());*/
            out.flush();
            logger.info("生成pdf处理完成");
            return (ByteArrayOutputStream) out;
        } catch (IOException e) {
    
    
            logger.info("IO异常{}", e.getMessage());
        } catch (DocumentException e) {
    
    
            logger.info("pdf操作异常{}", e.getMessage());
        }
        return null;
    }

    /**
     *
     * @param imgMap 图片信息(含有组装字段和url键值对)
     * @param stamper PdfStamper pdf页面对象
     * @param form pdf表单域对象
     * @throws IOException
     * @throws DocumentException
     */
    private static void imageFill(Map<String, String> imgMap, PdfStamper stamper, AcroFields form) throws IOException, DocumentException {
    
    
        Set<Map.Entry<String, String>> entrySet = imgMap.entrySet();
        for(Map.Entry<String, String> entry : entrySet) {
    
    
            String imgpath = entry.getValue();
            int pageNo = form.getFieldPositions(entry.getKey()).get(0).page;
            Rectangle signRect = form.getFieldPositions(entry.getKey()).get(0).position;
            float x = signRect.getLeft();
            float y = signRect.getBottom();
            //根据路径读取图片
            Image image = Image.getInstance(imgpath);
            //获取图片页面
            PdfContentByte under = stamper.getOverContent(pageNo);
            //图片大小自适应
            image.scaleToFit(signRect.getWidth(), signRect.getHeight());
            //添加图片
            image.setAbsolutePosition(x, y);
            under.addImage(image);
        }
    }

    /**
     * 根据输入的文字集信息填充表单中的文本域
     * @param data 文本填充数据集
     * @param form pdf表单域对象
     * @throws IOException
     * @throws DocumentException
     */
    private static void textFill(Map<String, String> data, AcroFields form) throws IOException, DocumentException {
    
    

        Set<Map.Entry<String, String>> entrySet = data.entrySet();
        for (Map.Entry<String, String> entry : entrySet) {
    
    
            form.setField(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 通过填充的pdf生成副本pdf
     * @param out 输出流(ByteArrayOutputStream指向父类型)
     * @param bos 模板填充的输出流(ByteArrayOutputStream)
     * @throws DocumentException
     * @throws IOException
     */
    private static void tempCopyPdf(OutputStream out, ByteArrayOutputStream bos) throws DocumentException, IOException {
    
    
        Document doc = new Document();
        PdfCopy copy = new PdfCopy(doc, out);
        doc.open();

        PdfImportedPage importPage = copy.getImportedPage(
                new PdfReader(bos.toByteArray()), 1);
        copy.addPage(importPage);
        doc.close();
    }

    public static void main(String[] args) {
    
    
        //测试企业法人
        //QYMC ZCZB QYXZ CLRQ FRDB JYQX JYXKFW JYZZ

        //测试个体户
        String newPdfPath = "D:\\工作目录\\2020\\6月\\20200612\\personal_pdf_mb-cs2.pdf";
//        String imgPath = "D:\\工作目录\\2020\\6月\\20200612\\lezhengkejichayan_erweima.png";
        String imgPath = "http://www.baidu.com/img/dongsc_eb45d000832f8e889ff64951eaf7f381.gif";
        Map<String,String> data = new HashMap<>(16);
        //SHMC JYXS QYXZ CLRQ JYR JYZZ JYXKFW
        data.put("SHXYDM", "91510100MA6B44RR2E");
        data.put("SHMC", "个体商户测试商店540");
        data.put("JYXS","经营形式:个体经营");
        data.put("QYXZ","个体商户");
        data.put("CLRQ","2020年6月9日");
        data.put("JYR","(个体户)");
        data.put("JYZZ","四川省成都市高新区永和大街 XXX 号");
        data.put("JYXKFW","从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发");

        Map<String,String> img = new HashMap<>(8);
        img.put("IMG", imgPath);

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
    
    
            ByteArrayOutputStream baos = outPdfFile(Template2PdfUtils.PERSONAL_TEMPLATE_PATH, data, img);
            if (null != baos) {
    
    
                FileOutputStream fos = null;
                try {
    
    
                    fos = new FileOutputStream(new File(newPdfPath+i));
                    baos.writeTo(fos);
                    baos.flush();
                    fos.close();
                    baos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }

        long endTime = System.currentTimeMillis();
        System.out.print("耗时毫秒数:" + (endTime - startTime));
        System.out.print("\n");
    }
}

3. Other information

1. The pdf template is made using Adobe Acrobat DC, the software download address: link: https://pan.baidu.com/s/1WnQBxwC9EzL2iFX5RJY_cQ Extraction code: apbw, contains cracking software, tutorial piece Baidu
2. Template production requirements: To set the form text field, you need to set the relevant attributes of the text field, such as the position, range size, font size, whether the font is displayed in a new line, the name of the field, and other important content;
3. The Chinese uses the Song Ti font;

Note: Due to the high level of physical examination for the elements of the template during the use of the dpf template, it is recommended to choose carefully.

Guess you like

Origin blog.csdn.net/rao991207823/article/details/106763735