C#: 使用PDFsharp创建PDF表单(AcroForm)

7

如何在 PDFsharp 的PdfPage对象中添加PDF表单元素?

我知道AcroForm是创建可填写表单的最佳格式,但是PDFsharp库似乎不允许您创建AcroForm对象的实例。

我已经成功使用PDFsharp生成简单的文档,例如:

static void Main(string[] args) {
    PdfDocument document = new PdfDocument();
    document.Info.Title = "Created with PDFsharp";

    // Create an empty page
    PdfPage page = document.AddPage();

    // Draw Text
    XGraphics gfx = XGraphics.FromPdfPage(page);
    XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
    gfx.DrawString("Hello, World!", font, XBrushes.Black,
        new XRect(0, 0, page.Width, page.Height), XStringFormats.Center);

    // Save document
    const string filename = "HelloWorld.pdf";
    document.Save(filename);
}

但是我无法弄清如何添加可填写表单元素。我了解它可能会使用page.Elements.Add(string key, PdfItem item)方法,但是如何制作AcroForm PdfItem?(因为像PdfTextField这样的类似物似乎没有公共构造函数)
PDFsharp论坛和文档对此没有帮助,而我在Stack Overflow上找到的最接近的答案是这个,它正在回答错误的库。
简而言之:我应该如何将上面的“Hello World”文本转换为文本字段?
在PDFsharp中是否可以实现此操作,还是应该使用不同的C# PDF库? (我非常希望使用免费的 - 最好是开源的 - 库)

我不熟悉那个库。但是很可能它不知道如何创建注释,特别是表单字段。如果一切都失败了,你可能需要查看其他库,例如iText。 - Max Wyss
我会参考这个问题(https://dev59.com/MoLba4cB1Zd3GeqPdFaE),它与你的问题相同。 - el-aasi
1个回答

4
大多数PdfSharp中的类构造函数都是密封的,这使得创建新的pdf对象有点困难。但是,您可以使用其类创建对象以添加低级pdf元素。
以下是创建文本字段的示例。
请参考第432页开始的pdf技术规格,了解关键元素的定义。 https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf
        public static void AddTextBox()
        {

            using (PdfDocument pdf = new PdfDocument())
            {
                PdfPage page1 = pdf.AddPage();

                double left = 50;
                double right = 200;
                double bottom = 750;
                double top = 725;

                PdfArray rect = new PdfArray(pdf);
                rect.Elements.Add(new PdfReal(left));
                rect.Elements.Add(new PdfReal(bottom));
                rect.Elements.Add(new PdfReal(right));
                rect.Elements.Add(new PdfReal(top));
                pdf.Internals.AddObject(rect);

                PdfDictionary form = new PdfDictionary(pdf);
                form.Elements.Add("/Filter", new PdfName("/FlateDecode"));
                form.Elements.Add("/Length", new PdfInteger(20));
                form.Elements.Add("/Subtype", new PdfName("/Form"));
                form.Elements.Add("/Type", new PdfName("/XObject"));
                pdf.Internals.AddObject(form);

                PdfDictionary appearanceStream = new PdfDictionary(pdf);
                appearanceStream.Elements.Add("/N", form);
                pdf.Internals.AddObject(appearanceStream);

                PdfDictionary textfield = new PdfDictionary(pdf);
                textfield.Elements.Add("/FT", new PdfName("/Tx"));
                textfield.Elements.Add("/Subtype", new PdfName("/Widget"));
                textfield.Elements.Add("/T", new PdfString("fldHelloWorld"));
                textfield.Elements.Add("/V", new PdfString("Hello World!"));
                textfield.Elements.Add("/Type", new PdfName("/Annot"));
                textfield.Elements.Add("/AP", appearanceStream);
                textfield.Elements.Add("/Rect", rect);
                textfield.Elements.Add("/P", page1);
                pdf.Internals.AddObject(textfield);

                PdfArray annotsArray = new PdfArray(pdf);
                annotsArray.Elements.Add(textfield);
                pdf.Internals.AddObject(annotsArray);

                page1.Elements.Add("/Annots", annotsArray);

                // draw rectangle around text field
                //XGraphics gfx = XGraphics.FromPdfPage(page1);
                //gfx.DrawRectangle(new XPen(XColors.DarkOrange, 2), left, 40, right, bottom - top);

                // Save document
                const string filename = @"C:\Downloads\HelloWorld.pdf";
                pdf.Save(filename);
                pdf.Close();

                Process.Start(filename);
            }
        }


这基本上是使用PdfSharp将AcroForms添加到PDF文件的唯一方法。感谢@reas提供的示例 - 它非常有效!@Gebodal,请考虑将其作为接受的答案。一个小细节:我认为需要倒转顶部和底部值(即 double bottom = 725; double top = 750;)。 - Yeseanul
我正在尝试使用这段代码创建一个简单的复选框(True = 打勾,False = 空),但我卡住了。你们中有没有人实现过这样的复选框并可以分享代码? - MichaelS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接