我有一些代码,它结合了几页acro表单(带有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添加到单页文档中,则速度非常快。所以我的想法是,组合页面的代码以某种方式使得PdfReader
的PDF阅读速度变慢。
以下是合并代码:
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
open是缓慢的部分。
有什么想法吗?
答案 0 :(得分:2)
(评论转换为答案)
在GetBuffer()
上使用MemoryStream
偶尔会创建损坏的PDF。相反,ToArray()
应该 始终 。有关这方面的更多信息,请参见here。
答案 1 :(得分:1)
据记载,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版本来运行此代码。