apache pdfbox 设置PDF表单域,Java生成PDF模板简单案例。 apache pdfbox java生成pdf模板。

1. 编辑模板PDF

1.1 编辑内容


描述:打开用WPS打开需要编辑的PDF模板,编辑内容。

1.2 编辑表单

1.3 添加表单域


描述:添加表单域,并给各个表单域命名,本案例表单域命名为x1,x2,x3,读者可以自行修改,退出编辑保存即可。

1.4 存在水印


描述:由于没有WPS会员,所以存在试用水印,通过java工具去掉即可。

2. 项目结构

2.1 pom.xml


 
 org.apache.pdfbox
 pdfbox
 3.0.2
 

2.2 ClearWaterMarksUtils.java

package org.liberx;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
 * 清除 PDF 文件中的水印的工具类。
 * 此类使用 Apache PDFBox 库加载 PDF 文档并移除其水印。
 * 水印通过用空白图像替换原有图像来清除。
 */
public class ClearWaterMarksUtils {
 /**
 * 程序的入口点。
 * 加载指定路径的 PDF 文件,清除水印并保存为新的 PDF 文件。
 *
 * @param args 命令行参数,当前未使用
 */
 public static void main(String[] args) {
 try {
 // 加载 PDF 文档
 RandomAccessReadBuffer readPdf = new RandomAccessReadBuffer(ClearWaterMarksUtils.class.getResourceAsStream("/edit.pdf"));
 PDDocument document = Loader.loadPDF(readPdf);
 // 清除水印
 checkTextWatermark(document);
 // 保存修改后的 PDF路径
 document.save("无水印.pdf");
 document.close();
 } catch (IOException e) {
 // 处理 IO 异常
 throw new RuntimeException(e);
 }
 }
 /**
 * 检查并移除 PDF 文档中的文本水印。
 * 此方法会遍历 PDF 文档的每一页,并用空白图像替换所有图像对象,
 * 从而有效地去除水印。
 *
 * @param document 需要处理的 PDF 文档
 * @throws IOException 如果在处理文档时发生 IO 异常
 */
 private static void checkTextWatermark(PDDocument document) throws IOException {
 // 在内存中创建一个空白图像并验证其创建
 BufferedImage emptyImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
 if (emptyImage.getWidth() != 1 || emptyImage.getHeight() != 1) {
 throw new IOException("未能创建内存图像。");
 }
 // 将空白图像写入字节数组输出流
 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
 ImageIO.write(emptyImage, "png", byteArrayOutputStream);
 byte[] imageData = byteArrayOutputStream.toByteArray();
 // 验证图像数据长度
 if (imageData.length == 0) {
 throw new IOException("图像数据为空,未能创建内存图像。");
 }
 // 从内存图像数据创建 PDImageXObject
 PDImageXObject blankImageXObject = PDImageXObject.createFromByteArray(document, imageData, "empty");
 if (blankImageXObject.getWidth() == 0 || blankImageXObject.getHeight() == 0) {
 throw new IOException("未能从内存图像数据创建 PDImageXObject。");
 }
 // 用空白图像替换 PDF 页面中的每个图像
 for (PDPage page : document.getPages()) {
 PDResources resources = page.getResources();
 for (COSName name : resources.getXObjectNames()) {
 resources.put(name, blankImageXObject); // 替换图像
 System.out.println("在页面上用空白图像替换了图像。");
 }
 }
 }
}

2.3 去除水印

操作: 运行ClearWaterMarksUtils的main方法,会生成如下无水印文件。

2.4 验证水印是否去除成功


描述:通过WPS打开无水印.pdf发现水印已经消失。

2.5 移动无水印.pdf位置


描述:移动到resources根目录下,因为我都是通过类加载pdf和font文件。

2.6 ModifyPDFForm.java

package org.liberx;
import org.apache.fontbox.ttf.OTFParser;
import org.apache.fontbox.ttf.OpenTypeFont;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
 * 修改 PDF 表单中的字段内容的工具类。
 * 此类使用 Apache PDFBox 库加载 PDF 文档,修改表单字段的内容,并嵌入自定义字体。
 */
public class ModifyPDFForm {
 public static void dealPdf(String readPath, String outputPath,String fontPath,MapfieldContentMap) {
 // 尝试加载 PDF 文档并修改表单字段
 try (
 // 使用随机访问读取 PDF 文件
 RandomAccessRead readPdf = new RandomAccessReadBuffer(ModifyPDFForm.class.getResourceAsStream(readPath));
 PDDocument document = Loader.loadPDF(readPdf) // 加载 PDF 文档
 ) {
 // 获取 PDF 表单
 PDAcroForm pdfForm = document.getDocumentCatalog().getAcroForm();
 if (pdfForm != null) {
 // 加载并嵌入字体
 try (RandomAccessRead readFont = new RandomAccessReadBuffer(ModifyPDFForm.class.getResourceAsStream(fontPath))) {
 /* OpenTypeFont otfFont = new OTFParser().parse(readFont); // 解析 OTF 字体
 PDFont font = PDType0Font.load(document, otfFont, false); // 加载 OTF 字体*/
 PDFont font = PDType0Font.load(document,readFont, false,false); //加载ttf
 // 设置默认字体资源
 PDResources resources = new PDResources();
 resources.put(COSName.getPDFName("F1"), font); // 将字体添加到资源中
 pdfForm.setDefaultResources(resources); // 设置 PDF 表单的默认字体资源
 // 遍历所有表单字段并设置新内容
 for (PDField field : pdfForm.getFields()) {
 // 检查字段是否在定义的内容映射中
 if (fieldContentMap.containsKey(field.getFullyQualifiedName())) {
 if (field instanceof PDTextField) { // 确保字段是文本字段
 PDTextField textField = (PDTextField) field;
 // 设置文本字段的外观和内容
 textField.setDefaultAppearance("/F1 12 Tf 0 g"); // 设置字体和字号
 textField.setValue(fieldContentMap.get(field.getFullyQualifiedName())); // 设置字段值
 textField.setReadOnly(true); // 将字段设置为只读
 }
 }
 }
 } catch (IOException e) {
 System.err.println("加载字体时出错: " + e.getMessage()); // 输出字体加载错误信息
 }
 } else {
 System.out.println("PDF 表单未找到!"); // 如果没有找到表单
 }
 // 保存修改后的 PDF
 document.save(outputPath, CompressParameters.NO_COMPRESSION); // 不压缩保存 PDF
 System.out.println("PDF 保存成功!"); // 输出保存成功信息
 } catch (IOException e) {
 System.out.println(e.getMessage()); // 输出 IO 异常信息
 }
 }
 public static void main(String[] args) {
 String filePath = "/无水印.pdf"; // PDF 文件路径
 String outputPath = "填充.pdf"; // 输出文件路径
 String fontPath = "/fonts/SourceHanSans-Regular.ttf";
 // 定义表单字段和对应的新内容
 Map fieldContentMap = new HashMap();
 fieldContentMap.put("x1", "测试一下"); // 中文内容
 fieldContentMap.put("x2", "テスト"); // 日文内容
 fieldContentMap.put("x3", "대한민국English123456789"); // 韩文、英文、数字内容
 dealPdf(filePath,outputPath,fontPath,fieldContentMap);
 }
}

2.7 查看填充表单域结果


描述:填充表单域文件。

描述:通过WPS查看填充结果。

3 字体

source-han-sans-ttf
NotoSansCJKkr-Regular.otf
描述:字体只是测试字体,还是需要自行查找合适的字体,比较容易出现下面的错误。

Exception in thread “main” java.lang.IllegalArgumentException: No glyph for U+B300 (대) in font SourceHanSansCN-Regular
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:404)…

本案例仅供学习交流使用。

作者:someliber原文地址:https://blog.csdn.net/qq_71387716/article/details/143352951

%s 个评论

要回复文章请先登录注册