我需要通过页面解析PDF文件,并将每个文件分别加载到byte[]
。我使用了itext库。
我使用以下代码下载包含一页的文件:
public Document addPageInTheDocument(String namePage, MultipartFile pdfData, Long documentId) throws IOException {
notNull(namePage, INVALID_PARAMETRE);
notNull(pdfData, INVALID_PARAMETRE);
notNull(documentId, INVALID_PARAMETRE);
byte[] in = pdfData.getBytes(); // size file 88747
Page page = new Page(namePage);
Document document = new Document();
document.setId(documentId);
PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfData.getBytes()));
PdfDocument pdfDocument = new PdfDocument(reader);
if (pdfDocument.getNumberOfPages() != 1) {
throw new IllegalArgumentException();
}
byte[] transform = pdfDocument.getPage(1).getContentBytes(); // 1907 size page
page.setPageData(pdfDocument.getPage(1).getContentBytes());
return addPageInTheDocument(document, page);
}
我正在尝试使用以下代码恢复文件:
ByteBuffer byteContent = new ByteBuffer() ;
for (Map.Entry<String, Page> page : pages.entrySet()) {
byteContent.append(page.getValue().getPageData());
}
PdfWriter writer = new PdfWriter(new FileOutputStream(book.getName() + modification + FORMAT));
byte[] df = byteContent.toByteArray();
PdfReader reader = new PdfReader(new ByteArrayInputStream(byteContent.toByteArray()));
com.itextpdf.layout.Document itextDocument = new com.itextpdf.layout.Document(new PdfDocument(reader, writer));
itextDocument.close();
为什么尺寸会有这么大差异?
为什么文件和页面,以及byte[]
创建文件?
答案 0 :(得分:0)
让我们从您的尺寸问题开始:
byte[] in = pdfData.getBytes(); // size file 88747 ... byte[] transform = pdfDocument.getPage(1).getContentBytes(); // 1907 size page
...
为什么尺寸会有这么大差异?
因为PdfPage.getContentBytes()
没有返回您期望的内容。
您似乎希望它返回给定页面内容的完整表示,并且可以解释该方法的Javadoc(“获取整个页面内容的解码字节。”)意思是。
事实并非如此。 PdfPage.getContentBytes()
返回页面的内容流的内容。这些内容流包含构建页面的一系列命令。但是这些命令采用引用内容流之外的数据的参数,例如:
此外,存在具有其自己的内容流的注释(例如,表单字段),其存储在单独的结构中。许多页面属性也在外面。
因此,大小存在差异因为您只使用getContentBytes
获得了一小部分页面定义。
现在让我们看看你的代码“恢复文件”。
作为上述的推论,很明显你的代码只是连接了一些内容流,但没有提供这些流所引用的外部资源。
但除此之外,您的代码还指出了对PDF页面性质的误解:它们不仅仅是您可以根据需要拆分和连接的blob。它们是PDF对象的集合,遍布PDF文件;不同的页面可以共享它们的一些对象(例如常用图像的字体)。
你可以做什么......
作为单个页面的表示,您应该使用包含该单个页面引用的数据的PDF。 iText示例Burst.java显示了如何执行此操作。
要再次加入这些单页PDF,您可以使用iText PdfMerger
。请记住设置智能模式(PdfWriter.setSmartMode(true)
)以防止结果中的资源重复。