Skip to content

Officia.Pdf — PDF 读写、合并拆分与加密

能力摘要(AI 友好)OfficiaPdf 读取/抽取文本与图片、合并拆分、页码/水印/旋转、加密(RC4 与 AES-256),并提供链式 edit() 一次完成多步编辑。门面静态方法,纯 JDK 实现,依 PDF 32000 规范。

引入

xml
<dependency>
  <groupId>plus.ruoyi</groupId>
  <artifactId>officia-all</artifactId>
  <version>1.0.0</version>
</dependency>

仅需 PDF 能力时可单独引 officia-pdf

合并 / 拆分

java
import plus.ruoyi.officia.pdf.OfficiaPdf;
import java.util.List;

byte[] merged = OfficiaPdf.merge(List.of(pdfA, pdfB));        // 合并
OfficiaPdf.mergeToFile(List.of(pdfA, pdfB), new File("out.pdf")); // 合并直接写盘
List<byte[]> pages = OfficiaPdf.split(pdf);                   // 每页拆成一份

抽取 / 删除页(页索引可变参,从 0 开始)

java
byte[] sub  = OfficiaPdf.extractPages(pdf, 0, 2, 4);  // 抽取第 1、3、5 页
byte[] rest = OfficiaPdf.removePages(pdf, 1);         // 删除第 2 页

extractPages / removePages 接受 int... 页索引(0-based),可传任意多页,非连续也行。

读取 / 抽取

java
int n = OfficiaPdf.pageCount(pdf);
int n2 = OfficiaPdf.pageCount(pdf, "openPwd");        // 加密 PDF 传口令
String text = OfficiaPdf.extractText(pdf);            // 也有 (pdf, password) / (InputStream) / (File) 重载
List<String> perPage = OfficiaPdf.extractTextByPage(pdf);
List<byte[]> images = OfficiaPdf.extractImages(pdf);
List<float[]> sizes = OfficiaPdf.pageSizes(pdf);      // 每页 [宽, 高](pt)
String ver = OfficiaPdf.version(pdf);                 // 如 "1.7"
boolean locked = OfficiaPdf.isEncrypted(pdf);

元数据

java
PdfMetadata meta = OfficiaPdf.metadata(pdf);          // 也有 (pdf, password) 重载
byte[] tagged = OfficiaPdf.setMetadata(pdf, Map.of("Title", "合同", "Author", "Officia"));

单步编辑

java
byte[] rot = OfficiaPdf.rotate(pdf, 90);                  // 旋转 90°
byte[] wm  = OfficiaPdf.watermark(pdf, "机密");            // 默认字体水印
byte[] wm2 = OfficiaPdf.watermark(pdf, "机密", simsunTtf); // 指定中文字体(byte[])
byte[] pn  = OfficiaPdf.addPageNumbers(pdf, "第 {page} 页 / 共 {total} 页");

加密(含 AES-256)

java
byte[] enc  = OfficiaPdf.encryptAes256(pdf, "openPwd", "ownerPwd"); // AESV3,推荐
byte[] enc2 = OfficiaPdf.encrypt(pdf, "openPwd", "ownerPwd");        // 标准安全处理器(默认 128 位 RC4)
byte[] enc3 = OfficiaPdf.encrypt(pdf, "openPwd", "ownerPwd", 40);    // 指定位数
  • 用户口令(userPassword):打开文档需要的口令。
  • 拥有者口令(ownerPassword):解除权限限制的口令。

链式编辑 edit()

对同一份 PDF 做多步操作时,用链式编辑器一次完成(每步返回 thistoBytes() / writeTo() / toFile() 终结):

java
byte[] out = OfficiaPdf.edit(pdf)
    .watermark("机密", simsunTtf)                         // 水印
    .pageNumbers("第 {page} 页 / 共 {total} 页", simsunTtf) // 页码(注意方法名是 pageNumbers)
    .rotate(90)                                          // 旋转
    .append(anotherPdf)                                  // 追加另一份 PDF
    .keepPages(0, 1, 2)                                  // 只保留前 3 页
    .encryptAes256("open", "owner")                      // 加密放最后
    .toBytes();

链式方法:watermark / pageNumbers / rotate / keepPages / removePages / append / metadata / encrypt / encryptAes256;终结:toBytes() / writeTo(OutputStream) / toFile(File)

方法一览

分类方法
合并拆分merge / mergeToFile / split / extractPages(int...) / removePages(int...)
读取抽取pageCount / pageSizes / version / extractText(多重载) / extractTextByPage / extractImages / isEncrypted
元数据metadata / setMetadata
单步编辑rotate / watermark / addPageNumbers
链式编辑edit(pdf)watermark / pageNumbers / rotate / keepPages / removePages / append / metadata / encrypt / encryptAes256toBytes
加密encrypt(可选位数) / encryptAes256

常见问题

  • 中文水印/页码乱码:传入覆盖所需汉字的 TTF 字节(watermark(pdf, text, fontTtf))。
  • 加密 PDF 读取extractText / pageCount / metadata 都有 (…, password) 重载。
  • 页索引越界extractPages / removePages 的索引从 0 开始,越界抛 OfficiaException