Java使用IText根据pdf模板创建pdf文件

1.导包

java 复制代码
 <dependency>
     <groupId>com.itextpdf</groupId>
     <artifactId>itextpdf</artifactId>
    <version>5.5.10</version>
 </dependency>
 <dependency>
     <groupId>com.itextpdf</groupId>
     <artifactId>itext-asian</artifactId>
     <version>5.2.0</version>
 </dependency>
 <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

2.绘制pdf模板

3.示例代码

java 复制代码
/**
 * 读取pdf模板填充生成pdf文件并转为字节数组
 * @return
 */
public byte[] createPdf() {
	//获取源数据(一般从数据库查询,此处通过构造数据简化处理)
	List<Plan> plans = this.getPlans();
       final int size = plans.size();
       //临时文件
       final String outputFilePath = "D:/" + System.currentTimeMillis() + ".pdf";
       OutputStream os = null;
       PdfStamper ps = null;
       PdfReader reader = null;
       PdfReader reader2 = null;
       Document document = null;
       ByteArrayOutputStream byteArrayOutputStream = null;
       PdfCopy pdfNew = null;
       try {
           //读入pdf表单
           reader = new PdfReader(this.getClass().getResourceAsStream("/template/test.pdf"));
           //根据表单生成一个新的pdf
           os = Files.newOutputStream(new File(outputFilePath).toPath());
           ps = new PdfStamper(reader, os);
           //获取pdf表
           AcroFields form = ps.getAcroFields();
           form.setField("contractNo", "HT2024042501");//合同号
           form.setField("paymentDate", "2022-12-01");//放款日期
           form.setField("expiredDate", "2023-12-01");//到期日期
           ps.setFormFlattening(true);
           List<AcroFields.FieldPosition> table = form.getFieldPositions("table");
           Rectangle rect = table.get(0).position;
           PdfPTable pTable = new PdfPTable(8);
           BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
           Font fontZH = new Font(bfChinese, 10f, 0);
           pTable.getDefaultCell().setHorizontalAlignment(1);
           pTable.setWidthPercentage(100.0f);
           float totalWidth = rect.getRight() - rect.getLeft() - 1;
           //计算表格宽度
           float[] columnWidth = {(float) (totalWidth * 0.05), (float) (totalWidth * 0.15), (float) (totalWidth * 0.15), (float) (totalWidth * 0.15), (float) (totalWidth * 0.15), (float) (totalWidth * 0.13), (float) (totalWidth * 0.13), (float) (totalWidth * 0.09)};
           pTable.setTotalWidth(columnWidth);
           pTable.setLockedWidth(true);
           for (Plan plan : plans) {
               Integer periodNo = plan.getPeriodNo();
               int border = (periodNo % 12 == 0 || periodNo == size) ? Rectangle.BOTTOM : Rectangle.NO_BORDER;
               pTable.addCell(generateCell(String.valueOf(periodNo), border, fontZH));
               pTable.addCell(generateCell(plan.getMatchDate(), border, fontZH));
               pTable.addCell(generateCell(plan.getRepayOriginal(), border, fontZH));
               pTable.addCell(generateCell(plan.getPenalty(), border, fontZH));
               pTable.addCell(generateCell(plan.getRepayAmount(), border, fontZH));
               pTable.addCell(generateCell(plan.getRestOriginal(), border, fontZH));
               pTable.addCell(generateCell(plan.getRepayDate(), border, fontZH));
               pTable.addCell(generateCell(plan.getRepayStatus(), border, fontZH));
           }
           pTable.setKeepTogether(true);
           pTable.setSplitLate(false);
           pTable.setSplitRows(true);
           //计算需要分页的总页数
           int totalpage = size % 12 == 0 ? size / 12 : size / 12 + 1;
           if (totalpage == 1) {
               //获table页面
               PdfContentByte under = ps.getOverContent(1);
               //添加table
               pTable.writeSelectedRows(0, -1, rect.getLeft(), rect.getTop(), under);
           } else {
               for (int i = 1; i <= totalpage; i++) {
                   PdfContentByte under = ps.getOverContent(i);
                   if (i == 1) {
                       pTable.writeSelectedRows(0, 12, rect.getLeft(), rect.getTop(), under);
                   } else {
                       pTable.writeSelectedRows((i - 1) * 12, i * 12, rect.getLeft(), rect.getTop(), under);
                   }
               }
           }
           ps.close();
           reader2 = new PdfReader(outputFilePath);
           document = new Document(reader2.getPageSizeWithRotation(1));
           byteArrayOutputStream = new ByteArrayOutputStream();
           pdfNew = new PdfCopy(document, byteArrayOutputStream);
           document.open();
           PdfImportedPage page;
           for (int i = 1; i <= totalpage; i++) {
               page = pdfNew.getImportedPage(reader2, i);
               pdfNew.addPage(page);
           }
           document.close();
           os.close();
           pdfNew.close();
           reader.close();
           reader2.close();
           FileUtils.delete(new File(outputFilePath));
           return byteArrayOutputStream.toByteArray();
       } catch (Exception e) {
       	e.printStackTrace();
       } finally {
           try {
               if (ps != null) {
                   ps.close();
               }
               if (reader != null) {
                   reader.close();
               }
               if (os != null) {
                   os.close();
               }
               if (document != null) {
                   document.close();
               }
               if (pdfNew != null) {
                   pdfNew.close();
               }
               if (reader2 != null) {
                   reader2.close();
               }
               if (byteArrayOutputStream != null) {
                   byteArrayOutputStream.close();
               }
           } catch (Exception e) {
           	e.printStackTrace();
           }
       }
	return null;
}

private List<Plan> getPlans() {
	List<Plan> plans = new ArrayList<Plan>();
	for(int i=1;i<=12;i++) {
		plans.add(new Plan(i,"2023-"+String.format("%02d", i)+"-01","999","-", "999","0","2023-"+String.format("%02d", i)+"-01", "已结清"));
	}
	return plans;
}

   private PdfPCell generateCell(String value, int border, Font fontZH) {
       PdfPCell cell = new PdfPCell(new Phrase(value, fontZH));
       cell.setBorder(border);
       cell.setHorizontalAlignment(Element.ALIGN_CENTER);
       return cell;
   }
   
   public static void main(String [] args) throws FileNotFoundException, IOException {
   	//将字节流转为pdf文件放于D盘
       OutputStream fileOut = new FileOutputStream("D:/a.pdf");
       fileOut.write(new TestPdf().createPdf());
   }

4.执行结果

5.所用到jar包下载地址
itextpdf-5.5.10.jar

欢迎大家积极留言交流学习心得,点赞的人最美丽!

相关推荐
wuminyu11 分钟前
深入剖析 Panama Off-heap 的性能损耗与开销
java·linux·c语言·jvm·c++
pnoker20 分钟前
IoT DC3 AI 能力:Agentic Center 的设计与边界
java·人工智能·物联网·大模型·spring ai
xiaoqiMikko1 小时前
一条 CVSS 9.0 的 RCE,advisory 里没写修复版是哪个 —— fastjson 16723 的字段考古
java·安全
程序员贺加贝1 小时前
一次 SaaS ERP 主数据生命周期设计:Policy、PreCheck 与结构化阻断原因
java·后端·架构·saas
catino1 小时前
spring-Bean
java·后端·spring
深入云栈1 小时前
Netty 4.2.x 源码深度解析 (十一):EventExecutor 业务线程池 —— 防止 IO 线程阻塞的并发模型
java·后端
吴声子夜歌1 小时前
Java——基本类型
java·开发语言
CoderYanger3 小时前
A.每日一题:输入单词需要的最少按键次数 Ⅰ+Ⅱ
java·数据结构·算法·leetcode·面试
Cosolar3 小时前
一文弄懂 Agent Harness 与 Agent Runtime 的区别
java·后端·github
吴声子夜歌3 小时前
Java——类、对象及方法(一)
java·开发语言