1

所以,我正在这样做:

PDFMergerUtility mergePdf = new PDFMergerUtility();

for (int i = 0; i < filePaths.size(); i++) 
    mergePdf.addSource(filePaths.get(i));

mergePdf.setDestinationFileName(tempFile.getAbsolutePath()); 
mergePdf.mergeDocuments();

直到在无法解析的 PDF 上引发异常(损坏的 PDF 或 PDFBox 无法处理的东西)之前,它都非常有效。它不会经常发生。

我希望能够知道它失败的来源,在随后的合并中排除它们,并告诉用户哪些文档失败了。

这可以做到吗?

更新:

这是我的例外:

java.io.IOException: Error: Expected a long type at offset 591535, instead got 'E^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^UZí^KÄ@©¢^X<8d>G §ÑE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^TQE^T<84>f<96><8a>'
    at org.apache.pdfbox.pdfparser.BaseParser.readLong(BaseParser.java:1695)
    at org.apache.pdfbox.pdfparser.BaseParser.readObjectNumber(BaseParser.java:1623)
    at org.apache.pdfbox.pdfparser.PDFParser.parseObject(PDFParser.java:614)
    at org.apache.pdfbox.pdfparser.PDFParser.parse(PDFParser.java:203)
    at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1220)
    at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1187)
    at org.apache.pdfbox.util.PDFMergerUtility.mergeDocuments(PDFMergerUtility.java:237)
    at org.apache.pdfbox.util.PDFMergerUtility.mergeDocuments(PDFMergerUtility.java:194)
    at myapp.util.DocumentImage.combinePDFs(DocumentImage.java:289)
    at myapp.webapp.download.DownloadLatestForCLO.generate(DownloadLatestForCLO.java:73)
    at myapp.webapp.download.DownloadLatestForCLO.getFileSize(DownloadLatestForCLO.java:64)
    at myapp.webapp.download.DownloadServlet.handleRequest(DownloadServlet.java:58)
    at myapp.webapp.download.DownloadServlet.doGet(DownloadServlet.java:32)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
4

1 回答 1

1

幸运的是PDFBox开源的,因此已经下载了最新的源代码(在撰写本文时为 2.00 RC3)并在文件中 \pdfbox-2.0.0-RC3\pdfbox\src\main\java\org\apache\pdfbox\multipdf\PDFMergerUtility.java(大约第 188 行)

我们可以看到它从较低的级别向上抛出这个异常并且没有捕获它并添加导致错误的文件的详细信息。

在解决此问题之前,您必须在代码中捕获此错误并迭代加载和关闭它们的每个源文件,直到找到无法处理的文件并自行报告。

如果您有兴趣从源头(在PDFBox内)解决问题,那么这是要进行的编辑并提交给 PDFBox 项目团队。当该修复被合并到构建中并且您升级到该版本时,您可以安全地删除您的迭代代码:

        try
        {
            MemoryUsageSetting partitionedMemSetting = memUsageSetting != null ? 
                    memUsageSetting.getPartitionedCopy(sources.size()+1) :
                    MemoryUsageSetting.setupMainMemoryOnly();
            Iterator<InputStream> sit = sources.iterator();
            destination = new PDDocument(partitionedMemSetting);

            while (sit.hasNext())
            {
                sourceFile = sit.next();
                source = PDDocument.load(sourceFile, partitionedMemSetting);
                tobeclosed.add(source);
                appendDocument(destination, source);
            }
            if (destinationStream == null)
            {
                destination.save(destinationFileName);
            }
            else
            {
                destination.save(destinationStream);
            }
        }

catch (IOException e) { /* 插入代码以将其置于内部异常中并抛出一个包括命名的 'sourceFile' */ }


        finally
        {
            ....}
于 2016-02-12T23:33:53.660 回答