今天客户给了一个docx文档模板,让页面填写以后下载成pdf格式的文件,之前的项目里面用过wkhtmltopdf 动态生成pdf,但是如果使用这个方式需要先把word文件转化成html,把数据填充到html以后,再转成pdf,这样转起来太复杂了。
今天无意中发现使用lowagie 可以直接编辑pdf,而且也不需要像itextpdf那样额外引入系统字体。

话不多说,开始操作:

第一步 设置pdf模板

wps 将word 转成pdf,使用Adobe Acrobat DC编辑pdf。
Adobe Acrobat DC下载:

地址:https://pan.baidu.com/s/1NoPc0sNfk3hojJphUoPhyQ?pwd=cir7
密码:cir7

下载解压后执行这个文件:

Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)_java

为PDF准备表单

Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)_字段_02


表单准备完毕以后,如下图:

Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)_java_03


双击一个区域,自定义key:

Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)_字段_04


设置两个字段试试:

Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)_html_05

保存一下,生成一个新的带表单的pdf。

使用maven的项目

导入依赖

<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>cn.lesper</groupId>
<artifactId>iTextAsian</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext-rtf</artifactId>
<version>2.1.7</version>
</dependency>

java代码创建PdfUtils类

package pdf.kit.util;

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;
/**
* @ClassName PdfUtils * @Description TODO
* @Author lgn
* @Date 16:43 2022/8/22
* @Version 1.0
**/
public class PdfUtils {
public static void main(String[] args) throws Exception {
export();
System.out.println("生成完成");
}

public static void export(){
try {
// pdf模板所在路径,就是网站制作好后下载的pdf模板路径
String fileName = "C:\\Users\\lgn\\Desktop\\JS-PAS-2208-001222.pdf";
PdfReader reader = new PdfReader(fileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper ps = new PdfStamper(reader, bos);

// 使用中文字体
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());

//必须要调用这个,否则文档会出现你不想出现的东西
ps.setFormFlattening(true);
ps.close();

//生成pdf路径存放的路径
OutputStream fos = new FileOutputStream("C:\\Users\\lgn\\Desktop\\result.pdf");
fos.write(bos.toByteArray());
fos.flush();
fos.close();
bos.close();
}catch (Exception e){
e.printStackTrace();
}
}

/**
* 填充模板中的数据
*/
public static void fillData(AcroFields fields, Map<String, String> data) {
try {
for (String key : data.keySet()) {
String value = data.get(key);
// 为字段赋值,注意字段名称是区分大小写的
fields.setField(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 填充数据源
* 其中data存放的key值与pdf模板中的文本域值相对应
*/
public static Map<String, String> data() {
Map<String, String> data = new HashMap<String, String>();
data.put("executor", "钢铁侠");
data.put("reviewed", "小辣椒");
return data;
}
}

验证一下:

Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)_字段_06