PDFBox:具有附件的创建PDF/A-3A文档的验证,流长度不匹配而失败

发布于 2025-01-19 19:55:04 字数 3428 浏览 3 评论 0原文

我正在尝试使用示例 CreatePDFA 创建带有附加纯文本文件的 PDF/A-3A 文件,但使用 VeraPDF 验证器验证结果文件失败。 我正在使用 PDFBox v.3.0.0 RC1。

错误: 流字典中指定的 Length 键的值应与文件中紧跟在 Stream 关​​键字之后的 LINE FEED (0Ah) 字符之后以及在 endstream 关​​键字之前的 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

I'm trying to create a PDF/A-3A file with an attached plaint text file using the example CreatePDFA but the validation of the resulting file fails using VeraPDF validator.
I'm using PDFBox v.3.0.0 RC1.

Error:
The value of the Length key specified in the stream dictionary shall match the number of bytes in the file following the LINE FEED (0Ah) character after the stream keyword and preceding the EOL marker before the endstream keyword.

Error location is: root/indirectObjects[0](22 0)/directObject[0]

How can I add the correct length to the PDF file?
The attachment code is as follows:

    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);
        }
    }

The PDF file can be found here:
https://gofile.io/d/FuWIdV

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

李不 2025-01-26 19:55:04

PdfBox的最新版本3.0.0-alpha2似乎解决了这个问题。

The latest version 3.0.0-alpha2 of PdfBox seems to resolve this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文