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>
注意点
表格双边线的实现
- 双边线的实现思路:使用多层单元格嵌套的效果显示所有单元格的边框
页眉和页码的实现
- 继承
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);
}
@Test
public 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;
}
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
total = writer.getDirectContent().createTemplate(50, 50);
}
@Override
public 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);
}
@Override
public 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();
}
}
完整代码
|