Java使用itext按模板生成PDF表格

╰+攻爆jí腚メ 2024-03-27 16:23 217阅读 0赞

使用 itext 进行 pdf 打印

1、打印自定义表格

在这里插入图片描述

依赖

  1. <dependency>
  2. <groupId>com.itextpdf</groupId>
  3. <artifactId>itextpdf</artifactId>
  4. <version>5.5.13</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.itextpdf</groupId>
  8. <artifactId>itext-asian</artifactId>
  9. <version>5.2.0</version>
  10. </dependency>

代码实现

  1. package pdfgentest;
  2. import com.itextpdf.text.*;
  3. import com.itextpdf.text.pdf.BaseFont;
  4. import com.itextpdf.text.pdf.PdfPCell;
  5. import com.itextpdf.text.pdf.PdfPTable;
  6. import com.itextpdf.text.pdf.PdfWriter;
  7. import java.io.FileOutputStream;
  8. public class PdfTableGenTest {
  9. private static Font headFont;// 设置字体大小
  10. private static Font sonHeadFont;// 设置字体大小
  11. private static Font normalTextFont;// 设置字体大小
  12. private static Font tableLineHeadFont;// 设置字体大小
  13. private static Font tableColumHeadFont;// 设置字体大小
  14. private static Font textFont;// 设置字体大小
  15. private static Font minTextFont;// 设置字体大小
  16. static {
  17. BaseFont bfChinese;
  18. try {
  19. bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
  20. headFont = new Font(bfChinese, 16, Font.BOLD);// 设置字体大小
  21. sonHeadFont = new Font(bfChinese, 10, Font.BOLD);// 设置字体大小
  22. normalTextFont = new Font(bfChinese, 10, Font.NORMAL);// 设置字体大小
  23. tableLineHeadFont = new Font(bfChinese, 8, Font.BOLD);// 设置字体大小
  24. tableColumHeadFont = new Font(bfChinese, 6, Font.BOLD);// 设置字体大小
  25. textFont = new Font(bfChinese, 6, Font.NORMAL);// 设置字体大小
  26. minTextFont = new Font(bfChinese, 5, Font.NORMAL);// 设置字体大小
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. public static void writeExampaperPdf() throws Exception {
  32. // 1.新建document对象
  33. // 第一个参数是页面大小。接下来的参数分别是左、右、上和下页边距。
  34. Document document = new Document(PageSize.A4, 50, 50, 20, 40);
  35. // 2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
  36. // 创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。
  37. PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D://myPdfFile.pdf"));
  38. //3.2打开文档
  39. document.open();
  40. //创建一个包含多列的表格,以通过合并单元格的方式,控制表格的宽度大小
  41. PdfPTable table = createTable(12);
  42. table.addCell(createCell("\n", headFont, Element.ALIGN_CENTER, 4, false));
  43. table.addCell(createCell("客户基本信息表", headFont, Element.ALIGN_CENTER, 4, false));
  44. sonHeadFont.setColor(new BaseColor(205, 133, 63)); //设置字体颜色
  45. table.addCell(createCell("文件编号:FILEBH-001", sonHeadFont, Element.ALIGN_RIGHT, 4, false));
  46. PdfPCell jbxxCell = createCell("基本信息", tableLineHeadFont, Element.ALIGN_CENTER, 12, true);
  47. jbxxCell.setBackgroundColor(new BaseColor(205, 133, 63));
  48. table.addCell(jbxxCell);
  49. //创建单元格,指定字体、对齐方式、合并单元格的个数、是否有边框
  50. table.addCell(createCell("姓名", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  51. table.addCell(createCell(null, textFont, Element.ALIGN_CENTER, 4, true));
  52. table.addCell(createCell("职业", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  53. table.addCell(createCell("工程师", textFont, Element.ALIGN_CENTER, 4, true));
  54. table.addCell(createCell("出生日期", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  55. table.addCell(createCell("2020-01-01", textFont, Element.ALIGN_CENTER, 4, true));
  56. table.addCell(createCell("国籍", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  57. table.addCell(createCell("中国", textFont, Element.ALIGN_CENTER, 4, true));
  58. table.addCell(createCell("性别", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  59. table.addCell(createCell("男", textFont, Element.ALIGN_CENTER, 4, true));
  60. table.addCell(createCell("联系电话", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  61. table.addCell(createCell("18888888888", textFont, Element.ALIGN_CENTER, 4, true));
  62. table.addCell(createCell("个人税收居民身份", tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  63. Phrase phrase = new Phrase();
  64. PdfPCell wtrgrssjmxxCell1 = new PdfPCell();
  65. wtrgrssjmxxCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
  66. wtrgrssjmxxCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
  67. phrase.add(new Chunk("□ 1.中国税收居民 □ 2.非中国税收居民 ■ 3.既是中国税收居民又是其他国家(地区)税收居民\n", minTextFont).setLineHeight(12f));
  68. phrase.add(new Chunk("★ 如以上选项中填选第2项或第3项,请填写下列信息:\n", textFont).setLineHeight(12f));
  69. phrase.add(new Chunk(" 税收居民国(地区):", textFont).setLineHeight(12f));
  70. phrase.add(new Chunk(" HK00001", textFont).setLineHeight(12f).setUnderline(0.5f, -1f));
  71. phrase.add(new Chunk(" 纳税人识别号(如有):", textFont).setLineHeight(12f));
  72. phrase.add(new Chunk("289000001", textFont).setLineHeight(12f).setUnderline(0.5f, -1f)); //设置下划线,并设置下划线的粗细
  73. wtrgrssjmxxCell1.setPhrase(phrase);
  74. wtrgrssjmxxCell1.setPaddingLeft(20f);
  75. wtrgrssjmxxCell1.setColspan(10);
  76. wtrgrssjmxxCell1.setPaddingTop(3.0f);
  77. wtrgrssjmxxCell1.setPaddingBottom(6.0f);
  78. table.addCell(wtrgrssjmxxCell1);
  79. PdfPCell cclyCell = createCell("保险清单列表", tableLineHeadFont, Element.ALIGN_CENTER, 12, true);
  80. cclyCell.setBackgroundColor(new BaseColor(205, 133, 63)); //设置单元格背景
  81. table.addCell(cclyCell);
  82. for (int i = 0; i < 2; i++) {
  83. table.addCell(createCell("保险清单" + (i + 1), tableColumHeadFont, Element.ALIGN_CENTER, 2, true));
  84. Phrase insurancePhrase1 = new Phrase();
  85. PdfPCell insuranceCell1 = new PdfPCell();
  86. insuranceCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); //上下居中
  87. insuranceCell1.setHorizontalAlignment(Element.ALIGN_LEFT); //水平左对齐
  88. insurancePhrase1.add(new Chunk("1.保险产品名称:灵通万事家天下寿险" + i + "\n", textFont).setLineHeight(10f)); //setLineHeight 设置行高
  89. insurancePhrase1.add(new Chunk("3.保险单号:L000000002392997" + i + "\n", textFont).setLineHeight(10f));
  90. insurancePhrase1.add(new Chunk("5.保险险种:终身寿险" + "\n", textFont).setLineHeight(10f));
  91. insurancePhrase1.add(new Chunk("7.基本保额:250000" + i + "\n", textFont).setLineHeight(10f));
  92. insurancePhrase1.add(new Chunk("9.备注(其他情况说明):无", textFont).setLineHeight(10f));
  93. insuranceCell1.setPhrase(insurancePhrase1);
  94. insuranceCell1.setPaddingLeft(10f);//设置左侧空白填充的宽度
  95. insuranceCell1.setColspan(5); //合并单元格
  96. insuranceCell1.setPaddingTop(1.0f); //距离上边框距离
  97. insuranceCell1.setPaddingBottom(4.0f); //距离下边框距离
  98. insuranceCell1.disableBorderSide(8);//隐藏右边框 1-上, 2-下, 4-左, 8-右
  99. table.addCell(insuranceCell1);
  100. Phrase insurancePhrase2 = new Phrase();
  101. PdfPCell insuranceCell2 = new PdfPCell();
  102. insuranceCell2.setVerticalAlignment(Element.ALIGN_MIDDLE); //上下居中
  103. insuranceCell2.setHorizontalAlignment(Element.ALIGN_LEFT); //水平左对齐
  104. insurancePhrase2.add(new Chunk("2.保险公司:灵通万事" + i + "\n", textFont).setLineHeight(10f));
  105. insurancePhrase2.add(new Chunk("4.保单生效日:2020/12/0" + i + "\n", textFont).setLineHeight(10f));
  106. insurancePhrase2.add(new Chunk("6.应交总保费:1290500" + i + "\n", textFont).setLineHeight(10f));
  107. insurancePhrase2.add(new Chunk("8.受益人变更情况:生存受益人变更为保险公司;身故受益人变更为保险公司\n", textFont).setLineHeight(10f));
  108. insurancePhrase2.add(new Chunk(" \n", textFont).setLineHeight(10f));
  109. insuranceCell2.setPhrase(insurancePhrase2);
  110. insuranceCell2.setColspan(5);
  111. insuranceCell2.setPaddingTop(1.0f);
  112. insuranceCell2.setPaddingBottom(4.0f);
  113. insuranceCell2.disableBorderSide(4);//隐藏左边框: 1-上, 2-下, 4-左, 8-右
  114. table.addCell(insuranceCell2);
  115. }
  116. PdfPCell syrmxCell = createCell("受益人情况", tableLineHeadFont, Element.ALIGN_CENTER, 12, true);
  117. syrmxCell.setBackgroundColor(new BaseColor(205, 133, 63));
  118. table.addCell(syrmxCell);
  119. for (int i = 0; i < 1; i++) {
  120. table.addCell(createCell("受益人" + (i + 1), tableColumHeadFont, Element.ALIGN_CENTER, 1, true));
  121. Phrase syrPhrase1 = new Phrase();
  122. PdfPCell syrCell1 = new PdfPCell();
  123. syrCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
  124. syrCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
  125. syrPhrase1.add(new Chunk("姓名:王小" + i + "\n", textFont).setLineHeight(10f));
  126. syrPhrase1.add(new Chunk("与委托人关系:儿子\n", textFont).setLineHeight(10f));
  127. syrPhrase1.add(new Chunk("婚姻状况:未婚\n", textFont).setLineHeight(10f));
  128. syrPhrase1.add(new Chunk("联系电话:1887878000" + i + "\n", textFont).setLineHeight(10f));
  129. syrPhrase1.add(new Chunk("电子邮箱:8888888@168.com\n", textFont).setLineHeight(10f));
  130. syrPhrase1.add(new Chunk("邮寄地址:北京市朝阳区光明路128号5栋102\n", textFont).setLineHeight(10f));
  131. syrPhrase1.add(new Chunk("终止分配比例:100%", textFont).setLineHeight(10f));
  132. syrCell1.setPhrase(syrPhrase1);
  133. syrCell1.setPaddingLeft(10f);
  134. syrCell1.setColspan(5);
  135. syrCell1.setPaddingTop(1.0f);
  136. syrCell1.setPaddingBottom(4.0f);
  137. table.addCell(syrCell1);
  138. table.addCell(createCell("个人税收居民身份", tableColumHeadFont, Element.ALIGN_CENTER, 1, true));
  139. Phrase syrgrssjmxxPhrase = new Phrase();
  140. PdfPCell syrgrssjmxxCell1 = new PdfPCell();
  141. syrgrssjmxxCell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
  142. syrgrssjmxxCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
  143. syrgrssjmxxPhrase.add(new Chunk("■ 1.中国税收居民 □ 2.非中国税收居民 □ 3.既是中国又是其他国家(地区)税收居民\n", minTextFont).setLineHeight(15f));
  144. syrgrssjmxxPhrase.add(new Chunk("★ 如以上选项中填选第2项或第3项,请填写下列信息:\n", textFont).setLineHeight(15f));
  145. syrgrssjmxxPhrase.add(new Chunk(" 税收居民国(地区):▁▁▁▁ 纳税人识别号(如有):▁▁▁▁", textFont).setLineHeight(15f));
  146. syrgrssjmxxCell1.setPhrase(syrgrssjmxxPhrase);
  147. syrgrssjmxxCell1.setPaddingLeft(6f);
  148. syrgrssjmxxCell1.setColspan(5);
  149. syrgrssjmxxCell1.setPaddingTop(3.0f);
  150. syrgrssjmxxCell1.setPaddingBottom(6.0f);
  151. table.addCell(syrgrssjmxxCell1);
  152. }
  153. document.add(table);
  154. document.add(new Paragraph("\n"));
  155. String paragraph5 = "客户(签字):▁▁▁▁▁▁▁▁";
  156. Paragraph elements5 = new Paragraph(paragraph5, normalTextFont);
  157. elements5.setAlignment(Element.ALIGN_RIGHT);
  158. document.add(elements5);
  159. // 5.关闭文档
  160. document.close();
  161. }
  162. //建表
  163. public static PdfPTable createTable(int colNumber) {
  164. int maxWidth = 500;
  165. PdfPTable table = new PdfPTable(colNumber);
  166. try {
  167. table.setTotalWidth(maxWidth);
  168. table.setLockedWidth(true);
  169. table.setHorizontalAlignment(Element.ALIGN_CENTER);
  170. table.setWidths(new int[]{
  171. 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50});
  172. table.getDefaultCell().setBorder(1);
  173. } catch (Exception e) {
  174. e.printStackTrace();
  175. }
  176. return table;
  177. }
  178. //抽取公共代码,为每个元素设置格式样式
  179. public static PdfPCell createCell(String value, Font font, int align, int colspan, boolean boderFlag) {
  180. PdfPCell cell = new PdfPCell();
  181. cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
  182. cell.setHorizontalAlignment(align);
  183. cell.setColspan(colspan);
  184. cell.setPhrase(new Phrase(value, font));
  185. cell.setPadding(3.0f);
  186. if (!boderFlag) {
  187. //首行无边框等样式
  188. cell.setBorder(0);
  189. cell.setPaddingTop(15.0f);
  190. cell.setPaddingBottom(8.0f);
  191. }
  192. return cell;
  193. }
  194. public static void main(String[] args) {
  195. try {
  196. writeExampaperPdf();
  197. } catch (Exception e) {
  198. e.printStackTrace();
  199. }
  200. }
  201. }

参考

2、对模板表格进行填写

1 制作PDF模板

使用 Adobe 公司提供的 Adobe Acrobat Pro DC 软件进行制作

在这里插入图片描述

2 通过模板生成PDF文件

依赖
  1. <dependency>
  2. <groupId>com.itextpdf</groupId>
  3. <artifactId>itextpdf</artifactId>
  4. <version>5.5.13</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.itextpdf</groupId>
  8. <artifactId>itext-asian</artifactId>
  9. <version>5.2.0</version>
  10. </dependency>
代码实现
  1. package pdfdemo;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.OutputStream;
  6. import java.util.ArrayList;
  7. import java.util.HashMap;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import java.util.Map;
  11. import com.itextpdf.text.DocumentException;
  12. import com.itextpdf.text.pdf.AcroFields;
  13. import com.itextpdf.text.pdf.AcroFields.Item;
  14. import com.itextpdf.text.pdf.BaseFont;
  15. import com.itextpdf.text.pdf.PdfReader;
  16. import com.itextpdf.text.pdf.PdfStamper;
  17. public class PDFUtils {
  18. /**
  19. * 将要填入的内容,data即数据,键为创建模板时已定义的域列表,值为数据
  20. * @param fields
  21. * @param data
  22. * @throws IOException
  23. * @throws DocumentException
  24. */
  25. private static void fillData(AcroFields fields, Map<String, String> data) throws IOException, DocumentException {
  26. List<String> keys = new ArrayList<String>();
  27. Map<String, Item> formFields = fields.getFields();
  28. for (String key : data.keySet()) {
  29. if (formFields.containsKey(key)) {
  30. String value = data.get(key);
  31. fields.setField(key, value); // 为字段赋值,注意字段名称是区分大小写的
  32. keys.add(key);
  33. }
  34. }
  35. Iterator<String> itemsKey = formFields.keySet().iterator();
  36. while (itemsKey.hasNext()) {
  37. String itemKey = itemsKey.next();
  38. if (!keys.contains(itemKey)) {
  39. fields.setField(itemKey, " ");
  40. }
  41. }
  42. }
  43. /**
  44. * @param templatePdfPath 模板pdf路径
  45. * @param generatePdfPath 生成pdf路径
  46. * @param data 数据
  47. */
  48. public static String generatePDF(String templatePdfPath, String generatePdfPath, Map<String, String> data) {
  49. OutputStream fos = null;
  50. ByteArrayOutputStream bos = null;
  51. try {
  52. PdfReader reader = new PdfReader(templatePdfPath);
  53. bos = new ByteArrayOutputStream();
  54. /* 将要生成的目标PDF文件名称 */
  55. PdfStamper ps = new PdfStamper(reader, bos);
  56. /* 使用中文字体 */
  57. BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
  58. ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
  59. fontList.add(bf);
  60. /* 取出报表模板中的所有字段 */
  61. AcroFields fields = ps.getAcroFields();
  62. fields.setSubstitutionFonts(fontList);
  63. fillData(fields, data);
  64. /* 必须要调用这个,否则文档不会生成的 如果为false那么生成的PDF文件还能编辑,一定要设为true*/
  65. ps.setFormFlattening(true);
  66. ps.close();
  67. fos = new FileOutputStream(generatePdfPath);
  68. fos.write(bos.toByteArray());
  69. fos.flush();
  70. return generatePdfPath;
  71. } catch (Exception e) {
  72. e.printStackTrace();
  73. } finally {
  74. if (fos != null) {
  75. try {
  76. fos.close();
  77. } catch (IOException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81. if (bos != null) {
  82. try {
  83. bos.close();
  84. } catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. }
  88. }
  89. return null;
  90. }
  91. public static void main(String[] args) {
  92. Map<String, String> data = new HashMap<String, String>();
  93. //key为pdf模板的form表单的名字,value为需要填充的值
  94. data.put("title", "河海市人民医院诊疗病历单");
  95. data.put("case", "123456789");
  96. data.put("date", "2020.11.02");
  97. data.put("name", "熊瞎子");
  98. data.put("sex", "男");
  99. data.put("age", "29");
  100. data.put("phone", "137888880000");
  101. data.put("office", "内科");
  102. data.put("cert", "身痒找打");
  103. data.put("drug", "1、奥美拉唑肠溶胶囊 0.25g10粒×2板 ");
  104. data.put("dose", "×2盒");
  105. data.put("cons", "用法用量:口服 一日两次 一次2粒");
  106. data.put("tips", "温馨提示");
  107. data.put("desc", "尽量呆在通风较好的地方,保持空气流通,有利于病情康复。尽量呆在通风较好的地方");
  108. generatePDF("D:\\tpl2.pdf",
  109. "D:\\filled.pdf", data);
  110. }
  111. }
生成效果

在这里插入图片描述

参考

发表评论

表情:
评论列表 (有 0 条评论,217人围观)

还没有评论,来说两句吧...

相关阅读