Skip to main content
 首页 » 编程设计

java 中使用iText操作 PDF文件

2022年07月19日132qlqwjy

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