You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用iText7 C#导入仅含注释(无表单域)的FDF/XFDF至PDF

问题描述

尝试使用iText7 C#将仅包含注释(无AcroForm表单域)的FDF/XFDF文档导入PDF,现有FDF和XFDF内容如下,自行编写的代码未能成功添加注释,求解决方案。

FDF文档内容

%FDF-1.2
%âãÏÓ
1 0 obj
<< /FDF << /Annots[2 0 R]/F(/C/Users/Desktop/Emptypdf.pdf)/ID[<> <>]/UF(/C/Users/Desktop/Emptypdf.pdf)>> /Type/Catalog >>
endobj
2 0 obj
<< /Author(SYSTEM)/C[0.0 0.72 0.92]/Contents(FA)/DA(0 G 0 0.72 0.92 rg 0 Tc 0 Tw 100 Tz 0 TL 0 Ts 0 Tr /Arial 12 Tf)/DS(font: Arial,sans-serif 12.0pt; text-align:left; color:#00B8EB )/F 4/M(D:20230829121640+05'30')/NM(FA in page 1)/Page 0/RC(<?xml version="1.0"?><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="Acrobat:23.3.0" xfa:spec="2.0.2" ><p dir="ltr"><span dir="ltr" style="font-size:12.0pt;text-align:left;color:#FF0000;font-weight:normal;font-style:normal">FA</span></p></body>)/Rect[10.0 565.44 55.7559 585.44]/Subj(Text Box)/Subtype/FreeText/Type/Annot >>
endobj
trailer
<< /Root 1 0 R >>
%%EOF

XFDF文档内容

<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"
><annots
><freetext color="#00B8EB" flags="print" date="D:20230829121640+05'30'" name="FA in page 1" page="0" rect="10.000000,565.440000,55.755900,585.440000" subject="Text Box"
><contents-richtext
><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:APIVersion="Acrobat:23.3.0" xfa:spec="2.0.2"
><p dir="ltr"
><span dir="ltr" style="font-size:12.0pt;text-align:left;color:#FF0000;font-weight:normal;font-style:normal"
>FA</span
></p
></body
></contents-richtext
><defaultappearance
>0 G 0 0.72 0.92 rg 0 Tc 0 Tw 100 Tz 0 TL 0 Ts 0 Tr /Arial 12 Tf</defaultappearance
><defaultstyle
>font: Arial,sans-serif 12.0pt; text-align:left; color:#00B8EB </defaultstyle
></freetext
></annots
><f href="Emptypdf_acrf.pdf"
/><ids original="F7F892FBFFEABF49A24F61F6C466DB21" modified="F7F892FBFFEABF49A24F61F6C466DB21"
/></xfdf
>

尝试的无效代码

// Replace with the paths to your PDF and FDF files
string pdfFilePath = "C:\\blankpage.pdf";
string fdfFilePath = "C:\\blankpage.xfdf";

using (PdfReader pdfReader = new PdfReader(pdfFilePath))
{
    using (FileStream fs = new FileStream(fdfFilePath, FileMode.Open, FileAccess.Read))
    {
        XmlDocument fdfDoc = new XmlDocument();
        
        fdfDoc.Load(fs);

        var nsmgr = new XmlNamespaceManager(fdfDoc.NameTable);
        nsmgr.AddNamespace("a", "http://ns.adobe.com/xfdf/");

        XmlNodeList commentNodes = fdfDoc.SelectNodes("//a:annots", nsmgr);
        foreach (XmlNode commentNode in commentNodes)
        {
            string annotationText = commentNode.InnerText;

            // Apply the annotationText to the PDF using iTextSharp
            PdfDictionary pageDict = pdfReader.GetPageN(1); // Change 1 to the page number you need

            PdfArray annotsArray = pageDict.GetAsArray(PdfName.ANNOTS);
            if (annotsArray == null)
            {
                annotsArray = new PdfArray();
                pageDict.Put(PdfName.ANNOTS, annotsArray);
            }

            PdfDictionary commentDict = new PdfDictionary();
            commentDict.Put(PdfName.TYPE, new PdfName("Annot"));
            commentDict.Put(PdfName.SUBTYPE, new PdfName("Text"));
            commentDict.Put(PdfName.CONTENTS, new PdfString(annotationText, PdfObject.TEXT_UNICODE));
            // Set other annotation properties here

            annotsArray.Add(commentDict);
        }

        using (FileStream outputPdfStream = new FileStream("C:\\output.pdf", FileMode.Create))
        {
            using (PdfStamper stamper = new PdfStamper(pdfReader, outputPdfStream))
            {
                stamper.Close();
            }

        }
    }
}
解决方案

你的代码存在几个核心问题:

  • 混用了iTextSharp(PdfStamper属于旧版本iTextSharp)和iText7的API,两者不兼容
  • 手动解析XFDF时仅提取了文本内容,遗漏了注释的位置、样式、类型等关键属性
  • 注释类型设置错误(你设置的是Text注释,但实际是FreeText注释)

使用iText7的内置工具可以直接完成FDF/XFDF注释的导入,无需手动解析XML,以下是正确的代码片段:

导入XFDF注释的代码

using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Annot;
using iText.Forms.Xfdf;

string pdfPath = "C:\\blankpage.pdf";
string xfdfPath = "C:\\blankpage.xfdf";
string outputPath = "C:\\output.pdf";

// 读取原始PDF
using (PdfReader reader = new PdfReader(pdfPath))
using (PdfWriter writer = new PdfWriter(outputPath))
using (PdfDocument pdfDoc = new PdfDocument(reader, writer))
{
    // 加载XFDF文档
    XfdfReader xfdfReader = new XfdfReader(xfdfPath);
    
    // 遍历XFDF中的所有注释
    foreach (XfdfAnnotation xfdfAnnot in xfdfReader.GetAnnotations())
    {
        // 将XFDF注释转换为iText7的PdfAnnotation对象
        PdfAnnotation pdfAnnot = xfdfAnnot.MakeAnnotation(pdfDoc);
        
        // 获取注释对应的页面(XFDF中page从0开始,iText7中从1开始)
        PdfPage page = pdfDoc.GetPage(xfdfAnnot.GetPageIndex() + 1);
        
        // 将注释添加到页面
        page.AddAnnotation(pdfAnnot);
    }
}

导入FDF注释的代码

如果使用的是FDF文件而非XFDF,代码类似,只需替换为FdfReader:

using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Annot;
using iText.Forms.Fdf;

string pdfPath = "C:\\blankpage.pdf";
string fdfPath = "C:\\blankpage.fdf";
string outputPath = "C:\\output.pdf";

using (PdfReader reader = new PdfReader(pdfPath))
using (PdfWriter writer = new PdfWriter(outputPath))
using (PdfDocument pdfDoc = new PdfDocument(reader, writer))
{
    using (FdfReader fdfReader = new FdfReader(fdfPath))
    {
        PdfDictionary fdfDict = fdfReader.GetFdfObject();
        PdfArray annotsArray = fdfDict.GetAsArray(PdfName.Annots);
        
        if (annotsArray != null)
        {
            foreach (var annotObj in annotsArray)
            {
                PdfDictionary annotDict = ((PdfIndirectReference)annotObj).GetRefersTo() as PdfDictionary;
                if (annotDict != null)
                {
                    // 获取页面索引(FDF中Page从0开始)
                    int pageIndex = annotDict.GetAsNumber(PdfName.Page).IntValue() + 1;
                    PdfPage page = pdfDoc.GetPage(pageIndex);
                    
                    // 创建PdfAnnotation并添加到页面
                    PdfAnnotation pdfAnnot = PdfAnnotation.MakeAnnotation(annotDict);
                    page.AddAnnotation(pdfAnnot);
                }
            }
        }
    }
}

关键说明

  • 确保引用正确的iText7 NuGet包:iText7.Core和iText7.Forms(处理FDF/XFDF需要Forms包)
  • 代码自动处理注释的所有属性(位置、颜色、字体、样式等),无需手动设置
  • 注意页面索引的转换:FDF/XFDF中页面从0开始计数,iText7的PdfDocument.GetPage()从1开始

内容的提问来源于stack exchange,提问作者Kothandaraman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:44:56