Itext7使用详解

962 阅读4分钟

「这是我参与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带路径的文件名

image.png

  • PdfWriter了解它需要写什么内容,因为它监听PdfDocument的动态。PdfWriter负责管理添加的内容,并把内容分布到不同的页面上,并跟踪有关页面内容的所有信息。
  • PdfDocumentPdfWriter创建以后,我们把PdfDocument传入Docment,并对Document对象操作,Document就是我们的pdf对象
  • 创建Paragraph,包含"Hello World"字符串,并把这个短语加入Document独享中
  • 关闭Document。PDF文档创建完成

效果图图下:

image.png

解决中文不显示问题

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";
}

效果图如下:

image.png

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";
}

效果展示:

image.png

创建图像对象时可以设置图像位置:

image.png

不设置位置的话就是默认的衔接状态,也可以通过set方法设置图片的各种属性:

image.png

创建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)));
        }
    }
}

效果图如下:

image.png 以上就是一些基本功能的实现。