我正在阅读PDF并尝试复制我正在创建的PDF中的某些页面。但是,当我尝试保存创建的PDF时,臭名昭着的
会引发异常已添加具有相同键的项目
我在Pdf Document Save to stream method throwing exception(2010年的PdfSharp论坛)中发现了同样的错误,但未提及任何解决方案。并且SO c# PDFSharp - what's the point of Table.Clone?似乎是同一类问题(但我不知道如何将其应用于我的案例)
我的测试代码是: (注意使用Nuget的最新PdfSharp)
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
namespace TestError
{
public class TestCode
{
public void DupePages(string inFilePath, string outFilePath)
{
var inDoc = PdfReader.Open(inFilePath, PdfDocumentOpenMode.Import);
var outDoc = new PdfDocument();
outDoc.AddPage((PdfPage)inDoc.Pages[0].Clone());
outDoc.AddPage((PdfPage)inDoc.Pages[0].Clone());
outDoc.Save(outFilePath); // Exception thrown here
}
}
}
堆栈跟踪
System.ArgumentException occurred
HResult=0x80070057
Message=An item with the same key has already been added.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at PdfSharp.Pdf.PdfReferenceTable.Compact()
at PdfSharp.Pdf.PdfDocument.PrepareForSave()
at PdfSharp.Pdf.PdfDocument.DoSave(PdfWriter writer)
at PdfSharp.Pdf.PdfDocument.Save(Stream stream, Boolean closeStream)
at PdfSharp.Pdf.PdfDocument.Save(String path)
at TestError.TestCode.DupePages(String inFilePath, String outFilePath)
我已经检查过克隆操作正在返回不同的对象,但对于PdfSharp来说这是不够的。
如何成功克隆页面?
答案 0 :(得分:1)
我的原始代码使用PdfSharp Latest stable 1.32.3057
进行了测试。使用此版本时,如果我没有使用Clone
,那么AddPage
只会添加对该页面的引用而不会复制它。
但是,当User241.007提示转到Latest prerelease 1.5.4619-beta4c
版本时,情况发生了变化。不再抛出异常,但生成的文件不正确。在一个清晰的时刻,我稍微改变了代码,现在它按预期工作。
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
namespace TestError
{
public class TestCode
{
public void DupePages(string inFilePath, string outFilePath)
{
var inDoc = PdfReader.Open(inFilePath, PdfDocumentOpenMode.Import);
var outDoc = new PdfDocument();
var page = inDoc.Pages[0];
outDoc.AddPage(page);
page.Rotate = 0;
outDoc.AddPage(page);
outDoc.Save(outFilePath);
}
}
}
Rotate
的设置在我的案例中最终得到证明,该页面的独立副本已添加到outDoc
。当我查看结果时,两个页面具有不同的旋转(我正在测试的源PDF实际上具有初始旋转为90的页面)
通常我将Nuget设置为不显示预发行版本,但在这种情况下,它可能是我想要的选项。