pdf填充

GitHub[itexpdf] https://github.com/itext/itextpdf

第一步:编辑模板
使用可以编辑表单的pdf编辑器编辑pdf表单,效果如下。(我用的是迅捷pdf编辑器。)

第二步:使用iTextPdf设置表单属性值,支持多种类型,可自主研究
简单代码记录如下:
①导入以下两个包(代码中也使用到了Hutools,看个人情况):

依赖jar包
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.10</version>
        </dependency>

②核心逻辑实现

设置pdf表单属性值
package fill;

import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;

public class PdfUtils {
    /**
     * Description: 使用map中的参数填充pdf,map中的key和pdf表单中的field对应 <br>
     * @Param  fieldValueMap:文件字段  file:源文件的字节流   contractFileName:生成目标文件存放的地址
     * @return
     */
    public static void fillParam(Map<String, String> fieldValueMap, byte[] file, String contractFileName) throws IOException {
        if (fieldValueMap == null) {
            return;
        }
        FileOutputStream fos = null;
        try {
            //生成pdf 的路径
            fos = new FileOutputStream(contractFileName);
            PdfReader reader = null;
            PdfStamper stamper = null;
            BaseFont base;
            try {
                reader = new PdfReader(file);
                stamper = new PdfStamper(reader, fos);
                stamper.setFormFlattening(true);
                // 设置自定义字体,不然中文不显示
                base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                AcroFields acroFields = stamper.getAcroFields();
                for (String key : acroFields.getFields().keySet()) {
                    //将map填充到对应的位置中
                    if (!fieldValueMap.containsKey(key)) {
                        continue;
                    }
                    int fieldType = acroFields.getFieldType(key);
                    if (AcroFields.FIELD_TYPE_TEXT == fieldType) {
                        //设置一些填充位置的字体属性
                        acroFields.setFieldProperty(key, "textfont", base, null);
                        acroFields.setFieldProperty(key, "textsize", new Float(9), null);
                        acroFields.setField(key, fieldValueMap.get(key), true);
                    } else if (AcroFields.FIELD_TYPE_CHECKBOX == fieldType || AcroFields.FIELD_TYPE_RADIOBUTTON == fieldType ) {
                        //复选框、单选框
                        acroFields.setField(key, "Yes".equals(fieldValueMap.get(key)) ? "Yes" : "No", true);
                    } else if (AcroFields.FIELD_TYPE_PUSHBUTTON == fieldType) {
                        //图片
                        int pageNo = acroFields.getFieldPositions(key).get(0).page;
                        Rectangle signRect = acroFields.getFieldPositions(key).get(0).position;
                        float x = signRect.getLeft();
                        float y = signRect.getBottom();
                        Image image = Image.getInstance(fieldValueMap.get(key));
                        PdfContentByte overContent = stamper.getOverContent(pageNo);
                        image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                        image.setAbsolutePosition(x, y);
                        overContent.addImage(image);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (stamper != null) {
                    try {
                        stamper.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (reader != null) {
                    reader.close();
                }
            }

        } catch (Exception e) {
            System.out.println("填充参数异常");
            e.printStackTrace();
        } finally {
            fos.close();
        }
    }
}

③测试类

点击查看代码
package fill;

import cn.hutool.core.io.FileUtil;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;

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

public class PdfFillTest2 {
    public static void main(String[] args) throws IOException {
        HashMap<String, String> map = new HashMap<>();
        map.put("custName", "你叫什么名字啊?");
        map.put("certType", "100");
        map.put("certNo", "123345463572345473562");
        map.put("field1", "xxx开户行");
        map.put("field2", "654321xxxxxxxx1");
        map.put("field3", "xxx开户行");
        map.put("field4", "654321xxxxxxxx1");
        map.put("l1", "Yes");
        map.put("l3", "Yes");
        map.put("l4", "Yes");
        map.put("image", "D:\\pdf\\文件.png");
        //源模板地址
        String sourceFile = "D:\\pdf\\form.pdf";
        //生成文件的目标地址
        String targetFile = "D:\\pdf\\form_out.pdf";
        File templateFile = new File(sourceFile);

        try {
       /* 获取模板文件中的所有表单域
        Set<String> templateFileFieldNames = PdfUtils.getTemplateFileFieldNames(sourceFile);
            System.out.println(templateFileFieldNames);*/

//            PdfUtils.fillParam(map, FileUtils.readFileToByteArray(templateFile), targetFile);
            PdfUtils.fillParam(map, FileUtil.readBytes(templateFile), targetFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * Description: 获取pdf表单中的fieldNames<br>
     * @author mk
     * @Date 2018-11-2 15:21 <br>
     * @Param
     * @return
     */
    public static Set<String> getTemplateFileFieldNames(String pdfFileName) {
        Set<String> fieldNames = new TreeSet<String>();
        PdfReader reader = null;
        try {
            reader = new PdfReader(pdfFileName);
            Set<String> keys = reader.getAcroFields().getFields().keySet();
            for (String key : keys) {
                int lastIndexOf = key.lastIndexOf(".");
                int lastIndexOf2 = key.lastIndexOf("[");
                fieldNames.add(key.substring(lastIndexOf != -1 ? lastIndexOf + 1 : 0, lastIndexOf2 != -1 ? lastIndexOf2 : key.length()));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
        }

        return fieldNames;
    }


    /**
     * Description: 读取文件数组<br>
     * @author mk
     * @Date 2018-11-2 15:21 <br>
     * @Param
     * @return
     */
    public static byte[] fileBuff(String filePath) throws IOException {
        File file = new File(filePath);
        long fileSize = file.length();
        if (fileSize > Integer.MAX_VALUE) {
            //System.out.println("file too big...");
            return null;
        }
        FileInputStream fi = new FileInputStream(file);
        byte[] file_buff = new byte[(int) fileSize];
        int offset = 0;
        int numRead = 0;
        while (offset < file_buff.length && (numRead = fi.read(file_buff, offset, file_buff.length - offset)) >= 0) {
            offset += numRead;
        }
        // 确保所有数据均被读取
        if (offset != file_buff.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }
        fi.close();
        return file_buff;
    }


    /**
     * Description: 合并pdf <br>
     * @author mk
     * @Date 2018-11-2 15:21 <br>
     * @Param
     * @return
     */
    public static void mergePdfFiles(String[] files, String savepath) {
        Document document = null;
        try {
            document = new Document(); //默认A4大小
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
            document.open();
            for (int i = 0; i < files.length; i++) {
                PdfReader reader = null;
                try {
                    reader = new PdfReader(files[i]);
                    int n = reader.getNumberOfPages();
                    for (int j = 1; j <= n; j++) {
                        document.newPage();
                        PdfImportedPage page = copy.getImportedPage(reader, j);
                        copy.addPage(page);
                    }
                } finally {
                    if (reader != null) {
                        reader.close();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭PDF文档流,OutputStream文件输出流也将在PDF文档流关闭方法内部关闭
            if (document != null) {
                document.close();
            }

        }
    }
}

④效果图

posted @ 2023-01-13 16:42  zomicc  阅读(273)  评论(0编辑  收藏  举报