Itext Pdf 生成、相关API
需求
- 需求
java
代码生成PDF
效果如下:后端生成 Pdf
文件,内容包含基本信息表格,图片、pdf
需要有页眉,pdf
每页含有页码,pdf
含有多页。 - 上图看看最后生成的效果如下:

功能实现
引入依赖
<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version>
</dependency>
<dependency><groupId>org.xhtmlrenderer</groupId><artifactId>core-renderer</artifactId><version>R8</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>layout</artifactId><version>7.2.3</version>
</dependency>
注意点
表格双边线的实现
- 双边线的实现思路:使用多层单元格嵌套的效果显示所有单元格的边框
页眉和页码的实现
- 继承
PdfPageEventHelper
重写对应的方法,在响应的方法中完成相关逻辑。
代码
public class ItextPdfUtils {private static final Logger logger = LoggerFactory.getLogger(ItextPdfUtils.class);public static final int TWENTY = 20;public static final int Thirty = 30;public static final int TWELVE = 12;public static BaseFont baseFontChinese = null;public static Font font = null;public static Font blueFont = null;public static Font smallThreeFont = null;public static Font fiveFont = null;public static Font smallFiveFont = null;public static Font smallSixFont = null;public static Font greenFont = null;public static Font messFont = null;public static Font titleFont = null;static {try {baseFontChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);font = new Font(baseFontChinese);font.setSize(10);blueFont = new Font(baseFontChinese);blueFont.setColor(BaseColor.BLUE);blueFont.setSize(5);smallThreeFont = new Font(baseFontChinese, TWENTY);smallThreeFont.setColor(BaseColor.BLACK);fiveFont = new Font(baseFontChinese);fiveFont.setColor(BaseColor.BLACK);fiveFont.setSize(10.5f);smallFiveFont = new Font(baseFontChinese);smallFiveFont.setColor(BaseColor.BLACK);smallFiveFont.setSize(9);smallSixFont = new Font(baseFontChinese);smallSixFont.setColor(BaseColor.BLACK);smallSixFont.setSize(6.5f);greenFont = new Font(baseFontChinese, TWELVE, Font.BOLD);greenFont.setColor(BaseColor.BLACK);messFont = new Font(baseFontChinese, 12);messFont.setColor(BaseColor.BLACK);titleFont = new Font(baseFontChinese, 14, Font.BOLD);titleFont.setColor(BaseColor.BLACK);} catch (Exception e) {logger.error("Error Occur:{0}", e);}}public static void setFooter(PdfWriter writer, String yeMei, int fontSize, Rectangle pageSize) {ItextPdfHeaderFooter headerFooter = new ItextPdfHeaderFooter(yeMei, pageSize);writer.setPageEvent(headerFooter);}public static PdfPCell getCell(String title, Font font, int miniMumHeight, int alignMiddle) {PdfPCell pdfPCell;pdfPCell = new PdfPCell(new Phrase(title, font));pdfPCell.setMinimumHeight(miniMumHeight);pdfPCell.setVerticalAlignment(alignMiddle);return pdfPCell;}public static PdfPCell getCell(String title, Font font, int miniMumHeight) {PdfPCell pdfPCell;pdfPCell = new PdfPCell(new Phrase(title, font));pdfPCell.setMinimumHeight(miniMumHeight);return pdfPCell;}public static PdfPCell getCell(String title, Font font, int miniMumHeight, boolean useAscender, int horizontalAlignment, int verticalAlignment) {PdfPCell pdfPCell;pdfPCell = new PdfPCell(new Phrase(title, font));pdfPCell.setUseAscender(useAscender);pdfPCell.setMinimumHeight(miniMumHeight);pdfPCell.setVerticalAlignment(verticalAlignment);pdfPCell.setHorizontalAlignment(horizontalAlignment);return pdfPCell;}public static PdfPCell getCell(String title, Font font, int miniMumHeight, boolean useAscender, int horizontalAlignment, int verticalAlignment, int colSpan) {PdfPCell pdfPCell;pdfPCell = new PdfPCell(new Phrase(title, font));pdfPCell.setUseAscender(useAscender);pdfPCell.setMinimumHeight(miniMumHeight);pdfPCell.setVerticalAlignment(verticalAlignment);pdfPCell.setHorizontalAlignment(horizontalAlignment);pdfPCell.setColspan(colSpan);return pdfPCell;}public static PdfPCell getCell(String title, Font font, Integer miniMumHeight, Boolean useAscender, Integer horizontalAlignment, Integer verticalAlignment, Integer colSpan, Integer rowSpan, Integer border, Integer borderWidthTop, Integer borderWidthLeft, Integer borderWidthRight) {Phrase phrase = new Phrase(title, font);PdfPCell pdfPCell = new PdfPCell(phrase);if (Objects.nonNull(miniMumHeight)) {pdfPCell.setMinimumHeight(miniMumHeight);}if (Objects.nonNull(useAscender)) {pdfPCell.setUseAscender(useAscender);}if (Objects.nonNull(horizontalAlignment)) {pdfPCell.setHorizontalAlignment(horizontalAlignment);}if (Objects.nonNull(verticalAlignment)) {pdfPCell.setVerticalAlignment(verticalAlignment);}if (Objects.nonNull(colSpan)) {pdfPCell.setColspan(colSpan);}if (Objects.nonNull(rowSpan)) {pdfPCell.setRowspan(rowSpan);}if (Objects.nonNull(border)) {pdfPCell.setBorder(border);}if (Objects.nonNull(borderWidthTop)) {pdfPCell.setBorderWidthTop(borderWidthTop);}if (Objects.nonNull(borderWidthLeft)) {pdfPCell.setBorderWidthLeft(borderWidthLeft);}if (Objects.nonNull(borderWidthRight)) {pdfPCell.setBorderWidthRight(borderWidthRight);}return pdfPCell;}
}
public class ItextPdfTest {private static final Logger logger = LoggerFactory.getLogger(ItextPdfUtils.class);private static final float[] columnWidths5 = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f};private String createItextPdf() {Date date = new Date();String startTime = new SimpleDateFormat("yyyyMMddHHmmss").format(date);String fileName = "demo";String oldPath = fileName + ".pdf";Document document = new Document();PdfWriter writer = null;try {document.setPageSize(PageSize.A4);writer = PdfWriter.getInstance(document, new FileOutputStream(oldPath));ItextPdfUtils.setFooter(writer, "测试页眉", 12, PageSize.LEGAL);document.open();PdfPTable table = new PdfPTable(4);table.setWidthPercentage(100);table.setSpacingBefore(100f);table.setSpacingAfter(10f);float[] columnWidths = {0.8f, 0.8f, 0.5f, 0.5f};table.setWidths(columnWidths);PdfPCell cell;table.addCell(ItextPdfUtils.getCell("", null, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE, 0, null, 0, 0, 0, 0));table.addCell(ItextPdfUtils.getCell("ItextPdf 打印测试", smallThreeFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE, 0, null, 0, 0, 0, 0));table.addCell(ItextPdfUtils.getCell("", fiveFont, TWENTY, true, Cell.ALIGN_RIGHT, Cell.ALIGN_BOTTOM, 2, null, 0, null, null, null));table.addCell(ItextPdfUtils.getCell("记录人:张三", fiveFont, TWENTY, true, Cell.ALIGN_LEFT, Cell.ALIGN_MIDDLE, 0, null, 0, null, null, null));table.addCell(ItextPdfUtils.getCell("打印日期:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date()), fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE, 0, null, 0, null, null, null));table.addCell(ItextPdfUtils.getCell("编号:AAAAAAAAAAAAA号", fiveFont, TWENTY, true, Cell.ALIGN_RIGHT, Cell.ALIGN_MIDDLE, 2, null, 0, null, null, null));PdfPTable personInfoTable = new PdfPTable(5);float[] headerTableColumnWidth = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f};personInfoTable.setWidthPercentage(100);personInfoTable.setWidths(headerTableColumnWidth);personInfoTable.addCell(ItextPdfUtils.getCell("编号", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("姓名", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));Image img = Image.getInstance("demo.jpg");PdfPCell imageCell = new PdfPCell(new Phrase("照片", fiveFont));imageCell.setVerticalAlignment(Cell.ALIGN_MIDDLE);imageCell.setHorizontalAlignment(Cell.ALIGN_CENTER);imageCell.setRowspan(4);imageCell.setImage(img);personInfoTable.addCell(imageCell);personInfoTable.addCell(ItextPdfUtils.getCell("性别", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("籍贯", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("民族", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("出生日期", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("政治面貌", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("学历", fiveFont, Thirty, Cell.ALIGN_MIDDLE));personInfoTable.addCell(ItextPdfUtils.getCell("", fiveFont, Thirty, Cell.ALIGN_MIDDLE));PdfPCell personInfoCell = new PdfPCell(new Phrase(""));personInfoCell.setColspan(4);personInfoCell.addElement(personInfoTable);personInfoCell.setFixedHeight(120);table.addCell(personInfoCell);PdfPTable remarkTable = new PdfPTable(2);remarkTable.setWidthPercentage(100);float[] remarkColumnWidth = {0.1f, 0.9f};remarkTable.setWidths(remarkColumnWidth);PdfPCell remarkCell;remarkCell = new PdfPCell(new Phrase("情况说明(个人家庭情况做简单说明):", fiveFont));remarkCell.setHorizontalAlignment(Cell.ALIGN_CENTER);remarkCell.setVerticalAlignment(Cell.ALIGN_MIDDLE);remarkTable.addCell(remarkCell);remarkCell = new PdfPCell(new Phrase("", fiveFont));remarkCell.setMinimumHeight(200);remarkTable.addCell(remarkCell);PdfPCell remark = new PdfPCell(new Phrase(""));remark.setMinimumHeight(200);remark.setColspan(4);remark.addElement(remarkTable);table.addCell(remark);PdfPTable mainLeftTable = new PdfPTable(2);mainLeftTable.setWidthPercentage(100);float[] columnWidths0 = {0.8f, 0.8f};mainLeftTable.setWidths(columnWidths0);mainLeftTable.addCell(ItextPdfUtils.getCell("家庭成员", fiveFont, 28, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("身份证号", fiveFont, 28, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("李四", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("632123111100000000", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("王五", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("632123111100000000", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("王五", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));mainLeftTable.addCell(ItextPdfUtils.getCell("632123111100000000", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));cell = new PdfPCell(new Phrase("", fiveFont));cell.setMinimumHeight(80);cell.setUseAscender(true);cell.setHorizontalAlignment(Cell.ALIGN_CENTER);cell.setVerticalAlignment(Cell.ALIGN_MIDDLE);cell.setRowspan(5);cell.setColspan(2);cell.setBorderWidthRight(0);cell.setBorderWidthBottom(0);cell.setPaddingRight(-0.2f);cell.addElement(mainLeftTable);table.addCell(cell);PdfPTable rightOne = new PdfPTable(3);rightOne.setWidthPercentage(100);float[] columnWidths1 = {0.06f, 0.06f, 0.06f};rightOne.setWidths(columnWidths1);rightOne.addCell(ItextPdfUtils.getCell("正常收入", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP, 3));rightOne.addCell(ItextPdfUtils.getCell("千", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));rightOne.addCell(ItextPdfUtils.getCell("百", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));rightOne.addCell(ItextPdfUtils.getCell("十", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));for (int i = 0; i < 9; i++) {rightOne.addCell(ItextPdfUtils.getCell("", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));}cell = new PdfPCell(new Phrase("", fiveFont));cell.setMinimumHeight(68);cell.setUseAscender(true);cell.setHorizontalAlignment(Cell.ALIGN_CENTER);cell.setVerticalAlignment(Cell.ALIGN_TOP);cell.setBorderWidthRight(0);cell.setBorderWidthLeft(0);cell.setBorderWidthBottom(0);cell.setPaddingLeft(2.5f);cell.setPaddingBottom(-3);cell.setRowspan(5);cell.addElement(rightOne);table.addCell(cell);PdfPTable rightTwo = new PdfPTable(3);rightTwo.setWidthPercentage(102);float[] columnWidths2 = {0.06f, 0.06f, 0.06f};rightTwo.setWidths(columnWidths2);PdfPCell cell2;rightTwo.addCell(ItextPdfUtils.getCell("补助", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP, 3));rightTwo.addCell(ItextPdfUtils.getCell("千", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));rightTwo.addCell(ItextPdfUtils.getCell("百", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));rightTwo.addCell(ItextPdfUtils.getCell("十", fiveFont, 14, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));for (int i = 0; i < 9; i++) {rightTwo.addCell(ItextPdfUtils.getCell("十", fiveFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_TOP));}cell = new PdfPCell(new Phrase("", fiveFont));cell.setMinimumHeight(80);cell.setUseAscender(true);cell.setHorizontalAlignment(Cell.ALIGN_CENTER);cell.setVerticalAlignment(Cell.ALIGN_TOP);cell.setBorderWidthLeft(0);cell.setBorderWidthBottom(0);cell.setPaddingRight(3);cell.setPaddingBottom(-3);cell.setRowspan(5);cell.addElement(rightTwo);table.addCell(cell);PdfPTable table4 = new PdfPTable(1);table4.setWidthPercentage(100);float[] columnWidths4 = {1.6f};table4.setWidths(columnWidths4);table4.addCell(ItextPdfUtils.getCell("金额合计:捌佰陆拾壹元陆角玖分", fiveFont, TWENTY, true, Cell.ALIGN_LEFT, Cell.ALIGN_MIDDLE));cell = new PdfPCell(new Phrase("", fiveFont));cell.setBorderWidthRight(0);cell.setBorderWidthTop(0);cell.setPaddingRight(-0.2f);cell.setPaddingTop(-0.5f);cell.addElement(table4);cell.setColspan(2);table.addCell(cell);PdfPTable table3 = new PdfPTable(3);table3.setWidthPercentage(102);float[] columnWidths3 = {0.06f, 0.06f, 0.06f,};table3.setWidths(columnWidths3);for (int i = 0; i < 3; i++) {table3.addCell(ItextPdfUtils.getCell("", smallSixFont, TWENTY, true, Cell.ALIGN_CENTER, Cell.ALIGN_MIDDLE));}cell = new PdfPCell(new Phrase("", smallFiveFont));cell.setBorderWidthRight(0);cell.setBorderWidthLeft(0);cell.setBorderWidthTop(0);cell.setPaddingLeft(2.5f);cell.setPaddingTop(-0.5f);cell.addElement(table3);table.addCell(cell);cell = new PdfPCell(new Phrase("", smallFiveFont));cell.setBorderWidthLeft(0);cell.setBorderWidthTop(0);cell.setPaddingTop(-0.5f);cell.setPaddingRight(3);cell.addElement(table3);table.addCell(cell);PdfPTable remarkTableOne = new PdfPTable(2);remarkTableOne.setWidthPercentage(100);remarkTableOne.setWidths(remarkColumnWidth);remarkTableOne.addCell(ItextPdfUtils.getCell("领导意见", fiveFont, 200, true, Cell.ALIGN_CENTER, Cell.ALIGN_CENTER));remarkTableOne.addCell(ItextPdfUtils.getCell("", fiveFont, 200, true, Cell.ALIGN_CENTER, Cell.ALIGN_CENTER));remarkTableOne.addCell(ItextPdfUtils.getCell("", fiveFont, 200));PdfPCell remarkOne = new PdfPCell(new Phrase(""));remarkOne.setMinimumHeight(200);remarkOne.setColspan(4);remarkOne.addElement(remarkTableOne);table.addCell(remarkOne);document.add(table);Paragraph paragraphTail = new Paragraph("制单人:李某某", fiveFont);paragraphTail.setLeading(10);paragraphTail.setAlignment(Element.ALIGN_LEFT);document.add(paragraphTail);createTwoPage(document);} catch (Exception e) {logger.error("Error Occur:", e);} finally {document.close();if (writer != null) {writer.close();}}return oldPath;}private void createTwoPage(Document document) throws DocumentException {document.newPage();document.setMargins(4, 4, 4, 50);document.addAuthor("张三");document.addHeader("测试", "测试打印页头部");PdfPTable table = new PdfPTable(5);table.setWidths(columnWidths5);table.setWidthPercentage(100);PdfPCell cell;for (int i = 0; i < 500; i++) {if (i <= 4) {cell = new PdfPCell(new Phrase("测试列" + i, fiveFont));cell.setMinimumHeight(20);} else {cell = new PdfPCell(new Phrase(String.valueOf(i), fiveFont));cell.setMinimumHeight(15);}table.addCell(cell);}document.add(table);}@Testpublic void test1() {createItextPdf();}
}
- 页眉和页码处理:
ItextPdfHeaderFooter.java
public class ItextPdfHeaderFooter extends PdfPageEventHelper {public String header;public PdfTemplate total;public Rectangle pageSize;public ItextPdfHeaderFooter(String yeMei, Rectangle pageSize) {this.header = yeMei;this.pageSize = pageSize;}@Overridepublic void onOpenDocument(PdfWriter writer, Document document) {total = writer.getDirectContent().createTemplate(50, 50);}@Overridepublic void onEndPage(PdfWriter writer, Document document) {ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, ItextPdfUtils.font), document.left(250), document.top() + 20, 0);int pageS = writer.getPageNumber();String foot1 = "第 " + pageS + "页 / 共";Phrase footer = new Phrase(foot1, ItextPdfUtils.font);float len = ItextPdfUtils.baseFontChinese.getWidthPoint(foot1, ItextPdfUtils.font.getSize());PdfContentByte cb = writer.getDirectContent();ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, (document.rightMargin() + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 20F, document.bottom() - 20, 0);cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin() - document.left()) / 2.0F + 20F, document.bottom() - 20);}@Overridepublic void onCloseDocument(PdfWriter writer, Document document) {total.beginText();total.setFontAndSize(ItextPdfUtils.baseFontChinese, ItextPdfUtils.font.getSize());String foot = (writer.getPageNumber()) + "页";total.showText(foot);total.endText();total.closePath();}
}
完整代码
- 见地址:https://gitee.com/Marlon_Brando/JavaTest/tree/develop/src/main/java/otherapi