使用itextpdf 生成pdf的两种方式
因最近有个需求里要做个生成pdf的功能,在网上找了很久相关的资料,决定使用 itextpdf ,使用到了两种方式,记下来,万一以后再用到呢
第一种自己生成文件所有内容
第二种按照模板生成pdf
话不多说,上代码
<!-- 引入依赖-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- 解决中文乱码/不显示问题 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
/**
* 简单的例子,生成一个pdf里面是表格
*
* @throws Exception
*/
public static void createdPdf() throws IOException, DocumentException {
//文档对象
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
File file = new File("F:\\1\\123.pdf");
if (!file.exists()) {
file.createNewFile();
}
//创建写入对象
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
//打开文档对象
document.open();
//字体 - 编码 设置为宋体,中文正常现实
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//大小
Font font = new Font(bfChinese, 16);
//颜色
font.setColor(BaseColor.BLACK);
//列数
PdfPTable t = new PdfPTable(3);
t.setSpacingBefore(10);
t.setSpacingAfter(10);
//一个cell 代表一个单元格
PdfPCell cell = new PdfPCell(new Phrase("挂钩标的表现参考情况表", font));
// 设置单元格高度
cell.setMinimumHeight(20);
// 设置可以居中
cell.setUseAscender(true);
// 设置水平居中
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
// 设置垂直居中
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
//无边框
cell.setBorder(0);
//设置合并3个单元格
cell.setColspan(3);
t.addCell(cell);
cell = new PdfPCell(new Phrase("观察日期", font));
cell.setMinimumHeight(20);
cell.setUseAscender(true);
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
cell.setFixedHeight(20f);
t.addCell(cell);
cell = new PdfPCell(new Phrase("挂钩标的", font));
cell.setMinimumHeight(20);
cell.setUseAscender(true);
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
cell.setFixedHeight(20f);
t.addCell(cell);
cell = new PdfPCell(new Phrase("挂钩标的表现值", font));
cell.setMinimumHeight(20);
cell.setUseAscender(true);
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
cell.setFixedHeight(20f);
t.addCell(cell);
//测试用数据
for (int i = 0; i < 5; i++) {
cell=new PdfPCell(new Phrase("2020-10-55", font));
cell.setMinimumHeight(20);
cell.setUseAscender(true);
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
cell.setFixedHeight(20f);
t.addCell(cell);
cell=new PdfPCell(new Phrase("沪深300指数", font));
cell.setMinimumHeight(20);
cell.setUseAscender(true);
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
cell.setFixedHeight(20f);
t.addCell(cell);
cell=new PdfPCell(new Phrase("20211.33", font));
cell.setMinimumHeight(20);
cell.setUseAscender(true);
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
cell.setFixedHeight(20f);
t.addCell(cell);
}
//将表格对象添加至文档对象
document.add(t);
//一定要关闭,不然pdf会打不开
document.close();
writer.close();
}
测试效果
对于生成详细的pdf感兴趣的可以参考以下链接,写的比较详细
http://www.ibm.com/developerworks/cn/opensource/os-javapdf/
我自己测试用的模板
https://download.csdn.net/download/weixin_45500120/14156493
对于填充模板首先需要一个模板
首先新建一个word文档,里面随便放个表格
创建pdf,我使用的软件是Adobe Acrobat DC
首先根据之前创建的word文档创建PDF模板
打开后点击创建表单,选择当前打开文件点击开始
可以看到空白的地方已经自动填充的有文本域,也可以手动选择上面的添加文本域到想要填充的地方,
双击右边文本域可以修改名称 , 文本域名称后面填充数据时要一致
之后直接保存就可以使用模板了
/**
* 根据模板生成pdf 需要设置模板中的表单
*
* @throws Exception
*/
public static void createAllPdf() throws Exception {
//填充创建pdf
PdfReader reader = null;
PdfStamper stamp = null;
try {
reader = new PdfReader("E:/test.pdf");
SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd");
String times = simp.format(new Date()).trim();
//创建生成报告名称
String root = "F:\\1\\" + File.separator;
if (!new File(root).exists()) {
new File(root).mkdirs();
}
File deskFile = new File(root, times + ".pdf");
stamp = new PdfStamper(reader, new FileOutputStream(deskFile));
//取出报表模板中的所有字段
AcroFields form = stamp.getAcroFields();
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font f = new Font(bf, 18, Font.NORMAL);
ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
fontList.add(bf);
//设置文字字体
form.setSubstitutionFonts(fontList);
// 填充数据
form.setField("01", "产品开22始观察日");
form.setField("02", "男");
form.setField("03", "15");
form.setField("04", "产品结察日");
form.setField("05", "这个不太好卖呀");
form.setField("06", "我觉得还可以");
//报告生成日期
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
String generationdate = dateformat.format(new Date());
form.setField("generationdate", generationdate);
stamp.setFormFlattening(true);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stamp != null) {
stamp.close();
}
if (reader != null) {
reader.close();
}
}
}
测试效果图
填充模板有个问题,字体大小设置不怎么好使
可以参考GitHub文档设置大小.我试着没什么卵用
https://github.com/rongfengliang/itextpdf-image-learning/blob/76fc137eec9f541e5e59b8cc975a77da0c0ed025/src/main/java/com/dalong/Application.java#L53