由于基于模板生成pdf文件的方式,无法灵活支持同类别不固定行数的信息展示,所以只能改为不依靠模板的方式。现将我开发实现过程,做一简单分享。算是一个总结,便于自己日后查阅,也希望能够帮助到其他有需要的同学。
需要参考的,看一下我下面截图的结果样式,再看一下对应的测试代码就可以使用了。
1. 生成结果样式
网络异常,图片无法展示
|
pdf表格文件示例
2. 生成PDF文件实现方式
具体实现:
2.1 引入jar包
<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>
2.2 具体代码如下:
不啰嗦直接上代码,具体含义如果不清楚的话,可以看注释,我已经把注释尽可能的写详细了。
package pdfgentest; import com.itextpdf.text.*; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileOutputStream; public class PdfTableGenTest { private static Font headFont;// 设置字体大小 private static Font sonHeadFont;// 设置字体大小 private static Font normalTextFont;// 设置字体大小 private static Font tableLineHeadFont;// 设置字体大小 private static Font tableColumHeadFont;// 设置字体大小 private static Font textFont;// 设置字体大小 private static Font minTextFont;// 设置字体大小 static { BaseFont bfChinese; try { bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); headFont = new Font(bfChinese, 16, Font.BOLD);// 设置字体大小 sonHeadFont = new Font(bfChinese, 10, Font.BOLD);// 设置字体大小 normalTextFont = new Font(bfChinese, 10, Font.NORMAL);// 设置字体大小 tableLineHeadFont = new Font(bfChinese, 8, Font.BOLD);// 设置字体大小 tableColumHeadFont = new Font(bfChinese, 6, Font.BOLD);// 设置字体大小 textFont = new Font(bfChinese, 6, Font.NORMAL);// 设置字体大小 minTextFont = new Font(bfChinese, 5, Font.NORMAL);// 设置字体大小 } catch (Exception e) { e.printStackTrace(); } } public static void writeExampaperPdf() throws Exception { // 1.新建document对象 // 第一个参数是页面大小。接下来的参数分别是左、右、上和下页边距。 Document document = new Document(PageSize.A4, 50, 50, 20, 40); // 2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。 // 创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D://myPdfFile.pdf")); //3.2打开文档 document.open(); //创建一个包含多列的表格,以通过合并单元格的方式,控制表格的宽度大小 PdfPTable table = createTable(12); table.addCell(createCell("\n", headFont, Element.ALIGN_CENTER, 4, false)); table.addCell(createCell("客户基本信息表", headFont, Element.ALIGN_CENTER, 4, false)); sonHeadFont.setColor(new BaseColor(205, 133, 63)); //设置字体颜色 table.addCell(createCell("文件编号:FILEBH-001", sonHeadFont, Element.ALIGN_RIGHT, 4, false)); PdfPCell jbxxCell = createCell("基本信息", tableLineHeadFont, Element.ALIGN_CENTER, 12, true); jbxxCell.setBackgroundColor(new BaseColor(205, 133, 63)); table.addCell(jbxxCell); //创建单元格,指定字体、对齐方式、合并单元格的个数、是否有边框 table.addCell(createCell("姓名", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); table.addCell(createCell(null, textFont, Element.ALIGN_CENTER, 4, true)); table.addCell(createCell("职业", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); table.addCell(createCell("工程师", textFont, Element.ALIGN_CENTER, 4, true)); table.addCell(createCell("出生日期", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); table.addCell(createCell("2020-01-01", textFont, Element.ALIGN_CENTER, 4, true)); table.addCell(createCell("国籍", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); table.addCell(createCell("中国", textFont, Element.ALIGN_CENTER, 4, true)); table.addCell(createCell("性别", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); table.addCell(createCell("男", textFont, Element.ALIGN_CENTER, 4, true)); table.addCell(createCell("联系电话", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); table.addCell(createCell("18888888888", textFont, Element.ALIGN_CENTER, 4, true)); table.addCell(createCell("个人税收居民身份", tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); Phrase phrase = new Phrase(); PdfPCell wtrgrssjmxxCell1 = new PdfPCell(); wtrgrssjmxxCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); wtrgrssjmxxCell1.setHorizontalAlignment(Element.ALIGN_LEFT); phrase.add(new Chunk("□ 1.中国税收居民 □ 2.非中国税收居民 ■ 3.既是中国税收居民又是其他国家(地区)税收居民\n", minTextFont).setLineHeight(12f)); phrase.add(new Chunk("★ 如以上选项中填选第2项或第3项,请填写下列信息:\n", textFont).setLineHeight(12f)); phrase.add(new Chunk(" 税收居民国(地区):", textFont).setLineHeight(12f)); phrase.add(new Chunk(" HK00001", textFont).setLineHeight(12f).setUnderline(0.5f, -1f)); phrase.add(new Chunk(" 纳税人识别号(如有):", textFont).setLineHeight(12f)); phrase.add(new Chunk("289000001", textFont).setLineHeight(12f).setUnderline(0.5f, -1f)); //设置下划线,并设置下划线的粗细 wtrgrssjmxxCell1.setPhrase(phrase); wtrgrssjmxxCell1.setPaddingLeft(20f); wtrgrssjmxxCell1.setColspan(10); wtrgrssjmxxCell1.setPaddingTop(3.0f); wtrgrssjmxxCell1.setPaddingBottom(6.0f); table.addCell(wtrgrssjmxxCell1); PdfPCell cclyCell = createCell("保险清单列表", tableLineHeadFont, Element.ALIGN_CENTER, 12, true); cclyCell.setBackgroundColor(new BaseColor(205, 133, 63)); //设置单元格背景 table.addCell(cclyCell); for (int i = 0; i < 2; i++) { table.addCell(createCell("保险清单" + (i + 1), tableColumHeadFont, Element.ALIGN_CENTER, 2, true)); Phrase insurancePhrase1 = new Phrase(); PdfPCell insuranceCell1 = new PdfPCell(); insuranceCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); //上下居中 insuranceCell1.setHorizontalAlignment(Element.ALIGN_LEFT); //水平左对齐 insurancePhrase1.add(new Chunk("1.保险产品名称:灵通万事家天下寿险" + i + "\n", textFont).setLineHeight(10f)); //setLineHeight 设置行高 insurancePhrase1.add(new Chunk("3.保险单号:L000000002392997" + i + "\n", textFont).setLineHeight(10f)); insurancePhrase1.add(new Chunk("5.保险险种:终身寿险" + "\n", textFont).setLineHeight(10f)); insurancePhrase1.add(new Chunk("7.基本保额:250000" + i + "\n", textFont).setLineHeight(10f)); insurancePhrase1.add(new Chunk("9.备注(其他情况说明):无", textFont).setLineHeight(10f)); insuranceCell1.setPhrase(insurancePhrase1); insuranceCell1.setPaddingLeft(10f);//设置左侧空白填充的宽度 insuranceCell1.setColspan(5); //合并单元格 insuranceCell1.setPaddingTop(1.0f); //距离上边框距离 insuranceCell1.setPaddingBottom(4.0f); //距离下边框距离 insuranceCell1.disableBorderSide(8);//隐藏右边框 1-上, 2-下, 4-左, 8-右 table.addCell(insuranceCell1); Phrase insurancePhrase2 = new Phrase(); PdfPCell insuranceCell2 = new PdfPCell(); insuranceCell2.setVerticalAlignment(Element.ALIGN_MIDDLE); //上下居中 insuranceCell2.setHorizontalAlignment(Element.ALIGN_LEFT); //水平左对齐 insurancePhrase2.add(new Chunk("2.保险公司:灵通万事" + i + "\n", textFont).setLineHeight(10f)); insurancePhrase2.add(new Chunk("4.保单生效日:2020/12/0" + i + "\n", textFont).setLineHeight(10f)); insurancePhrase2.add(new Chunk("6.应交总保费:1290500" + i + "\n", textFont).setLineHeight(10f)); insurancePhrase2.add(new Chunk("8.受益人变更情况:生存受益人变更为保险公司;身故受益人变更为保险公司\n", textFont).setLineHeight(10f)); insurancePhrase2.add(new Chunk(" \n", textFont).setLineHeight(10f)); insuranceCell2.setPhrase(insurancePhrase2); insuranceCell2.setColspan(5); insuranceCell2.setPaddingTop(1.0f); insuranceCell2.setPaddingBottom(4.0f); insuranceCell2.disableBorderSide(4);//隐藏左边框: 1-上, 2-下, 4-左, 8-右 table.addCell(insuranceCell2); } PdfPCell syrmxCell = createCell("受益人情况", tableLineHeadFont, Element.ALIGN_CENTER, 12, true); syrmxCell.setBackgroundColor(new BaseColor(205, 133, 63)); table.addCell(syrmxCell); for (int i = 0; i < 1; i++) { table.addCell(createCell("受益人" + (i + 1), tableColumHeadFont, Element.ALIGN_CENTER, 1, true)); Phrase syrPhrase1 = new Phrase(); PdfPCell syrCell1 = new PdfPCell(); syrCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); syrCell1.setHorizontalAlignment(Element.ALIGN_LEFT); syrPhrase1.add(new Chunk("姓名:王小" + i + "\n", textFont).setLineHeight(10f)); syrPhrase1.add(new Chunk("与委托人关系:儿子\n", textFont).setLineHeight(10f)); syrPhrase1.add(new Chunk("婚姻状况:未婚\n", textFont).setLineHeight(10f)); syrPhrase1.add(new Chunk("联系电话:1887878000" + i + "\n", textFont).setLineHeight(10f)); syrPhrase1.add(new Chunk("电子邮箱:8888888@168.com\n", textFont).setLineHeight(10f)); syrPhrase1.add(new Chunk("邮寄地址:北京市朝阳区光明路128号5栋102\n", textFont).setLineHeight(10f)); syrPhrase1.add(new Chunk("终止分配比例:100%", textFont).setLineHeight(10f)); syrCell1.setPhrase(syrPhrase1); syrCell1.setPaddingLeft(10f); syrCell1.setColspan(5); syrCell1.setPaddingTop(1.0f); syrCell1.setPaddingBottom(4.0f); table.addCell(syrCell1); table.addCell(createCell("个人税收居民身份", tableColumHeadFont, Element.ALIGN_CENTER, 1, true)); Phrase syrgrssjmxxPhrase = new Phrase(); PdfPCell syrgrssjmxxCell1 = new PdfPCell(); syrgrssjmxxCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); syrgrssjmxxCell1.setHorizontalAlignment(Element.ALIGN_LEFT); syrgrssjmxxPhrase.add(new Chunk("■ 1.中国税收居民 □ 2.非中国税收居民 □ 3.既是中国又是其他国家(地区)税收居民\n", minTextFont).setLineHeight(15f)); syrgrssjmxxPhrase.add(new Chunk("★ 如以上选项中填选第2项或第3项,请填写下列信息:\n", textFont).setLineHeight(15f)); syrgrssjmxxPhrase.add(new Chunk(" 税收居民国(地区):▁▁▁▁ 纳税人识别号(如有):▁▁▁▁", textFont).setLineHeight(15f)); syrgrssjmxxCell1.setPhrase(syrgrssjmxxPhrase); syrgrssjmxxCell1.setPaddingLeft(6f); syrgrssjmxxCell1.setColspan(5); syrgrssjmxxCell1.setPaddingTop(3.0f); syrgrssjmxxCell1.setPaddingBottom(6.0f); table.addCell(syrgrssjmxxCell1); } document.add(table); document.add(new Paragraph("\n")); String paragraph5 = "客户(签字):▁▁▁▁▁▁▁▁"; Paragraph elements5 = new Paragraph(paragraph5, normalTextFont); elements5.setAlignment(Element.ALIGN_RIGHT); document.add(elements5); // 5.关闭文档 document.close(); } public static PdfPTable createTable(int colNumber) { int maxWidth = 500; PdfPTable table = new PdfPTable(colNumber); try { table.setTotalWidth(maxWidth); table.setLockedWidth(true); table.setHorizontalAlignment(Element.ALIGN_CENTER); table.setWidths(new int[]{50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50}); table.getDefaultCell().setBorder(1); } catch (Exception e) { e.printStackTrace(); } return table; } public static PdfPCell createCell(String value, Font font, int align, int colspan, boolean boderFlag) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(align); cell.setColspan(colspan); cell.setPhrase(new Phrase(value, font)); cell.setPadding(3.0f); if (!boderFlag) { cell.setBorder(0); cell.setPaddingTop(15.0f); cell.setPaddingBottom(8.0f); } return cell; } public static void main(String[] args) { try { writeExampaperPdf(); } catch (Exception e) { e.printStackTrace(); } } }
3. 写在最后的小心得
网上得来的代码,尤其是涉及流资源读取与关闭的,一定要仔细重点的经过反复测试验证之后,再借鉴使用。一定不要拿来主义,直接照搬。因为很多时候看似是捷径的方法,其实质很可能是拖你后腿的大坑。