最近业务又新提了一个小需求,由于原来基于模板生成pdf文件的方式,无法灵活支持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 EffectNoticePdfTest { private static Font headfont;// 设置字体大小 private static Font keyNormalFont;// 设置字体大小 private static Font keyBoldFont;// 设置字体大小 private static Font theadfont;// 设置字体大小 private static Font textfont;// 设置字体大小 static { BaseFont bfChinese; try { bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); headfont = new Font(bfChinese, 16, Font.BOLD);// 设置字体大小 keyNormalFont = new Font(bfChinese, 10, Font.NORMAL);// 设置字体大小 keyBoldFont = new Font(bfChinese, 10, Font.BOLD);// 设置字体大小 theadfont = new Font(bfChinese, 9, Font.BOLD);// 设置字体大小 textfont = new Font(bfChinese, 8, Font.NORMAL);// 设置字体大小 } catch (Exception e) { e.printStackTrace(); } } public static void writeExampaperPdf() throws Exception { // 1.新建document对象 // 第一个参数是页面大小。接下来的参数分别是左、右、上和下页边距。 Document document = new Document(PageSize.A4, 50, 50, 120, 80); // 2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。 // 创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D://effect_notice_file2020.pdf")); //3.打开文档 document.open(); //4.设置背景图片 Image jpeg = Image.getInstance("backgroud.jpeg"); jpeg.setAlignment(Image.MIDDLE | Image.UNDERLYING); jpeg.setAbsolutePosition(0, 0); jpeg.scaleAbsolute(595, 842); document.add(jpeg); //5.将标题写进去 Paragraph pt = new Paragraph("合同生效通知书", headfont); pt.setAlignment(1);// 设置文字居中 0靠左 1,居中 2,靠右 document.add(pt); document.add(new Paragraph("\n"));// 添加段落分隔符 换行 Paragraph paragraph1 = new Paragraph(); paragraph1.add(new Chunk("致:尊敬的合伙人\n", keyBoldFont)); paragraph1.add(new Chunk(" 《", keyNormalFont)); paragraph1.add(new Chunk("益生华飞•第【64】号投资合作协议合同", keyNormalFont).setUnderline(0.7f, -1f)); paragraph1.add(new Chunk("》(以下简称“本合同”)已达到协议合同约定的生效条件,于", keyNormalFont)); paragraph1.add(new Chunk("2020", keyNormalFont).setUnderline(0.7f, -1f)); paragraph1.add(new Chunk("年", keyNormalFont)); paragraph1.add(new Chunk("10", keyNormalFont).setUnderline(0.7f, -1f)); paragraph1.add(new Chunk("月", keyNormalFont)); paragraph1.add(new Chunk("29", keyNormalFont).setUnderline(0.7f, -1f)); paragraph1.add(new Chunk("日生效。执行人已按照协议合同的约定管理数据和资产。\n", keyNormalFont)); paragraph1.add(new Chunk("一、成立信息\n", keyBoldFont)); paragraph1.add(new Chunk(" 1、管理期限:", keyNormalFont)); paragraph1.add(new Chunk("50", keyNormalFont).setUnderline(0.7f, -1f)); paragraph1.add(new Chunk("年\n", keyNormalFont)); paragraph1.add(new Chunk(" 2、本合同的交付的保险金请求权如下:", keyNormalFont)); paragraph1.setLeading(20f); document.add(paragraph1); document.add(new Paragraph("\n"));// 添加段落分隔符 换行 // PdfPTable table = createTable(8); table.addCell(createCell("序号", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("保险产品名称", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("保险公司", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("保险单号", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("保单生效日", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("保险险种", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("保险规模(元)", theadfont, Element.ALIGN_CENTER)); table.addCell(createCell("受益人变更情况", theadfont, Element.ALIGN_CENTER)); for (int i = 0; i < 3; i++) { table.addCell(createCell(i + 1 + "", textfont)); table.addCell(createCell("亚盛财富版终身寿险" + i, textfont)); table.addCell(createCell("亚盛财富"+ i, textfont)); table.addCell(createCell("Y000000002392997" + i, textfont)); table.addCell(createCell("2020/8/1" + i, textfont)); PdfPCell pCell = createCell("□年金险\n" + "■终身寿险\n", textfont, Element.ALIGN_LEFT); pCell.setMinimumHeight(50); //设置最小行高 pCell.setPadding(8f); table.addCell(pCell); Phrase phrase = new Phrase(); PdfPCell pCell1 = new PdfPCell(); pCell1.setVerticalAlignment(Element.ALIGN_MIDDLE); pCell1.setHorizontalAlignment(Element.ALIGN_CENTER); phrase.add(new Chunk("1.应交总保费:\n", textfont)); phrase.add(new Chunk("1290500\n", textfont).setUnderline(0.1f, -1f).setLineHeight(9f)); phrase.add(new Chunk("2.基本保额: \n", textfont).setLineHeight(9f)); phrase.add(new Chunk("2500006\n", textfont).setUnderline(0.1f, -1f).setLineHeight(9f)); pCell1.setPhrase(phrase); pCell1.setPaddingLeft(7f); table.addCell(pCell1); PdfPCell pCell2 = createCell("□生存受益人变更为管理公司\n" + "■身故受益人变更为管理公司\n", textfont, Element.ALIGN_LEFT); pCell2.setPadding(6f); table.addCell(pCell2); } document.add(table); document.add(new Paragraph("\n")); Paragraph paragraph3 = new Paragraph(); paragraph3.add(new Chunk(" 特此回函。\n", keyNormalFont).setWordSpacing(30f)); paragraph3.add(new Chunk("重要提示:执行人仅以合同约定为限向受益人支付利益,且执行人及相关服务机构不承诺对本协议的业绩表现或者" + "任何回报之支付做出任何保证。\n", keyBoldFont).setWordSpacing(30f)); paragraph3.add(new Chunk(" 执行人咨询电话:400-888-8888。\n", keyNormalFont)); paragraph3.add(new Chunk(" 感谢您对我司的一贯支持与信任。\n", keyNormalFont)); paragraph3.setLeading(20f); document.add(paragraph3); String paragraph5 = "益生华飞投资管理有限公司\n2020年10月20日"; Paragraph elements5 = new Paragraph(paragraph5, keyNormalFont); 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[]{15, 50, 50, 50, 28, 42, 45, 45}); table.getDefaultCell().setBorder(1); } catch (Exception e) { e.printStackTrace(); } return table; } public static PdfPCell createCell(String value, Font font, int align) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(align); Phrase phrase = new Phrase(); phrase.add(new Chunk(value, font).setLineHeight(9f)); cell.setPhrase(phrase); return cell; } public static PdfPCell createCell(String value, Font font) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(Element.ALIGN_CENTER); Phrase phrase = new Phrase(); phrase.add(new Chunk(value, font).setLineHeight(9f)); cell.setPhrase(phrase); return cell; } public static void main(String[] args) { try { writeExampaperPdf(); } catch (Exception e) { e.printStackTrace(); } } }
写在最后的小心得:网上得来的代码,尤其是涉及流资源读取与关闭的,一定要仔细重点的经过反复测试验证之后,再借鉴使用。一定不要拿来主义,直接照搬。因为很多时候看似是捷径的方法,其实质很可能是拖你后腿的大坑。