PDFBox:创建的带有附件的 PDF/A-3A 文档的验证失败,流长度不匹配
PDFBox: Validation of created PDF/A-3A document with attachment fails with stream length mismatch
我正在尝试使用示例 CreatePDFA 创建一个带有附加纯文本文件的 PDF/A-3A 文件,但使用 VeraPDF 验证程序验证生成的文件失败。
我正在使用 PDFBox v.3.0.0 RC1。
错误:
流字典中指定的 Length 键的值应与流关键字后的换行符 (0Ah) 字符后和结束流关键字前的 EOL 标记前的文件中的字节数相匹配。
错误位置为:root/indirectObjects[0](22 0)/directObject[0]
如何为 PDF 文件添加正确的长度?
附件代码如下:
private void attachFile(PDDocument doc, File file, String mediaType, String description) throws IOException {
long fileSize = file.length();
BasicFileAttributes fileAttr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
GregorianCalendar creationTimeCal = new GregorianCalendar();
creationTimeCal.setTimeInMillis(fileAttr.creationTime().toMillis());
GregorianCalendar modifiedTimeCal = new GregorianCalendar();
modifiedTimeCal.setTimeInMillis(fileAttr.lastModifiedTime().toMillis());
// embedded files are stored in a named tree
PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode();
// first create the file specification, which holds the embedded file
PDComplexFileSpecification fs = new PDComplexFileSpecification();
// use both methods for backwards, cross-platform and cross-language compatibility.
fs.setFile(file.getName());
fs.setFileUnicode(file.getName());
COSDictionary dict = fs.getCOSObject();
dict.setName("AFRelationship", "Alternative");
try (InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ)) {
PDEmbeddedFile ef = new PDEmbeddedFile(doc, is);
// now lets some of the optional parameters
ef.setSubtype(mediaType);
ef.setSize((int) fileSize);
ef.setCreationDate(creationTimeCal);
ef.setModDate(modifiedTimeCal);
ef.setDecodedStreamLength((int) fileSize);
// use both methods for backwards, cross-platform and cross-language compatibility.
fs.setEmbeddedFile(ef);
fs.setEmbeddedFileUnicode(ef);
fs.setFileDescription(StringUtils.defaultString(description, file.getName()));
// create a new tree node and add the embedded file
String attachmentName = StringUtils.defaultString(file.getName(),description);
PDEmbeddedFilesNameTreeNode treeNode = new PDEmbeddedFilesNameTreeNode();
treeNode.setNames(Collections.singletonMap(attachmentName, fs));
// add the new node as kid to the root node
List<PDEmbeddedFilesNameTreeNode> kids = new ArrayList<>();
kids.add(treeNode);
efTree.setKids(kids);
// add the tree to the document catalog
PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
names.setEmbeddedFiles(efTree);
doc.getDocumentCatalog().setNames(names);
// AF entry (Array) in catalog with the FileSpec
COSArray cosArray = new COSArray();
cosArray.add(fs);
doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray);
// show attachments panel in some viewers
doc.getDocumentCatalog().setPageMode(PageMode.USE_ATTACHMENTS);
}
}
可在此处找到 PDF 文件:
https://gofile.io/d/FuWIdV
PdfBox 的最新版本 3.0.0-alpha2 似乎解决了这个问题。
我正在尝试使用示例 CreatePDFA 创建一个带有附加纯文本文件的 PDF/A-3A 文件,但使用 VeraPDF 验证程序验证生成的文件失败。 我正在使用 PDFBox v.3.0.0 RC1。
错误: 流字典中指定的 Length 键的值应与流关键字后的换行符 (0Ah) 字符后和结束流关键字前的 EOL 标记前的文件中的字节数相匹配。
错误位置为:root/indirectObjects[0](22 0)/directObject[0]
如何为 PDF 文件添加正确的长度? 附件代码如下:
private void attachFile(PDDocument doc, File file, String mediaType, String description) throws IOException {
long fileSize = file.length();
BasicFileAttributes fileAttr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
GregorianCalendar creationTimeCal = new GregorianCalendar();
creationTimeCal.setTimeInMillis(fileAttr.creationTime().toMillis());
GregorianCalendar modifiedTimeCal = new GregorianCalendar();
modifiedTimeCal.setTimeInMillis(fileAttr.lastModifiedTime().toMillis());
// embedded files are stored in a named tree
PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode();
// first create the file specification, which holds the embedded file
PDComplexFileSpecification fs = new PDComplexFileSpecification();
// use both methods for backwards, cross-platform and cross-language compatibility.
fs.setFile(file.getName());
fs.setFileUnicode(file.getName());
COSDictionary dict = fs.getCOSObject();
dict.setName("AFRelationship", "Alternative");
try (InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ)) {
PDEmbeddedFile ef = new PDEmbeddedFile(doc, is);
// now lets some of the optional parameters
ef.setSubtype(mediaType);
ef.setSize((int) fileSize);
ef.setCreationDate(creationTimeCal);
ef.setModDate(modifiedTimeCal);
ef.setDecodedStreamLength((int) fileSize);
// use both methods for backwards, cross-platform and cross-language compatibility.
fs.setEmbeddedFile(ef);
fs.setEmbeddedFileUnicode(ef);
fs.setFileDescription(StringUtils.defaultString(description, file.getName()));
// create a new tree node and add the embedded file
String attachmentName = StringUtils.defaultString(file.getName(),description);
PDEmbeddedFilesNameTreeNode treeNode = new PDEmbeddedFilesNameTreeNode();
treeNode.setNames(Collections.singletonMap(attachmentName, fs));
// add the new node as kid to the root node
List<PDEmbeddedFilesNameTreeNode> kids = new ArrayList<>();
kids.add(treeNode);
efTree.setKids(kids);
// add the tree to the document catalog
PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
names.setEmbeddedFiles(efTree);
doc.getDocumentCatalog().setNames(names);
// AF entry (Array) in catalog with the FileSpec
COSArray cosArray = new COSArray();
cosArray.add(fs);
doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray);
// show attachments panel in some viewers
doc.getDocumentCatalog().setPageMode(PageMode.USE_ATTACHMENTS);
}
}
可在此处找到 PDF 文件: https://gofile.io/d/FuWIdV
PdfBox 的最新版本 3.0.0-alpha2 似乎解决了这个问题。