我有一些代码,结合了几页的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
,因为我需要保留表单字段,因此不能使用PdfCopy
或PdfSmartCopy
。这个组合代码非常快(几毫秒),并产生工作文档。上面的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版本来运行此代码。