文本pdf阅读器极其缓慢打开



我有一些代码,结合了几页的acroforms(实际上是acrofields),然后在最后写一些JS到整个文档。

添加JS的函数中的PdfReader需要非常长的时间来实例化(对于1MB的文件大约需要12秒)。

下面是代码(非常简单):
public static byte[] AddJavascript(byte[] document, string js)
    {
        PdfReader reader = new PdfReader(new RandomAccessFileOrArray(document), null);
        MemoryStream msOutput = new MemoryStream();
        PdfStamper stamper = new PdfStamper(reader, msOutput);
        PdfWriter writer = stamper.Writer;
        writer.AddJavaScript(js);
        stamper.Close();
        reader.Close();
        byte[] withJS = msOutput.GetBuffer();
        return withJS;
    }

我对上面的代码进行了基准测试,慢的那行是第一条。我试过从文件而不是内存中读取它,并尝试使用MemoryStream而不是RandomAccessFileOrArray。没有什么比这更快了。

如果我将JS添加到单页文档中,它会非常快。所以我的想法是,结合页面的代码在某种程度上使PDF对PdfReader的阅读变慢。

下面是组合代码:

public static byte[] CombineFiles(List<byte[]> sourceFiles)
    {
        MemoryStream output = new MemoryStream();
        PdfCopyFields copier = new PdfCopyFields(output);
        try
        {
            output.Position = 0;
            foreach (var fileBytes in sourceFiles)
            {
                PdfReader fileReader = new PdfReader(fileBytes);
                copier.AddDocument(fileReader);
            }
        }
        catch (Exception exception)
        {
            //throw
        }
        finally
        {
            copier.Close();
        }
        byte[] concat = output.GetBuffer();
        return concat;
    }

我正在使用PdfCopyFields,因为我需要保留表单字段,因此不能使用PdfCopyPdfSmartCopy。这个组合代码非常快(几毫秒),并产生工作文档。上面的AddJS代码在它之后调用,PdfReader打开是较慢的部分。

任何想法?

(评论转化为回答)

MemoryStream上使用GetBuffer()偶尔会产生损坏的pdf。相反,ToArray()应该始终使用

如文档所述,PdfCopyFields确实很慢。然而,PdfCopyFields要么被弃用,要么即将被弃用,取而代之的是PdfCopy。沙箱中有两个示例展示了它是如何完成的:MergeForms(复制表单而不重命名字段)和MergeForms2(在重命名字段后复制表单)。这是MergeForms的样子:

Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
copy.setMergeFields();
document.open();
for (PdfReader reader : readers) {
    copy.addDocument(reader);
}
document.close();
for (PdfReader reader : readers) {
    reader.close();
}

请注意,您需要最新的iText版本来运行此代码。

最新更新