使用iText计算PDF上的附件数量

时间:2019-01-31 00:51:28

标签: java pdf count itext attachment

我正在尝试计算PDF上的附件数,以验证我们的附件代码。我拥有的代码大多数时候都可以使用,但是最近随着附件数量以及附件大小的增加,它开始失败。示例:我有一个包含700个附件的PDF,总计1.6 gb。另一个带有65个附件,大约10 mb。 65个计数是递增计数的。我们已经逐个文件地建立了它。例程有64个文件(约9.8mb),可以算正常。添加文件65(大约.5mb),例程失败。

这是位于jre1.8.0_162下的itextpdf-5.5.9.jar

我们仍在测试文件编号和大小的不同组合,以查看中断的位置。

private static String CountFiles() throws IOException, DocumentException {

    Boolean errorFound = new Boolean(true);
    PdfDictionary root;
    PdfDictionary names;
    PdfDictionary embeddedFiles;
    PdfReader reader = null;
    String theResult = "unknown";

    try {
        if (!theBaseFile.toLowerCase().endsWith(".pdf"))
            theResult = "file not PDF";
        else {
            reader = new PdfReader(theBaseFile);
            root = reader.getCatalog();
            names = root.getAsDict(PdfName.NAMES);
            if (names == null)
                theResult = "0";
            else {
                embeddedFiles = names.getAsDict(PdfName.EMBEDDEDFILES);
                PdfArray namesArray = embeddedFiles.getAsArray(PdfName.NAMES);
                theResult = String.format("%d", namesArray.size() / 2);
            }
            reader.close();
            errorFound = false;
        }
    }
    catch (Exception e) {
        theResult = "unknown";
    }
    finally {
        if (reader != null)
            reader.close();
    }
    if (errorFound)
        sendError(theResult);
    return theResult;
}

private static String AttachFileInDir() throws IOException, DocumentException {

    String theResult = "unknown";
    String outputFile = theBaseFile.replaceFirst("(?i).pdf$", ".attach.pdf");
    int maxFiles = 1000;
    int fileCount = 1;

    PdfReader reader = null;
    PdfStamper stamper = null;

    try {
        if (!theBaseFile.toLowerCase().endsWith(".pdf"))
            theResult = "basefile not PDF";
        else if (theFileDir.length() == 0)
            theResult = "no attach directory";
        else if (!Files.isDirectory(Paths.get(theFileDir)))
            theResult = "invalid attach directory";
        else {
            reader = new PdfReader(theBaseFile);
            stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
            stamper.getWriter().setPdfVersion(PdfWriter.VERSION_1_7);
            Path dir = FileSystems.getDefault().getPath(theFileDir);
            DirectoryStream<Path> stream = Files.newDirectoryStream(dir);
            for (Path path : stream) {
                stamper.addFileAttachment(null, null, path.toFile().toString(), path.toFile().getName());
                if (++fileCount > maxFiles) {
                    theResult = "maxfiles exceeded";
                    break;
                }
            }
            stream.close();
            stamper.close();
            reader.close();
            theResult = "SUCCESS";
        }
    }
    catch (Exception e) {
        theResult = "unknown";
    }
    finally {
        if (stamper != null)
            stamper.close();
        if (reader != null)
            reader.close();
    }
    if (theResult != "SUCCESS")
        sendError(theResult);
    return theResult;
}

我希望附件可以简单计数。似乎正在发生的是namesArray返回null。结果保持“未知”。我怀疑,namesArray试图容纳所有文件,但大小不一。

注意:使用AttachFileInDir过程附加文件。转储目录中的所有文件,然后运行AttachFileInDir。是的,AttachFileInDir中的错误陷阱需要解决。

我们将不胜感激,欢迎您使用其他方法

1 个答案:

答案 0 :(得分:0)

我终于明白了。原来每个KID都是NAMES的字典…。

每个NAMES拥有64个文件引用。在65个文件及以上的文件中,它组成了一个KIDS字典名称数组。所以279个文件=(8 * 64 46)/ 2(9个总KIDS阵列元件)。

有一两件事,我必须弥补。如果从pdf删除所有附件,则会留下伪像,而不是从来没有附件的PDF

private static String CountFiles() throws IOException, DocumentException {

    Boolean errorFound = new Boolean(true);
    int totalFiles = 0;
    PdfArray filesArray;
    PdfDictionary root;
    PdfDictionary names;
    PdfDictionary embeddedFiles;
    PdfReader reader = null;
    String theResult = "unknown";

    try {
        if (!theBaseFile.toLowerCase().endsWith(".pdf"))
            theResult = "file not PDF";
        else {
            reader = new PdfReader(theBaseFile);
            root = reader.getCatalog();
            names = root.getAsDict(PdfName.NAMES);
            if (names == null){
                theResult = "0";
                errorFound = false;
            }
            else {
                embeddedFiles = names.getAsDict(PdfName.EMBEDDEDFILES);
                filesArray = embeddedFiles.getAsArray(PdfName.NAMES);
                if (filesArray != null)
                    totalFiles = filesArray.size();
                else {
                    filesArray = embeddedFiles.getAsArray(PdfName.KIDS);
                    if (filesArray != null){
                        for (int i = 0; i < filesArray.size(); i++)
                            totalFiles += filesArray.getAsDict(i).getAsArray(PdfName.NAMES).size();                         
                    }
                }
                theResult = String.format("%d", totalFiles / 2);
                reader.close();
                errorFound = false;
            }
        }
    }
    catch (Exception e) {
        theResult = "unknown" + e.getMessage();
    }
    finally {
        if (reader != null)
            reader.close();
    }
    if (errorFound)
        sendError(theResult);
    return theResult;
}