PDFテンプレートに基づいて新しいPDFファイルを生成します(Java)

PDFテンプレートに基づいて新しいPDFファイルを生成します

1.プロジェクトの依存関係

1. Mavenバージョン:3.5.x 2.Pom
ファイルの依存関係

<!--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.使用したツール

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.その他の情報

1. pdfテンプレートは、Adobe Acrobat DC、ソフトウェアダウンロードアドレスを使用して作成されます:リンク:https://pan.baidu.com/s/1WnQBxwC9EzL2iFX5RJY_cQ抽出コード:apbw、クラッキングソフトウェア、チュートリアルピースBaidu2が含まれています
。テンプレートの作成要件:フォームテキストフィールドを設定するには、位置、範囲サイズ、フォントサイズ、フォントを新しい行に表示するかどうか、フィールドの名前など、テキストフィールドの関連プロパティを設定する必要があります。およびその他の重要なコンテンツ。3
。中国人はTimesNewRomanフォントを使用しています。

注:dpfテンプレートの使用中は、テンプレートの要素の物理的検査が高レベルであるため、慎重に選択することをお勧めします。

おすすめ

転載: blog.csdn.net/rao991207823/article/details/106763735