- itext官网https://itextpdf.com/
- 官方api地址https://api.itextpdf.com/iText7/java/7.2.4/
下面是来自官网首页的介绍:
Discover iText PDF
Our PDF toolkit offers you one of the best-documented and most versatile PDF engines in the world (written in Java and .NET), which allows you to not only integrate PDF functionalities into your workflow, but also in your applications, processes or products.
显而易见,itext是一款基于 Java and .NET编程语言pdf生成工具,用户可以使用api根据需要生成自己想要的pdf格式同时支持文字内容的拼接。
下面是小编在工作中实际遇到过的生产问题。
首先引入相关依赖
<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>
根据用户提供的样版,生成带有数据填写功能和审批功能的pdf文本。
由于基本信息,生产数据以及审批信息是分段获取到的(换句话说不能一次性拿到所有数据,数据的产生是根据现场的变化和实时的生产活动生成的),所以该pdf文件必须具备实时性,所以通过软件动态生成则是比较理想的实现方式。
itext实现效果如下:
基本数据和生产数据可以动态插入表中,
审批意见,签字,时间戳也可以动态实时拼接。
接下来是具体的实现过程:
基本信息的生成以及文本的编写。
创建文件
Document document = new Document();
//建立一个书写器
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(“E:/重要设施安全检查签证记录.pdf”));
document.setPageSize(PageSize.A4);
BaseFont baseFont = FontFactory.getFont(“STSong-Light”, “UniGB-UCS2-H”, BaseFont.NOT_EMBEDDED,
8f, Font.NORMAL, BaseColor.BLACK).getBaseFont();
Font FontChinese = new Font(baseFont);
//打开文件
document.open();
Font font = new Font(baseFont);
font.setStyle(1);
Paragraph title = new Paragraph(“重要设施安全检查签证记录”,font);
title.setAlignment(Element.ALIGN_CENTER);
document.add(title);
整体的格式布置采用的是itext里的PdfPTable数据格式,数据的插入整体过程就是PdfPTable获取行 List listRow = table.getRows();然后行设置列,PdfPCell cells1[]= new PdfPCell[4](cell的长度就是一行可以包含的cell个数), PdfPRow row1 = new PdfPRow(cells1);listRow.add(row1)。listRow是table对象获取到的实例,所以需要几行就往listRow加入几行row就可以了。
//cells4[0].addElement(paragraph1);
//cells4[0].addElement(paragraph2);
Rectangle rectangle = new Rectangle(50,50,550,350-10*6);//ury减小向下 urx减小向左
writer.getDirectContent().rectangle(rectangle);
ColumnText ct = new ColumnText(writer.getDirectContent());
ct.addElement(paragraph1);
ct.addElement(paragraph2);
ct.setSimpleColumn(rectangle);
ct.go();
这一段代码与注释的代码可以实现同样的效果,但是注释代码的灵活性有些不足之处。对应的实现部位如下图所示:
ury大小代表Rectangle 文本块的y坐标,如果数据动态增加,文本块必然会错位,这时,ury的大小就需要根据数据文本块的高度和数量动态调整,据小编尝试100f的高度,Rectangle 文本块50x50,10行数据在原来的基础上减去10*6便可(具体数值是根据实际数据文本块的高度和数量决定的,大家可以在实践中体会)。具体的样式和格式字段的设置大家可以根据官网提供的api文本学习,在这里就不具体展开了。
下面附上可执行代码(与大家共勉):
public class ITextDemo {
@Test
public void test9() throws FileNotFoundException, DocumentException {
//创建文件
Document document = new Document();
//建立一个书写器
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("E:/重要设施安全检查签证记录.pdf"));
document.setPageSize(PageSize.A4);
BaseFont baseFont = FontFactory.getFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED,
8f, Font.NORMAL, BaseColor.BLACK).getBaseFont();
Font FontChinese = new Font(baseFont);
//打开文件
document.open();
Font font = new Font(baseFont);
font.setStyle(1);
Paragraph title = new Paragraph("重要设施安全检查签证记录",font);
title.setAlignment(Element.ALIGN_CENTER);
document.add(title);
Paragraph tableId = new Paragraph("表号:",FontChinese);
tableId.setAlignment(Element.ALIGN_RIGHT);
tableId.setIndentationRight(60f);
Paragraph names = new Paragraph();
Chunk project_name = new Chunk("项目名称:",FontChinese);
Chunk code = new Chunk("编号:",FontChinese);
names.add(project_name);
String space = "";
for (int i =0 ;i <110;i++){
space += " ";
}
names.add(new Chunk(space));
names.add(code);
names.setKeepTogether(false);
names.setSpacingAfter(0);
document.add(tableId);
document.add(names);
PdfPTable table = new PdfPTable(4);
table.setWidthPercentage(100); // 宽度100%填充
table.setSpacingBefore(10f); // 前间距
table.setSpacingAfter(10f); // 后间距
float[] columnWidths = { 1f, 3f, 1f, 2f };
table.setWidths(columnWidths);
table.setSplitLate(false);
table.setSplitRows(true);
List<PdfPRow> listRow = table.getRows();
PdfPCell cells1[]= new PdfPCell[4];
PdfPRow row1 = new PdfPRow(cells1);
//单元格
cells1[0] = new PdfPCell(new Phrase("重要设施名称",FontChinese));//单元格内容
cells1[0].setFixedHeight(30f);
cells1[0].setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cells1[0].setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
cells1[1] = new PdfPCell();
cells1[2] = new PdfPCell(new Phrase("计划使用时间",FontChinese));//单元格内容
cells1[2].setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cells1[2].setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
Paragraph p = new Paragraph();
Chunk c1 = new Chunk("年",FontChinese);
Chunk c2 = new Chunk("月",FontChinese);
Chunk c3 = new Chunk("日",FontChinese);
String spaceYMD = "";
for (int i =0 ;i <5;i++){
spaceYMD += " ";
}
p.add(spaceYMD);
p.add(c1);
p.add(spaceYMD);
p.add(c2);
p.add(spaceYMD);
p.add(c3);
p.setKeepTogether(false);
cells1[3] = new PdfPCell(p);//单元格内容
cells1[3].setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cells1[3].setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
listRow.add(row1);
PdfPCell cells2[]= new PdfPCell[4];
PdfPRow row2 = new PdfPRow(cells2);
//单元格
cells2[0] = new PdfPCell(new Phrase("现场负责人",FontChinese));//单元格内容
cells2[0].setFixedHeight(30f);
cells2[0].setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cells2[0].setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
cells2[1] = new PdfPCell();
cells2[2] = new PdfPCell(new Phrase("计划停用时间",FontChinese));//单元格内容
cells2[2].setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cells2[2].setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
Paragraph p2 = new Paragraph();
Chunk c21 = new Chunk("年",FontChinese);
Chunk c22 = new Chunk("月",FontChinese);
Chunk c23 = new Chunk("日",FontChinese);
p2.add(spaceYMD);
p2.add(c21);
p2.add(spaceYMD);
p2.add(c22);
p2.add(spaceYMD);
p2.add(c23);
p2.setKeepTogether(false);
cells2[3] = new PdfPCell(p2);//单元格内容
cells2[3].setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cells2[3].setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直居中
listRow.add(row2);
PdfPTable table2 = new PdfPTable(3);
table2.setWidthPercentage(100); // 宽度100%填充
float[] table2ColumnWidths = { 2f, 4f, 2f };
table2.setWidths(table2ColumnWidths);
table2.setSplitLate(false);
table2.setSplitRows(true);
ArrayList<PdfPRow> table2Rows = table2.getRows();
PdfPCell headerCell[] = new PdfPCell[3];
headerCell[0] = new PdfPCell(new Phrase("检查内容",FontChinese));
headerCell[1] = new PdfPCell(new Phrase("检查标准及要求",FontChinese));
headerCell[2] = new PdfPCell(new Phrase("检查结果",FontChinese));
PdfPRow rows3 = new PdfPRow(headerCell);
table2Rows.add(rows3);
int lineNum = 60;
for (int i = 0;i< lineNum ;i++){
PdfPCell cell = new PdfPCell(new Phrase("1",FontChinese));
table2.addCell(cell);
}
PdfPCell cells3= new PdfPCell();
cells3.setColspan(4);
cells3.addElement(table2);
cells3.setPadding(0f);
cells3.setBorderWidth(0f);
table.addCell(cells3);
PdfPCell cells4[]= new PdfPCell[4];
PdfPRow row4 = new PdfPRow(cells4);
//单元格
Paragraph titleCell = new Paragraph(new Chunk("施工项目部检查结论:",FontChinese));
titleCell.setAlignment(Element.ALIGN_LEFT);
cells4[0] = new PdfPCell(titleCell);//单元格内容
cells4[0].addElement(titleCell);
Paragraph paragraph1 = new Paragraph(new Chunk("施工项目经理", FontChinese));
Paragraph paragraph2 = new Paragraph(new Chunk("年 月 日", FontChinese));
paragraph1.setAlignment(Element.ALIGN_RIGHT);
paragraph1.setIndentationRight(50f);
paragraph2.setAlignment(Element.ALIGN_RIGHT);
paragraph2.setIndentationRight(50f);
//cells4[0].addElement(paragraph1);
//cells4[0].addElement(paragraph2);
cells4[0].setColspan(4);
cells4[0].setFixedHeight(100f);//单元格固定高度
cells4[0].setHorizontalAlignment(Element.ALIGN_LEFT);//水平居中
cells4[0].setVerticalAlignment(Element.ALIGN_TOP);//垂直居中
Rectangle rectangle = new Rectangle(50,50,550,350-10*6);//ury减小向下 urx减小向左
writer.getDirectContent().rectangle(rectangle);
ColumnText ct = new ColumnText(writer.getDirectContent());
ct.addElement(paragraph1);
ct.addElement(paragraph2);
ct.setSimpleColumn(rectangle);
ct.go();
PdfPCell cells5[]= new PdfPCell[4];
PdfPRow row5 = new PdfPRow(cells5);
//单元格
Paragraph titleCell2 = new Paragraph(new Chunk("监理项目部核查结论:",FontChinese));
titleCell2.setAlignment(Element.ALIGN_LEFT);
cells5[0] = new PdfPCell(titleCell2);//单元格内容
cells5[0].addElement(titleCell2);
Paragraph paragraph3 = new Paragraph(new Chunk("专业监理工程师", FontChinese));
Paragraph paragraph4 = new Paragraph(new Chunk("年 月 日", FontChinese));
paragraph3.setAlignment(Element.ALIGN_RIGHT);
paragraph3.setIndentationRight(50f);
paragraph4.setAlignment(Element.ALIGN_RIGHT);
paragraph4.setIndentationRight(50f);
// cells5[0].addElement(paragraph3);
// cells5[0].addElement(paragraph4);
Rectangle rectangle2 = new Rectangle(50,50,550,250-10*6);//ury减小向下 urx减小向左
writer.getDirectContent().rectangle(rectangle2);
ColumnText ct2 = new ColumnText(writer.getDirectContent());
ct2.addElement(paragraph3);
ct2.addElement(paragraph4);
ct2.setSimpleColumn(rectangle2);
ct2.go();
cells5[0].setColspan(4);
cells5[0].setFixedHeight(100f);
cells5[0].setHorizontalAlignment(Element.ALIGN_LEFT);//水平居中-居左
cells5[0].setVerticalAlignment(Element.ALIGN_TOP);//垂直居中-顶部
listRow.add(row4);
listRow.add(row5);
document.add(table);
Paragraph foot = new Paragraph();
Chunk bz = new Chunk("注 " +
"重要设施包括大中型起重机械、整体提升脚手架或整体提升工作平台、模板自升式架设设施," +
"脚手架,施工用电、水、气等力能设施,交通运输道路和危险品库房等;每一处重要设施填写一" +
"张表。",FontChinese);
foot.setIndentationLeft(20f);
foot.add(bz);
document.add(foot);
document.close();
//关闭书写器
writer.close();
}
}