PdfSharp克隆页面:已添加具有相同键的项目

时间:2017-09-06 15:57:28

标签: c# pdf pdfsharp

我正在阅读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来说这是不够的。

如何成功克隆页面?

1 个答案:

答案 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设置为不显示预发行版本,但在这种情况下,它可能是我想要的选项。