DOCX转PDF时间太长

有一个特殊docx样本,总共4510页,是由相同的几页内容一直复制得到的。我想把这个docx样本的前10页转成pdf。微软的office365大概1秒左右完成,aspose迟迟得不到转换结果。有没有办法应对这种样本。
代码如下:

private Document loadDocument(byte[] inWord, String password) throws Exception {
    LoadOptions loadOptions = new LoadOptions();
    if (password != null && !password.isEmpty()) {
        loadOptions.setPassword(password);
    }
    return new Document(new ByteArrayInputStream(inWord), loadOptions);
}

private byte[] convertToPdf(Document document) throws Exception {
    try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
        PdfSaveOptions pdfOptions = new PdfSaveOptions();
        pdfOptions.setCompliance(PdfCompliance.PDF_17);
        pdfOptions.setPageSet(new PageSet(0, 10));
        document.save(bos, pdfOptions);
        return bos.toByteArray();
    }
}

样本在文件系统中显示为:12.5MB, 但是上传附件提示超过了48.8MB
样本的微软云下载链接:https://dllf.intsig.net/download/2025/CustomService/debug.docx

@ztthu

在处理大型DOCX文件转换为PDF时,可能会遇到性能问题,尤其是当文档页数非常多时。您提到的样本文档有4510页,且内容重复,这可能导致Aspose在处理时效率较低。

为了提高转换速度,您可以尝试以下几种方法:

  1. 限制转换的页面范围:您已经在代码中使用了PageSet来限制转换的页面范围。确保您只转换所需的页面(例如前10页),这可以显著减少处理时间。

  2. 优化PDF保存选项:在PdfSaveOptions中,您可以尝试调整一些设置以优化性能。例如,禁用某些不必要的功能,如嵌入所有字体或图像压缩等,可能会加快转换速度。

  3. 使用流式处理:如果您的文档非常大,考虑使用流式处理来逐步读取和转换文档,而不是一次性加载整个文档。

  4. 检查文档内容:确保文档中没有复杂的元素(如大量的图形、表格或嵌入对象),这些元素可能会影响转换速度。

以下是您可以尝试的代码示例,展示了如何设置PdfSaveOptions以优化性能:

private byte[] convertToPdf(Document document) throws Exception {
    try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
        PdfSaveOptions pdfOptions = new PdfSaveOptions();
        pdfOptions.setCompliance(PdfCompliance.PDF_17);
        pdfOptions.setPageSet(new PageSet(0, 10)); // 仅转换前10页
        pdfOptions.setEmbedFullFonts(false); // 禁用嵌入所有字体
        pdfOptions.setImageCompression(PdfImageCompression.JPEG); // 设置图像压缩
        document.save(bos, pdfOptions);
        return bos.toByteArray();
    }
}

通过这些调整,您可能会发现转换速度有所提升。如果问题仍然存在,建议您检查Aspose的文档或社区论坛,寻找其他用户的经验和建议。

@ztthu 默认情况下,Aspose.Words 在渲染文档时会为整个文档构建布局。您可以使用如下代码来中断构建文档布局。代码演示了如何在构建指定页面的布局后强制中断:

int pagesToRender = 10;
Document doc = new Document("C:\\Temp\\in.docx");
doc.getLayoutOptions().setCallback(new PageLayoutCallback(pagesToRender));
try
{
    doc.updatePageLayout();
}
catch (PageLimitReachedException ex)
{
    PdfSaveOptions opt = new PdfSaveOptions();
    opt.setPageSet(new PageSet(new PageRange(0, pagesToRender-1)));
    doc.save("C:\\Temp\\out.pdf", opt);
}
private static class PageLayoutCallback implements IPageLayoutCallback
{
    public PageLayoutCallback(int maxPageCount)
    {
        mMaxPageCount = maxPageCount;
    }
 
    @Override
    public void notify(PageLayoutCallbackArgs args) throws Exception {
        if (args.getEvent() == PageLayoutEvent.PART_REFLOW_STARTED &&
                args.getPageIndex() >= mMaxPageCount)
            throw new PageLimitReachedException();
    }
    
    private int mMaxPageCount;
}
private static class PageLimitReachedException extends Exception { }

上述代码在我这边大约需要10秒。

1 Like

非常感谢,很有用,从600s以上提升到了8s

@alexey.noskov
这个方案对目前转换前几页样本非常有效,我尝试在您的代码基础上增加了起始页和终止页,没有得到预想的效果提升,构建文档布局是必须按顺序从第一页开始吗?

@ztthu 您可能知道 MS Word 文档本质上是流动的,没有“页面”的概念。消费者应用程序会动态地将文档内容重新排版到页面中。因此,要构建文档中最后一页的页面布局,需要构建文档中所有先前页面的布局。

@alexey.noskov
多谢解答。还有个疑问,Office365在转换中间页时的速度明显快很多,只需要几秒,这是如何做到的呢?

@ztthu 很遗憾,我们没有关于在 Office365 内部处理文档的信息。