java 中使用iText操作 PDF文件
文本我们聚焦如何创建PDF文档,基于流行的iText和PdfBox库。我们着重利用iText示例进行说明。
maven 依赖
首先看下maven依赖,需要在项目中加入:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
读者可以查找最新版本。另外还有一个可选依赖,对pdf进行加密时需要。Bounty Castle 提供加密算法实现,maven依赖如下:
org.bouncycastle bcprov-jdk15on 1.56概述
iText 和 PdfBox 都可以用于操作/创建PDF的java工具库。虽然输出库文件一样,但操作方式有一些差异。
IText创建pdf
pdf 中插入文本
首先示例在pdf文件中插入“hello world” 文本。
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("iTextHelloWorld.pdf"));
document.open();
Font font = FontFactory.getFont(FontFactory.COURIER, 16, BaseColor.BLACK);
Chunk chunk = new Chunk("Hello World", font);
document.add(chunk);
document.close();
使用iText库创建pdf是基于在文档中操作实现Elements接口对象,往文档加入最小元素是Chunk(块),是带有字体格式的字符串。另外块用于组合其他元素,如段落、章节等,最终组成文档。
插入图像
iText提供简单方法实现文档中插入图像。仅需创建图像示例并增加至文档:
Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("iTextImageExample.pdf"));
document.open();
Image img = Image.getInstance(path.toAbsolutePath().toString());
document.add(img);
document.close();
插入表格
在pdf中插入表格是我们常见的需求。幸运的是,iText默认提供这些功能。首先我们要做的是创建PdfTable对象,在构造函数中提供表格列的数量,现在对新创建的表格可以通过调用addCell方法增加新的单元格。只要定义了所有必要的单元格,iText就会创建表行,这意味着加入你创建了有3列的表并向其中添加了8个单元格,就只会显示2行,每一行有3个单元格。请看示例:
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("iTextTable.pdf"));
document.open();
PdfPTable table = new PdfPTable(3);
addTableHeader(table);
addRows(table);
addCustomRows(table);
document.add(table);
document.close();
我们创建新的表格有三列和三行,第一行作为表格头,带有不同的背景色和边框宽度:
private void addTableHeader(PdfPTable table) {
Stream.of("column header 1", "column header 2", "column header 3")
.forEach(columnTitle -> {
PdfPCell header = new PdfPCell();
header.setBackgroundColor(BaseColor.LIGHT_GRAY);
header.setBorderWidth(2);
header.setPhrase(new Phrase(columnTitle));
table.addCell(header);
});
}
第二行有三个单元格组成,没有额外的样式,包含不同文字:
private void addRows(PdfPTable table) {
table.addCell("row 1, col 1");
table.addCell("row 1, col 2");
table.addCell("row 1, col 3");
}
单元格不仅可以展示文本,也可以是图像。另外,每个单元格有不同的样式,下面示例中使用水平和垂直对齐:
private void addCustomRows(PdfPTable table)
throws URISyntaxException, BadElementException, IOException {
Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
Image img = Image.getInstance(path.toAbsolutePath().toString());
img.scalePercent(10);
PdfPCell imageCell = new PdfPCell(img);
table.addCell(imageCell);
PdfPCell horizontalAlignCell = new PdfPCell(new Phrase("row 2, col 2"));
horizontalAlignCell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(horizontalAlignCell);
PdfPCell verticalAlignCell = new PdfPCell(new Phrase("row 2, col 3"));
verticalAlignCell.setVerticalAlignment(Element.ALIGN_BOTTOM);
table.addCell(verticalAlignCell);
}
文件加密
使用iText库实现权限控制,需要已创建的pdf文档。下面示例,我们针对前面生成的 iTextHelloWorld.pdf 文件。首先我们使用PdfReader加载pdf文件,然后创建PdfStamper对象给pdf增加额外内容,如元数据、加密等:
PdfReader pdfReader = new PdfReader("HelloWorld.pdf");
PdfStamper pdfStamper
= new PdfStamper(pdfReader, new FileOutputStream("encryptedPdf.pdf"));
pdfStamper.setEncryption(
"userpass".getBytes(),
"ownerpass".getBytes(),
0,
PdfWriter.ENCRYPTION_AES_256
);
pdfStamper.close();
上面示例我们使用两个密码加密文件,userpass密码是只读权限,不能打印。ownerpass密码是主密码,允许完全访问。如果希望用户可以打印pdf,修改setEncryption方法的第三个参数的“0”值为"PdfWriter.ALLOW_PRINTING"。
当然,我们也能混合不同的权限组合:
PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY
需要提醒的是,使用iText设置访问权限会同时创建临时pdf文件,应该删除,否则会被任何人完全访问。
总结
本文介绍了如何通过iText库操作pdf文件,创建文件、插入文本和图像以及表格,同时也介绍了如何对pdf文件进行加密。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/82817020