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)用户密码
-
用户密码(User Password / Open Password)用于打开 PDF 文件,也叫打开密码或文档密码
-
如果设置了用户密码,任何人在打开该 PDF 时都必须输入这个密码,否则无法查看内容
(2)所有者密码
-
所有者密码(Owner Password / Permissions Password)用于解除权限限制
-
所有者密码用于禁止某些操作,例如,打印、复制、编辑
-
只有拥有所有者密码的用户,才能移除这些限制,普通用户即使能打开 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
- 读取时未设置密码或设置了错误的密码
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
- 读取时设置了正确的密码
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