C#: Create PDF Form (AcroForm) using PDFsharp
Asked Answered
M

1

9

How does one add a PDF Form element to a PDFsharp PdfPage object?

I understand that AcroForm is the best format for form-fillable PDF elements, but the PDFsharp library doesn't seem to allow you to create instances of the AcroForm objects.

I have been able to use PDFsharp to generate simple documents, as here:

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);
}

But I cannot work out how to add a fillable form element. I gather it would likely use the page.Elements.Add(string key, PdfItem item) method, but how do you make an AcroForm PdfItem? (As classes like PdfTextField do not seem to have a public constructor)

The PDFsharp forums and documentation have not helped with this, and the closest answer I found on Stack Overflow was this one, which is answering with the wrong library.

So, in short: How would I convert the "Hello World" text above into a text field?

Is it possible to do this in PDFsharp, or should I be using a different C# PDF library? (I would very much like to stick with free - and preferably open-source - libraries)

Mauretania answered 1/2, 2019 at 20:15 Comment(2)
I don't know that library. But it is plausible that it does not know how to create Annotations in general and form fields in particular. If everything fails, you may have to look at other libraries, such as for example iText.Ebonize
I would refer you to this question, which is the same as your's.Rna
C
6

Most of the classes constructors in PdfSharp are sealed which makes it kind of difficult to create new pdf objects. However, you can create objects using it's classes to add low-level pdf elements.

Below is an example of creating a text field.

Please refer to the pdf tech specs starting on page 432 on definition of key elements https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/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);
            }
        }

Congratulant answered 2/2, 2021 at 3:5 Comment(2)
This is basically the only way that one could add AcroForms to a PDF file using PdfSharp. Thank you @Congratulant for this example - it works really well! @Gebodal, please consider making this as the accepted answer. One tiny thing: I believe the top and bottom values need to be inverted (i.e., double bottom = 725; double top = 750;).Subatomic
I am trying to create a simple checkbox (True = ticked, False = empty) with this code snippet but I am pretty much stuck. Did anyone of you every implement such a checkbox and might share the code?Gunsmith

© 2022 - 2024 — McMap. All rights reserved.