使用PDFSharp向已有PDF添加文本时遇重复键ArgumentException问题
PDFSharp DrawString 抛出 System.ArgumentException: "An item with the same key has already been added."
这个异常的核心原因是PDFSharp在管理字体资源字典时,尝试重复插入已存在的键——通常是你代码中使用的字体和原PDF中已嵌入的字体产生了冲突。针对你的场景,可尝试以下解决方案:
解决方案1:复用原PDF中的字体
如果不需要使用新字体,直接获取原PDF页面已有的字体来绘制文本,避免重复添加字体资源:
using PdfSharp.Pdf; using PdfSharp.Drawing; // 打开原PDF PdfDocument document = PdfReader.Open("原文件路径.pdf", PdfDocumentOpenMode.Modify); PdfPage page = document.Pages[0]; // 获取原页面的字体资源(假设原页面有文本,取第一个可用字体) XFont existingFont = null; var resources = page.Elements.GetDictionary("/Resources"); if (resources != null && resources.Elements.ContainsKey("/Font")) { var fontDict = resources.Elements.GetDictionary("/Font"); foreach (var key in fontDict.Elements.Keys) { var fontRef = fontDict.Elements.GetReference(key); var font = document.Internals.GetObject(fontRef.ObjectID) as PdfSharp.Pdf.Advanced.PdfFont; if (font != null) { existingFont = new XFont(font.FontName, 12, XFontStyle.Regular); break; } } } // 绘制文本 using (XGraphics gfx = XGraphics.FromPdfPage(page)) { if (existingFont != null) { gfx.DrawString("新增文本", existingFont, XBrushes.Black, new XPoint(100, 100)); } else { // 原PDF无字体时,使用默认字体 gfx.DrawString("新增文本", new XFont("Arial", 12, XFontStyle.Regular), XBrushes.Black, new XPoint(100, 100)); } } // 保存文档 document.Save("新文件路径.pdf");
解决方案2:使用私有字体集合隔离字体
创建独立的PrivateFontCollection来加载字体,避免和PDFSharp的全局字体池冲突:
using (var privateFonts = new System.Drawing.Text.PrivateFontCollection()) { // 加载系统字体文件(以Arial为例,替换为实际字体路径) privateFonts.AddFontFile(@"C:\Windows\Fonts\arial.ttf"); XFont font = new XFont(privateFonts.Families[0], 12, XFontStyle.Regular); using (XGraphics gfx = XGraphics.FromPdfPage(page)) { gfx.DrawString("新增文本", font, XBrushes.Black, new XPoint(100, 100)); } }
解决方案3:升级到稳定版PDFSharp
你使用的6.1.0 Preview 2是测试版本,可能存在未修复的字体资源管理bug。建议切换到PDFSharp的最新正式稳定版(比如6.0.x系列),很多预览版的问题会在正式版中修复。
解决方案4:预处理原PDF
如果原PDF的字体引用存在异常(比如重复的字体键),可以先用Adobe Acrobat或其他PDF工具重新保存原PDF,修复字体资源结构后再进行编辑。
补充说明
空PDF或仅含图形的PDF无字体资源,所以添加新字体时不会触发重复键冲突;而带文本的PDF已有字体条目,当PDFSharp尝试再次添加相同键的字体时就会抛出异常。
测试代码参考(用户提供)
using PdfSharp.Pdf; using PdfSharp.Drawing; class Program { static void Main(string[] args) { var doc = PdfReader.Open("test.pdf", PdfDocumentOpenMode.Modify); var page = doc.Pages[0]; using (var gfx = XGraphics.FromPdfPage(page)) { // 此行触发异常 gfx.DrawString("Test Text", new XFont("Arial", 12), XBrushes.Red, new XPoint(50, 50)); } doc.Save("output.pdf"); } }
报错堆栈参考(用户提供)
System.ArgumentException: An item with the same key has already been added. at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at PdfSharp.Pdf.Advanced.PdfResources.AddFont(PdfFont font) at PdfSharp.Drawing.XGraphicsPdfRenderer.ConvertFont(XFont font) at PdfSharp.Drawing.XGraphicsPdfRenderer.DrawString(String s, XFont font, XBrush brush, XPoint point, XStringFormat format) at PdfSharp.Drawing.XGraphics.DrawString(String s, XFont font, XBrush brush, XPoint point) at Program.Main(String[] args)
内容的提问来源于stack exchange,提问作者user20716902
相关产品推荐
相关产品推荐

