当前位置: 首页 > news >正文

完整教程:PDFBox - PDDocument 与 byte 数组、PDF 加密

一、PDDocument 与 byte 数组

1、由 byte 数组创建 PDDocument
(1)基本介绍
  • 调用 PDDocument 的 load 静态方法,由 byte 数组创建 PDDocument
public static PDDocument load(byte[] input) throws IOException {
return load(input, "");
}
(2)演示
File pdfFile = new File("pdf/image_example.pdf");
InputStream pdfInputStream;
try {
pdfInputStream = new FileInputStream(pdfFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("PDF 文件不存在");
return;
}
ByteArrayOutputStream pdfBuffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
try {
while ((nRead = pdfInputStream.read(data, 0, data.length)) != -1) {
pdfBuffer.write(data, 0, nRead);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("PDF 读取文件失败");
return;
}
byte[] pdfBytes = pdfBuffer.toByteArray();
try (PDDocument document = PDDocument.load(pdfBytes)) {
PDPage page = new PDPage();
document.addPage(page);
File imgFile = new File("pdf/dzs.jpeg");
InputStream imgInputStream;
try {
imgInputStream = new FileInputStream(imgFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("图片不存在");
return;
}
ByteArrayOutputStream imgBuffer = new ByteArrayOutputStream();
int nReadImg;
byte[] dataImg = new byte[1024];
try {
while ((nReadImg = imgInputStream.read(dataImg, 0, dataImg.length)) != -1) {
imgBuffer.write(dataImg, 0, nReadImg);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("图片读取失败");
return;
}
byte[] imgBytes = imgBuffer.toByteArray();
PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, imgBytes, "dzs.jpeg");
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
contentStream.drawImage(pdImage, 100, 600, pdImage.getWidth() * 0.25f, pdImage.getHeight() * 0.25f);
} catch (IOException e) {
e.printStackTrace();
}
document.save("pdf/image_example.pdf");
} catch (IOException e) {
e.printStackTrace();
}
2、由 PDDocument 得到 byte 数组
(1)基本介绍
public void save(OutputStream output) throws IOException {
if (this.document.isClosed()) {
throw new IOException("Cannot save a document which has been closed");
} else {
Iterator var2 = this.fontsToSubset.iterator();
while(var2.hasNext()) {
PDFont font = (PDFont)var2.next();
font.subset();
}
this.fontsToSubset.clear();
COSWriter writer = new COSWriter(output);
try {
writer.write(this);
} finally {
writer.close();
}
}
}
(2)演示
File pdfFile = new File("pdf/image_example.pdf");
InputStream pdfInputStream;
try {
pdfInputStream = new FileInputStream(pdfFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("PDF 文件不存在");
return;
}
ByteArrayOutputStream pdfBuffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
try {
while ((nRead = pdfInputStream.read(data, 0, data.length)) != -1) {
pdfBuffer.write(data, 0, nRead);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("PDF 读取文件失败");
return;
}
byte[] pdfBytes = pdfBuffer.toByteArray();
try (PDDocument document = PDDocument.load(pdfBytes)) {
PDPage page = new PDPage();
document.addPage(page);
File imgFile = new File("pdf/dzs.jpeg");
InputStream imgInputStream;
try {
imgInputStream = new FileInputStream(imgFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("图片不存在");
return;
}
ByteArrayOutputStream imgBuffer = new ByteArrayOutputStream();
int nReadImg;
byte[] dataImg = new byte[1024];
try {
while ((nReadImg = imgInputStream.read(dataImg, 0, dataImg.length)) != -1) {
imgBuffer.write(dataImg, 0, nReadImg);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("图片读取失败");
return;
}
byte[] imgBytes = imgBuffer.toByteArray();
PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, imgBytes, "dzs.jpeg");
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
contentStream.drawImage(pdImage, 100, 600, pdImage.getWidth() * 0.25f, pdImage.getHeight() * 0.25f);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
document.save(output);
byte[] bytes = output.toByteArray();
System.out.println("PDF 字节数:" + bytes.length);
} catch (IOException e) {
e.printStackTrace();
}
# 输出结果
PDF 字节数:86736

二、PDF 加密

1、基本介绍
(1)用户密码
  1. 用户密码(User Password / Open Password)用于打开 PDF 文件,也叫打开密码或文档密码

  2. 如果设置了用户密码,任何人在打开该 PDF 时都必须输入这个密码,否则无法查看内容

(2)所有者密码
  1. 所有者密码(Owner Password / Permissions Password)用于解除权限限制

  2. 所有者密码用于禁止某些操作,例如,打印、复制、编辑

  3. 只有拥有所有者密码的用户,才能移除这些限制,普通用户即使能打开 PDF,也无法绕过这些限制

2、创建加密的 PDF
try (PDDocument document = new PDDocument()) {
PDPage page = new PDPage();
document.addPage(page);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText("Hello PDFBox");
contentStream.endText();
} catch (IOException e) {
e.printStackTrace();
}
// 设置权限
AccessPermission accessPermission = new AccessPermission();
accessPermission.setReadOnly();
// 设置保护策略
StandardProtectionPolicy policy = new StandardProtectionPolicy("12345", "12345", accessPermission);
document.protect(policy);
document.save("pdf/test.pdf");
} catch (IOException e) {
e.printStackTrace();
}
3、读取加密的 PDF
  1. 读取时未设置密码或设置了错误的密码
try (PDDocument document = PDDocument.load(new File("pdf/test.pdf"), "abc")) {
PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(document);
System.out.println(text);
} catch (Exception e) {
e.printStackTrace();
}
# 输出结果
org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException: Cannot decrypt PDF, the password is incorrect
  1. 读取时设置了正确的密码
try (PDDocument document = PDDocument.load(new File("pdf/test.pdf"), "12345")) {
PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(document);
System.out.println(text);
} catch (Exception e) {
e.printStackTrace();
}
# 输出结果
Hello PDFBox
http://www.zskr.cn/news/49821.html

相关文章:

  • Web应用模糊测试完全指南
  • 【HT-086-Div.2】错乱的集合
  • WEditor的使用方法
  • 感情粉末沿着试管边缘 在祝福中逐渐分解 加热认知离子重新排列 于底部悲伤沉淀
  • flask: 抛出异常
  • 雪地奔驰全等级提升所需经验一览
  • 2025皮肤亚健康管理品牌最新专业推荐:科技赋能健康美新生态
  • 深入解析:Vue3 路由配置和使用与讲解(超级详细)
  • HubSpot如何规模化推进AI编码助手应用
  • 完整教程:OpenHarmony内核基础:LiteOS-M内核与POSIX/CMSIS接口
  • 常量指针 和 指针常量 - const pointer and pointer to const
  • 11.14模拟赛
  • 实用指南:云计算生态及学习方向和就业领域方向
  • 2025年11月徐州AI GEO平台综合评测与权威推荐
  • 2025年国内徐州宣传片公司品牌权威推荐榜单
  • 好题集 (2) - LG P4550 收集邮票
  • 腾讯元宝如何导出内容为文档
  • 洛谷 P4242. 树上的毒瘤
  • Number Theory
  • 实用指南:【STM32】RTC实时时钟
  • 探索乐泰胶水:性能与适用场景全解析
  • 【System Beats!】第七章 链接
  • 实用指南:接口测试 | 使用Postman实际场景化测试
  • 应用程序建立的数据库连接,也就是非交互式连接 是什么时候开始的?什么时候结束?连接结束后 会影响应用程序操作db失败吗? 还有就是如果连接关闭了 会立马重新建立新的连接吗?
  • #题解#洛谷P1884#二维离散化#
  • HarmonyOS应用配置文件与资源组织深度解析 - 教程
  • 2025厨房/无烟管/商用/复合式/内循环/小型/油烟净化/一体机推荐榜:上海多环五星领跑 全场景适配解锁餐饮 / 家用净化新体验
  • 2分钟选刊!值得农林环境人收藏的6个期刊!境科研人必备!
  • 2025武汉车出租厂家推荐榜:防撞车出租/高空车出租/登高车出租/服务体验与高性价比深度解析
  • 2025试验机厂家推荐榜:万能试验机/高低温试验机/钢丝绳试验机专精之选