「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。
过完年了学校里有一个高新申报的项目会涉及到很多pdf相关的操作,用的技术栈时Itext7,经过两天的的学习简单做了一些总结。
依赖添加
首先是一些需要的依赖,通过gradle构建:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
//包含低层次常用的基础的函数------------------------------------------
implementation group: 'com.itextpdf', name: 'kernel', version: '7.2.0'
implementation group: 'com.itextpdf', name: 'io', version: '7.2.0'
//包含高层次的函数
implementation group: 'com.itextpdf', name: 'layout', version: '7.2.0'
//有关AcorForms操作需要的函数库
implementation group: 'com.itextpdf', name: 'forms', version: '7.2.0'
//有关PDF/A(电子文档标准)的相关操作
implementation group: 'com.itextpdf', name: 'pdfa', version: '7.2.0'
//----------------------以上为常用jar包---------------------------
//条形码相关
implementation group: 'com.itextpdf', name: 'barcodes', version: '7.2.0'
//电子签名
implementation group: 'com.itextpdf', name: 'sign', version: '7.2.0'
//字体相关,主要解决中文不显示的问题
testImplementation group: 'com.itextpdf', name: 'font-asian', version: '7.2.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
基本构建块
helloword
当然要从最简单的helloWord开始
@PostMapping("/test")
public String test() throws FileNotFoundException {
PdfWriter writer = new PdfWriter("/xxxxx/xxxx/test.pdf");//带路径的文件名
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
document.add(new Paragraph("Hello World!"));
document.close();
return "success";
}
具体流程如下:
- 创建
PdfWriter
实例,PdfWriter
是一个可以写PDF文件的对象,它不需要了解它要写的pdf的实际内容是什么,PdfWriter
不需要知道文档是什么,一旦文件结构完成,它就写不同的文件部分,不同的对象,构成一个有效的文档。PdfWriter
的初始化参数可以是文件名或者Stream或带路径的文件名。
PdfWriter
了解它需要写什么内容,因为它监听PdfDocument
的动态。PdfWriter
负责管理添加的内容,并把内容分布到不同的页面上,并跟踪有关页面内容的所有信息。PdfDocument
和PdfWriter
创建以后,我们把PdfDocument
传入Docment
,并对Document
对象操作,Document
就是我们的pdf对象- 创建
Paragraph
,包含"Hello World"
字符串,并把这个短语加入Document
独享中 - 关闭
Document
。PDF文档创建完成
效果图图下:
解决中文不显示问题
itext默认情况下是不显示中文的,我这里的做法是采用本地的字体库文件,版本为itext7.2.0,其余版本不知道是否适用。部署到服务器上的话可以看一下linux的字体库怎么调用。
//使用系统本地字体,可以解决生成的pdf中无法显示中文问题,本处字体为宋体
//在创建字体时直接使用即可解决中文问题
PdfFont sysFont = PdfFontFactory.createFont("C:/Windows/Fonts/simsun.ttc,1", PdfEncodings.IDENTITY_H);
//。。。。。。。。。。
document.add(new Paragraph("好 的!").setFont(sysFont));//通过setfont方法设置自定义的字体就可以正常显示了
写入list
public String list() throws FileNotFoundException {
PdfWriter writer = new PdfWriter(PATH + "\\list.pdf");
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
document.add(new Paragraph("iText list:").setFont(sysFont));
// 创建list,位于itextpdf.layout包下
List list = new List()
.setSymbolIndent(12)//列表项的缩进单元
.setListSymbol("\u2022")//列表符号,没有找到具体说明,有需求只能一个一个试了
.setFont(sysFont);
// 添加数据
list.add(new ListItem("English test1"))
.add(new ListItem("English test2"))
.add(new ListItem("中文测试1"))
.add(new ListItem("中文测试2"));
document.add(list);
document.close();
return "success";
}
效果图如下:
2.4-写入图片
@PostMapping("/image")
public String image() throws FileNotFoundException, MalformedURLException {
//创建基础模块
PdfWriter writer = new PdfWriter(PATH + "\\image.pdf");
PdfDocument pdf = new PdfDocument(writer);
//document就是我们的pdf对象
Document document = new Document(pdf);
//生成图片对象
Image image = new Image(ImageDataFactory.create("testImage.jpg"),200,400,200);
Image image1 = new Image(ImageDataFactory.create("testImage.jpg")).setHeight(100);
Paragraph p = new Paragraph("图片输出测试: ").setFont(sysFont)
.add(image)
.add(image1);
document.add(p);
document.close();
return "success";
}
效果展示:
创建图像对象时可以设置图像位置:
不设置位置的话就是默认的衔接状态,也可以通过set方法设置图片的各种属性:
创建table
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf, PageSize.A4.rotate());//设置页面大小,rotate()表示页面横向
document.setMargins(20, 20, 20, 20);//设置页边距
PdfFont font = PdfFontFactory.createFont(FontConstants.HELVETICA);//定义不同的字体类型
PdfFont bold = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD);//定义不同的字体类型
Table table = new Table(new float[]{4, 1, 3, 4, 3, 3, 3, 3, 1});//每个数定义一个列的相对宽度。
table.setWidth(UnitValue.createPercentValue(100));//表的宽度相对于页面的可用宽度,在这种情况下,表将使用100% 的页面宽度,减去页边距。
//接下来的操作时通过读取一个csv文件里的内容填充到pdf的表格上
BufferedReader br = new BufferedReader(new FileReader(DATA));
String line = br.readLine();
//process ()方法,使用特定的字体将行添加到表中,并定义行是否包含标题行的内容。
process(table, line, bold, true);
while ((line = br.readLine()) != null) {
process(table, line, font, false);
}
br.close();
document.add(table);
document.close();
public void process(Table table, String line, PdfFont font, boolean isHeader) {
StringTokenizer tokenizer = new StringTokenizer(line, ";");
while (tokenizer.hasMoreTokens()) {
if (isHeader) {
table.addHeaderCell(
new Cell().add(
new Paragraph(tokenizer.nextToken()).setFont(font)));
} else {
table.addCell(
new Cell().add(
new Paragraph(tokenizer.nextToken()).setFont(font)));
}
}
}
效果图如下:
以上就是一些基本功能的实现。