当前位置: 首页 > 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)基本介绍
  • 调用 PDDocument 的 save 方法,使用 ByteArrayOutputStream 来捕获输出,由 PDDocument 得到 byte 数组
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.dtcms.com/a/486088.html

相关文章:

  • 【Pytorch】分类问题交叉熵
  • 如何轻松删除 realme 手机中的联系人
  • Altium Designer怎么制作自己的集成库?AD如何制作自己的原理图库和封装库并打包生成库文件?AD集成库制作好后如何使用丨AD集成库使用方法
  • Jackson是什么
  • 代码实例:Python 爬虫抓取与解析 JSON 数据
  • 襄阳建设网站首页百度知识营销
  • 山东住房和城乡建设厅网站电话开发软件都有哪些
  • AbMole| Yoda1( M9372;GlyT2-IN-1; Yoda 1)
  • LLM监督微调SFT实战指南(Qwen3-0.6B-Base)
  • 【基础算法】多源 BFS
  • *@UI 视角下主程序与子程序的菜单页面架构及关联设计
  • Virtio 半虚拟化技术解析
  • 网站设计怎么好看律师做网络推广哪个网站好
  • 用commons vfs 框架 替换具体的sftp 实现
  • 网站模板怎么设计软件wordpress多重筛选页面
  • 通往Docker之路:从单机到容器编排的架构演进全景
  • 分布式链路追踪:微服务可观测性的核心支柱
  • PostgreSQL 函数ARRAY_AGG详解
  • 【OpenHarmony】MSDP设备状态感知模块架构
  • RAG 多模态 API 处理系统设计解析:企业级大模型集成架构实战
  • 通过一个typescript的小游戏,使用单元测试实战(二)
  • 多物理域协同 + 三维 CAD 联动!ADS 2025 解锁射频前端、天线设计新体验
  • 前端微服务架构解析:qiankun 运行原理详解
  • linux ssh config详解
  • 内网攻防实战图谱:从红队视角构建安全对抗体系
  • 鲲鹏ARM服务器配置YUM源
  • 网站分类标准沈阳网站制作招聘网
  • 建设一个网站需要几个角色建筑工程网课心得体会
  • 基于Robosuite和Robomimic采集mujoco平台的机械臂数据微调预训练PI0模型,实现快速训练机械臂任务
  • 深度学习目标检测项目