可用于公司用户合同导出pdf文件
效果图
一、导入所需要jar包
<!--生成PDF-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.icepdf.os</groupId>
<artifactId>icepdf-core</artifactId>
<version>6.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
二、工具类代码实现
package com.example.excel.pdf;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author: reshui
* description:
* DateTime:2025/2/25-17:40
*/
@Slf4j
public class PdfTemplateFillUtil {
/**
* 文件暂存地址
*/
public static final String TEMP_FILE_PATH = System.getProperty("java.io.tmpdir");
/**
* pdf文件暂存地址
*/
private static final String FILE_PATH = TEMP_FILE_PATH + File.separator + "generate_pdf";
/**
* 时间格式
*/
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static void main(String[] args) {
Map<String, Object> paramsMap = new HashMap<String, Object>();
Map<String, Object> textAreaMap = new HashMap<String, Object>();
Map<String, Object> imageAreaMap = new HashMap<String, Object>();
textAreaMap.put("partyAName", "胡图图");
textAreaMap.put("partyBName", "胡英俊");
textAreaMap.put("address", "翻斗大街翻斗花园二号楼1001室");
textAreaMap.put("systemOrderNumber", "Vx2024121315555020011");
textAreaMap.put("idCard", "44xxxxxxxxxxx132123");
textAreaMap.put("mobile", "185700xxxxxx");
textAreaMap.put("remark", " * BaseFont.NOT_EMBEDDED该参数指定是否将字体嵌入到生成的 PDF 文件中。BaseFont.NOT_EMBEDDED 表示不嵌入字体,即生成的 PDF 文件不会包含字体文件本身,而是依赖于查看 PDF 的设备上是否安装了相应的字体。如果设置为 BaseFont.EMBEDDED,则会将字体文件嵌入到 PDF 中,确保在任何设备上都能正确显示字体,但会增加 PDF 文件的大小。\n");
String formatDateTime = DateUtil.formatDateTime(new Date());
textAreaMap.put("now", formatDateTime);
textAreaMap.put("haha", "你好呀,我是胡图图");
textAreaMap.put("checkNow", "yes");
textAreaMap.put("check2", "yes");
paramsMap.put("textAreaMap", textAreaMap);
imageAreaMap.put("companySign", "https://profile-avatar.csdnimg.cn/128f2647a3ac408eafb94c7a6706689b_weixin_42477252.jpg!1");
imageAreaMap.put("signatureImg", "https://profile-avatar.csdnimg.cn/128f2647a3ac408eafb94c7a6706689b_weixin_42477252.jpg!1");
paramsMap.put("imageAreaMap", imageAreaMap);
easyGeneratePdf(paramsMap, "C:\\Users\\86138\\Desktop\\xxx\\123.pdf");
}
public static void easyGeneratePdf(Map<String, Object> areaMap, String fileName, String readPdfTemplateUrl) {
String formatDateTimeStamp = DateUtil.format(new Date(), YYYYMMDDHHMMSS);
String pdfFilePath = FILE_PATH + File.separator + formatDateTimeStamp + StrUtil.UNDERLINE + fileName + ".pdf";
FileUtil.touch(pdfFilePath);
generatePdf(areaMap, pdfFilePath, readPdfTemplateUrl);
}
public static void easyGeneratePdf(Map<String, Object> areaMap, String readPdfTemplateUrl) {
String formatDateTimeStamp = DateUtil.format(new Date(), YYYYMMDDHHMMSS);
String pdfFilePath = FILE_PATH + File.separator + formatDateTimeStamp + ".pdf";
FileUtil.touch(pdfFilePath);
generatePdf(areaMap, pdfFilePath, readPdfTemplateUrl);
}
/**
* 模板填充生成PDF
*
* @param areaMap 域集合
* @param outPutPdfFilePath 输出文件路径
* @param readPdfTemplateUrlOrPath 读取pdf模板路径
* Linix 字体
* BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
* Windows 字体
* BaseFont bf = BaseFont.createFont("c://windows//fonts//simsunb.ttf" , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
* <p>
* BaseFont.IDENTITY_H这个参数指定了字符编码。BaseFont.IDENTITY_H 表示使用 Unicode 水平书写方向的编码,这对于支持中文等多语言字符非常重要。如果不使用合适的编码,可能会导致字符显示乱码。
* BaseFont.NOT_EMBEDDED该参数指定是否将字体嵌入到生成的 PDF 文件中。BaseFont.NOT_EMBEDDED 表示不嵌入字体,即生成的 PDF 文件不会包含字体文件本身,而是依赖于查看 PDF 的设备上是否安装了相应的字体。如果设置为 BaseFont.EMBEDDED,则会将字体文件嵌入到 PDF 中,确保在任何设备上都能正确显示字体,但会增加 PDF 文件的大小。
*/
protected static synchronized File generatePdf(Map<String, Object> areaMap, String outPutPdfFilePath, String readPdfTemplateUrlOrPath) {
PdfReader reader;
FileOutputStream out;
ByteArrayOutputStream bos;
PdfStamper stamper;
PdfTemplateFillConfig config = getSystemType();
try {
Document doc = new Document();
BaseFont bf = BaseFont.createFont(config.getFontName(), config.getEncoding(), config.getEmbedded());
out = new FileOutputStream(outPutPdfFilePath);// 输出模板
//读取 PDF 模板
reader = new PdfReader(readPdfTemplateUrlOrPath);
bos = new ByteArrayOutputStream();
// 创建一个 PdfStamper 对象,用于修改 PDF
stamper = new PdfStamper(reader, bos);
// 获取 PDF 中的表单域
AcroFields form = stamper.getAcroFields();
//文字类的内容处理
Map<String, String> textAreaMap = (Map<String, String>) areaMap.get("textAreaMap");
if (Objects.nonNull(textAreaMap) && !textAreaMap.isEmpty()) {
// 遍历表单数据,将数据填充到对应的表单域中
for (Map.Entry<String, String> entry : textAreaMap.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
if (fieldName.startsWith("check")) {
form.setField(fieldName, fieldValue, true);
} else {
form.setField(fieldName, fieldValue);
}
}
}
form.addSubstitutionFont(bf);
//图片类的内容处理
Map<String, String> imageAreaMap = (Map<String, String>) areaMap.get("imageAreaMap");
if (Objects.nonNull(imageAreaMap) && !imageAreaMap.isEmpty()) {
// 遍历表单数据,将数据填充到对应的表单域中
for (Map.Entry<String, String> entry : imageAreaMap.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions(fieldName);
if (form.getFieldPositions(fieldName) != null) {
int pageNo = fieldPositions.get(0).page;
Rectangle signRect = fieldPositions.get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
//根据路径读取图片
Image image = Image.getInstance(fieldValue);
//获取图片页面
PdfContentByte under = stamper.getOverContent(pageNo);
//图片大小自适应
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
//添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
}
}
///*必须要调用这个,否则文档不会生成的 如果为false那么生成的PDF文件还能编辑,一定要设为true*/
stamper.setFormFlattening(true);
stamper.close();
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
for (int i = 1; i < reader.getNumberOfPages() + 1; i++) {
doc.newPage();
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i);
copy.addPage(importPage);
}
doc.close();
File file = new File(outPutPdfFilePath);
log.info("pdf文件生成成功,文件路径为:" + file.getAbsolutePath());
return file;
} catch (Exception e) {
log.error("pdf文件生成失败:", e);
}
return null;
}
public static PdfTemplateFillConfig getSystemType() {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
return PdfTemplateFillConfig.getWindowsInstance();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
return PdfTemplateFillConfig.getLinuxInstance();
} else {
log.error("未知操作系统,无法加载配置。os-{}", os);
return null;
}
}
}
package com.example.excel.pdf;
import lombok.Data;
/**
* @author: reshui
* description:
* DateTime:2025/2/28-15:48
*/
@Data
public class PdfTemplateFillConfig {
/**
* 字体名
*/
private String fontName;
/**
* 编码
*/
private String encoding;
/**
* 是否嵌入字体
* 该参数指定是否将字体嵌入到生成的 PDF 文件中。BaseFont.NOT_EMBEDDED 表示不嵌入字体,即生成的 PDF 文件不会包含字体文件本身,
* 而是依赖于查看 PDF 的设备上是否安装了相应的字体。如果设置为 BaseFont.EMBEDDED,则会将字体文件嵌入到 PDF 中,确保在任何设备上都能正确显示字体,
* 但会增加 PDF 文件的大小。
*/
private Boolean embedded;
public static PdfTemplateFillConfig getLinuxInstance() {
PdfTemplateFillConfig config = new PdfTemplateFillConfig();
config.setFontName("STSong-Light");
config.setEncoding("UniGB-UCS2-H");
config.setEmbedded(true);
return config;
}
public static PdfTemplateFillConfig getWindowsInstance() {
PdfTemplateFillConfig config = new PdfTemplateFillConfig();
config.setFontName("c://windows//fonts//simsunb.ttf");
config.setEncoding("Identity-H");
config.setEmbedded(true);
return config;
}
}
三、pdf模板效果
四、实现效果图