A Comparison between IronPDF & GrapeCity PDF Viewer

PDF stands for Portable Document Format. It is a file type that allows for the conventional viewing of any document on many different devices. PDFs are often used to share important documents such as resumes with potential employers, or invoices with clients.

Despite its popularity, there are also some disadvantages to using PDFs as a way of storing and sharing data. For instance, PDFs can't be shared over email as they need to be opened in a PDF reader first. Even if they could, PDFs would not look as clear as a Word document when opened on a phone. Additionally, PDFs can not be edited or updated like Word documents- unless you have editing software installed on your computer that can recognize the data in the file and convert it back to editable form. This means that PDF files can look the same when you open them up no matter what device you are using- be it a PC or a Mac. This makes PDF files reliable across all devices due to the familiar standard they implement that are not found in other document formats like JPEG or GIF.

In this article we will review two .NET PDF libraries:

  • IronPDF
  • GrapeCity PDF

IronPDF

IronPDF is a .NET library that provides building functions for creating, reading, and manipulating PDF documents with just a few lines of code. The following article will show you how to create PDF files with IronPDF. The content is based on the assumption that you have an understanding of the basics of Visual Studio or C#, and that you possess a working knowledge of HTML.

We need Visual Studio for writing, compiling, and running our application, C# for writing logic and code, and HTML for formatting PDF files, including adding titles, headings, images, paragraphs, etc. IronPDF library fully supports .NET Core, .NET 5, Framework, and Standard.

We can create a PDF file in C# with just a few lines of code. This is a straightforward task given basic knowledge of C# and HTML. Learn more about IronPDF with this link.

Installing IronPDF

Developing a solution requires the installation of the NuGet Package. Click "Project" directly from the Menu Bar. A drop-down list will appear. Select on Manage NuGet Packages from the drop-down menu and select it. A window like this will display:

Select the "Browse" tab, and the subsequent window like this will appear:

Type 'IronPdf' into the search box and press "Enter". The resultant window should appear:

Select IronPdf:

How To Create PDF File In C# By Ironpdfile

How To Create PDF File In C# By Ironpdfile

Select the 'Install' button. The resultant window will emerge after a successful installation:

Once you press the 'OK' button, you're ready to go.

Creating a PDF

Add the namespace IronPdf at the top of the file.

using IronPdf;
using IronPdf;
Imports IronPdf
VB   C#

The actual work starts from this point. We require a file path in order to store the constructed PDF document. To accomplish that, we use SaveFileDialog which prompts the user to choose a file name and file path.

private void Save_Click(object sender, EventArgs e)
{
    // Code to Select the folder and save the file.
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    saveFileDialog1.InitialDirectory = @"D:\";
    saveFileDialog1.Title = "Save Pdf File";
    saveFileDialog1.DefaultExt = "pdf";
    saveFileDialog1.Filter = "Pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
    saveFileDialog1.FilterIndex = 2;
    saveFileDialog1.RestoreDirectory = true;
    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
    {
        string filename = saveFileDialog1.FileName;
        // actual code that will create Pdf files
        var HtmlLine = new HtmlToPdf();
        HtmlLine.RenderHtmlAsPdf(PdfText.Text).SaveAs(filename);
        // MessageBox to display that file save
        MessageBox.Show("File Saved Successfully!");
    }
}
private void Save_Click(object sender, EventArgs e)
{
    // Code to Select the folder and save the file.
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    saveFileDialog1.InitialDirectory = @"D:\";
    saveFileDialog1.Title = "Save Pdf File";
    saveFileDialog1.DefaultExt = "pdf";
    saveFileDialog1.Filter = "Pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
    saveFileDialog1.FilterIndex = 2;
    saveFileDialog1.RestoreDirectory = true;
    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
    {
        string filename = saveFileDialog1.FileName;
        // actual code that will create Pdf files
        var HtmlLine = new HtmlToPdf();
        HtmlLine.RenderHtmlAsPdf(PdfText.Text).SaveAs(filename);
        // MessageBox to display that file save
        MessageBox.Show("File Saved Successfully!");
    }
}
Private Sub Save_Click(ByVal sender As Object, ByVal e As EventArgs)
	' Code to Select the folder and save the file.
	Dim saveFileDialog1 As New SaveFileDialog()
	saveFileDialog1.InitialDirectory = "D:\"
	saveFileDialog1.Title = "Save Pdf File"
	saveFileDialog1.DefaultExt = "pdf"
	saveFileDialog1.Filter = "Pdf files (*.pdf)|*.pdf|All files (*.*)|*.*"
	saveFileDialog1.FilterIndex = 2
	saveFileDialog1.RestoreDirectory = True
	If saveFileDialog1.ShowDialog() = DialogResult.OK Then
		Dim filename As String = saveFileDialog1.FileName
		' actual code that will create Pdf files
		Dim HtmlLine = New HtmlToPdf()
		HtmlLine.RenderHtmlAsPdf(PdfText.Text).SaveAs(filename)
		' MessageBox to display that file save
		MessageBox.Show("File Saved Successfully!")
	End If
End Sub
VB   C#

SaveFileDialog should open a file dialog that will allow you to select the folder and file name in the location where you want to construct a PDF document. The Initial Directory is set to D drive, but you can choose to set it to any. As we are only dealing with PDF files, Default Extension has been set to PDF files.

In the "if" condition, the actual code that will create the PDF file is inserted. Now we can see that we have managed to generate a PDF file with only two lines of code. PdfText is the name of a Rich Text box that contains the text that will be written in a PDF document. The filename is the file path and name which was selected via the SaveFileDialog method.

Reading PDFs

You might be thinking that code for reading PDF files will be complex and difficult to write/understand — but don’t worry — IronPDF has made it easier and simpler. This process on requires merely two lines of code to achieve!

Add the following code for importing the IronPdf library on the top of the file.

using IronPdf;
using System;
using System.Windows.Forms;
using IronPdf;
using System;
using System.Windows.Forms;
Imports IronPdf
Imports System
Imports System.Windows.Forms
VB   C#

Write the following code inside the function.

private void Read_Click(object sender, EventArgs e)
{
    PdfDocument PDF = PdfDocument.FromFile(FilePath.Text);
    FileContent.Text = PDF.ExtractAllText();
}
private void Read_Click(object sender, EventArgs e)
{
    PdfDocument PDF = PdfDocument.FromFile(FilePath.Text);
    FileContent.Text = PDF.ExtractAllText();
}
Private Sub Read_Click(ByVal sender As Object, ByVal e As EventArgs)
	Dim PDF As PdfDocument = PdfDocument.FromFile(FilePath.Text)
	FileContent.Text = PDF.ExtractAllText()
End Sub
VB   C#

This will extract all the information from the data source to the document viewer. All the reporting components will use that data as a data source.

GrapeCity PDF Features

GrapeCity Documents is a cross-platform document management system to provide a universal document, editor, and reader solution for all common document formats. Without needing an additional program like Adobe Acrobat, the rich library supplied by .NET Standard 2.0 may be used to read, generate, alter, and save PDF files. It has a robust feature set that lets developers build PDF files that include advanced font support, photos, graphics, barcodes, comments, outlines, stamps, watermarks, and more.

Manipulating PDFs

In .NET Standard apps, you may use GrapeCityPDF to produce PDF documents with basic or complicated business needs. Additionally, you may load, change, and save PDFs from any source.

Save PDF as Image

You can save a PDF as an image without sacrificing picture quality using GrapeCityPDF. Furthermore, you may use only a few lines of code to implement this functionality.

PDF Viewer

GrapeCity Documents PDF Viewer is a lightweight programming-based client-side viewer for viewing PDF files. Many of the usual PDF capabilities are supported.

Vast Amount of Features

The GrapeCityPDF library has numerous capabilities that enable you to create complicated PDF documents containing information such as text, graphics, photos, annotations, outlines, and more.

Installations

There are two methods to install GrapeCity.

  1. Select the download zipped source files button in order to download the current sample sources.
  2. Extract the files directly from the downloaded zip into a directory on your computer.
  3. Navigate to that directory.
  4. Execute the run.cmd batch file. This will build the sample sources. Start the SupportApi service and open the http://localhost:3003 URL in your default browser.
  5. For more info, see the readme.MD, included in the downloaded zip.

Installing the WinForms Edition

The topic below discusses the procedure of installing the WinForms Edition. The following steps provides the instructions to install the WinForms Edition:

  • Download the C1ControlPanel from https://www.grapecity.com/componentone to install the latest edition of WinForms.
  • Open the ControlPanel using ComponentOneC1ControlPanel.exe. Any running instances of Visual Studio must be closed.
  • An existing user can log in using the registered email address and password.
  • If you are a new user:
    • Register with Component One and create an account by filling in the required fields.
    • Verification will be sent to your email address.
    • Activate your email address by visiting the verification link.
    • If you do not want to log in or register, you can proceed as an anonymous user.
  • In the WinForms Edition tile, select Install. Installation of all editions can be achieved by selecting the checkbox against All Editions. Select the View More button to learn more about the Edition.
GrapeCity PDF Installation

  • Once you click Install, a page will display the License Agreement asking you to review it before clicking the Accept License Agreement button.
  • Once you accept the License Agreement, a consequent page will appear with the Settings and directory path change buttons. Select the Accept Settings prompt to verify the directory path and begin the installation process.
GrapeCity PDF Installation

  • The installer installs the controls and displays its progress as it does so. You will not be able to cancel the installation process while this screen is showing.
  • Once the controls are installed, "Installation Success" screen will display. The version currently installed will be displayed in the respective Edition.
  • The installer installs the controls and displays its progress as it does so. You will not be able to cancel the installation process while this screen is showing.
GrapeCity PDF Installation

  • Once the controls are installed, "Installation Success" screen will dispay. The version currently installed will be displayed in the respective Edition.
GrapeCity PDF Installation

Creating a PDF

using System;
using System.IO;
using System.Drawing;
using System.Text;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Common;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Structure;
using GrapeCity.Documents.Pdf.MarkedContent;
using GrapeCity.Documents.Pdf.Graphics;
using GrapeCity.Documents.Pdf.Annotations;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
namespace GcPdfWeb.Samples.Basics
{
    // This sample shows how to create a PDF/A-3u compliant document.
    public class PdfA
    {
        public void CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();
            var date = new DateTime(1961, 4, 12, 6, 7, 0, DateTimeKind.Utc);

            // Mark the document as PDF/A-3u conformant:
            doc.ConformanceLevel = PdfAConformanceLevel.PdfA3u;

            var fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arial.ttf"));
            var gap = 36;

            // PDF/A-3a requires all content to be tagged so create and populate StructElement when rendering:
            StructElement sePart = new StructElement("Part");
            doc.StructTreeRoot.Children.Add(sePart);

            TextLayout tl = null;
            // Add 3 pages with sample content tagged according to PDF/A rules:
            for (int pageNo = 1; pageNo <= 3; ++pageNo)
            {
                // add page
                var page = doc.Pages.Add();
                var g = page.Graphics;
                float y = 72;
                if (doc.Pages.Count == 1)
                {
                    // Create paragraph element:
                    var seParagraph = new StructElement("P") { DefaultPage = page };
                    // Add it to Part element:
                    sePart.Children.Add(seParagraph);

                    tl = g.CreateTextLayout();
                    tl.MarginAll = 72;
                    tl.MaxWidth = page.Size.Width;

                    tl.DefaultFormat.Font = fnt;
                    tl.DefaultFormat.FontBold = true;
                    tl.DefaultFormat.FontSize = 20;
                    tl.Append("PDF/A-3A Document");

                    // PerformLayout is done automatically in a new TextLayout or after a Clear():
                    //tl.PerformLayout(true);

                    // Draw TextLayout within tagged content:
                    g.BeginMarkedContent(new TagMcid("P", 0));
                    g.DrawTextLayout(tl, PointF.Empty);
                    g.EndMarkedContent();

                    y = tl.ContentRectangle.Bottom + gap;

                    seParagraph.ContentItems.Add(new McidContentItemLink(0));
                }

                // Add some sample paragraphs tagged according to PDF/A rules:
                for (int i = 1; i <= 3; ++i)
                {
                    // Create paragraph element:
                    var seParagraph = new StructElement("P") { DefaultPage = page };
                    // Add it to Part element:
                    sePart.Children.Add(seParagraph);

                    var sb = new StringBuilder();
                    sb.Append(string.Format("Paragraph {0} on page {1}: ", i, pageNo));
                    sb.Append(Common.Util.LoremIpsum(1, 2, 4, 5, 10));
                    var para = sb.ToString();

                    tl.Clear();
                    tl.DefaultFormat.FontSize = 14;
                    tl.DefaultFormat.FontBold = false;
                    tl.MarginTop = y;
                    tl.Append(para);

                    // Draw TextLayout within tagged content:
                    g.BeginMarkedContent(new TagMcid("P", i));
                    g.DrawTextLayout(tl, PointF.Empty);
                    g.EndMarkedContent();

                    y += tl.ContentHeight + gap;

                    // Add content item to paragraph StructElement:
                    seParagraph.ContentItems.Add(new McidContentItemLink(i));

                    // PDF/A-3 allows embedding files into document, but they should be associated with some document element
                    // add embedded file associated with seParagraph:
                    var ef1 = EmbeddedFileStream.FromBytes(doc, Encoding.UTF8.GetBytes(para));
                    // ModificationDate and MimeType should be specified in case of PDF/A:
                    ef1.ModificationDate = date;
                    ef1.MimeType = "text/plain";
                    var fn = string.Format("Page{0}_Paragraph{1}.txt", pageNo, i);
                    var fs1 = FileSpecification.FromEmbeddedStream(fn, ef1);
                    // UnicodeFile.FileName should be specified for PDF/A compliance:
                    fs1.UnicodeFile.FileName = fs1.File.FileName;
                    // Relationship should be specified in case of PDF/A:
                    fs1.Relationship = AFRelationship.Unspecified;
                    doc.EmbeddedFiles.Add(fn, fs1);
                    seParagraph.AssociatedFiles.Add(fs1);
                }
            }

            // PDF/A-3 allows transparency drawing in PDF file, add some:
            var gpage = doc.Pages[0].Graphics;
            gpage.FillRectangle(new RectangleF(20, 20, 200, 200), Color.FromArgb(40, Color.Red));

            // PDF/A-3 allows using FormXObjects, add one with transparency:
            var r = new RectangleF(0, 0, 144, 72);
            var fxo = new FormXObject(doc, r);
            var gfxo = fxo.Graphics;
            gfxo.FillRectangle(r, Color.FromArgb(40, Color.Violet));
            TextFormat tf = new TextFormat()
            {
                Font = fnt,
                FontSize = 16,
                ForeColor = Color.FromArgb(100, Color.Black),
            };
            gfxo.DrawString("FormXObject", tf, r, TextAlignment.Center, ParagraphAlignment.Center);
            gfxo.DrawRectangle(r, Color.Blue, 3);
            gpage.DrawForm(fxo, new RectangleF(300, 250, r.Width, r.Height), null, ImageAlign.ScaleImage);

            // PDF/A-3 allows using embedded files, but each embedded file must be associated with a document's element:
            EmbeddedFileStream ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "WordDocs", "ProcurementLetter.docx"));
            // ModificationDate and MimeType should be specified for EmbeddedFile in PDF/A:
            ef.ModificationDate = date;
            ef.MimeType = "application/msword";
            var fs = FileSpecification.FromEmbeddedFile(ef);
            fs.UnicodeFile.FileName = fs.File.FileName;
            fs.Relationship = AFRelationship.Unspecified;
            doc.EmbeddedFiles.Add("ProcurementLetter.docx", fs);
            // Associate embedded file with the document:
            doc.AssociatedFiles.Add(fs);

            // Add an attachment associated with an annotation:
            var sa = new StampAnnotation()
            {
                UserName = "Minerva",
                Font = fnt,
                Rect = new RectangleF(300, 36, 220, 72),
            };
            sa.Flags |= AnnotationFlags.Print;
            // Use a FormXObject to represent the stamp annotation:
            var stampFxo = new FormXObject(doc, new RectangleF(PointF.Empty, sa.Rect.Size));
            var gstampFxo = stampFxo.Graphics;
            gstampFxo.FillRectangle(stampFxo.Bounds, Color.FromArgb(40, Color.Green));
            gstampFxo.DrawString("Stamp Annotation\nassociated with minerva.jpg", tf, stampFxo.Bounds, TextAlignment.Center, ParagraphAlignment.Center);
            gstampFxo.DrawRectangle(stampFxo.Bounds, Color.Green, 3);
            //
            sa.AppearanceStreams.Normal.Default = stampFxo;
            doc.Pages[0].Annotations.Add(sa);
            ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "Images", "minerva.jpg"));
            ef.ModificationDate = date;
            ef.MimeType = "image/jpeg";
            fs = FileSpecification.FromEmbeddedFile(ef);
            fs.UnicodeFile.FileName = fs.File.FileName;
            fs.Relationship = AFRelationship.Unspecified;
            doc.EmbeddedFiles.Add("minerva.jpg", fs);
            sa.AssociatedFiles.Add(fs);

            // Mark the document as conforming to Tagged PDF conventions (required for PDF/A):
            doc.MarkInfo.Marked = true;

            // Metadata.CreatorTool and DocumentInfo.Creator should be the same for a PDF/A document:
            doc.Metadata.CreatorTool = doc.DocumentInfo.Creator;
            // A title should be specified for PDF/A document:
            doc.Metadata.Title = "GcPdf Document";
            doc.ViewerPreferences.DisplayDocTitle = true;

            // Done:
            doc.Save(stream);
        }
    }
}
using System;
using System.IO;
using System.Drawing;
using System.Text;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Common;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Structure;
using GrapeCity.Documents.Pdf.MarkedContent;
using GrapeCity.Documents.Pdf.Graphics;
using GrapeCity.Documents.Pdf.Annotations;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
namespace GcPdfWeb.Samples.Basics
{
    // This sample shows how to create a PDF/A-3u compliant document.
    public class PdfA
    {
        public void CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();
            var date = new DateTime(1961, 4, 12, 6, 7, 0, DateTimeKind.Utc);

            // Mark the document as PDF/A-3u conformant:
            doc.ConformanceLevel = PdfAConformanceLevel.PdfA3u;

            var fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arial.ttf"));
            var gap = 36;

            // PDF/A-3a requires all content to be tagged so create and populate StructElement when rendering:
            StructElement sePart = new StructElement("Part");
            doc.StructTreeRoot.Children.Add(sePart);

            TextLayout tl = null;
            // Add 3 pages with sample content tagged according to PDF/A rules:
            for (int pageNo = 1; pageNo <= 3; ++pageNo)
            {
                // add page
                var page = doc.Pages.Add();
                var g = page.Graphics;
                float y = 72;
                if (doc.Pages.Count == 1)
                {
                    // Create paragraph element:
                    var seParagraph = new StructElement("P") { DefaultPage = page };
                    // Add it to Part element:
                    sePart.Children.Add(seParagraph);

                    tl = g.CreateTextLayout();
                    tl.MarginAll = 72;
                    tl.MaxWidth = page.Size.Width;

                    tl.DefaultFormat.Font = fnt;
                    tl.DefaultFormat.FontBold = true;
                    tl.DefaultFormat.FontSize = 20;
                    tl.Append("PDF/A-3A Document");

                    // PerformLayout is done automatically in a new TextLayout or after a Clear():
                    //tl.PerformLayout(true);

                    // Draw TextLayout within tagged content:
                    g.BeginMarkedContent(new TagMcid("P", 0));
                    g.DrawTextLayout(tl, PointF.Empty);
                    g.EndMarkedContent();

                    y = tl.ContentRectangle.Bottom + gap;

                    seParagraph.ContentItems.Add(new McidContentItemLink(0));
                }

                // Add some sample paragraphs tagged according to PDF/A rules:
                for (int i = 1; i <= 3; ++i)
                {
                    // Create paragraph element:
                    var seParagraph = new StructElement("P") { DefaultPage = page };
                    // Add it to Part element:
                    sePart.Children.Add(seParagraph);

                    var sb = new StringBuilder();
                    sb.Append(string.Format("Paragraph {0} on page {1}: ", i, pageNo));
                    sb.Append(Common.Util.LoremIpsum(1, 2, 4, 5, 10));
                    var para = sb.ToString();

                    tl.Clear();
                    tl.DefaultFormat.FontSize = 14;
                    tl.DefaultFormat.FontBold = false;
                    tl.MarginTop = y;
                    tl.Append(para);

                    // Draw TextLayout within tagged content:
                    g.BeginMarkedContent(new TagMcid("P", i));
                    g.DrawTextLayout(tl, PointF.Empty);
                    g.EndMarkedContent();

                    y += tl.ContentHeight + gap;

                    // Add content item to paragraph StructElement:
                    seParagraph.ContentItems.Add(new McidContentItemLink(i));

                    // PDF/A-3 allows embedding files into document, but they should be associated with some document element
                    // add embedded file associated with seParagraph:
                    var ef1 = EmbeddedFileStream.FromBytes(doc, Encoding.UTF8.GetBytes(para));
                    // ModificationDate and MimeType should be specified in case of PDF/A:
                    ef1.ModificationDate = date;
                    ef1.MimeType = "text/plain";
                    var fn = string.Format("Page{0}_Paragraph{1}.txt", pageNo, i);
                    var fs1 = FileSpecification.FromEmbeddedStream(fn, ef1);
                    // UnicodeFile.FileName should be specified for PDF/A compliance:
                    fs1.UnicodeFile.FileName = fs1.File.FileName;
                    // Relationship should be specified in case of PDF/A:
                    fs1.Relationship = AFRelationship.Unspecified;
                    doc.EmbeddedFiles.Add(fn, fs1);
                    seParagraph.AssociatedFiles.Add(fs1);
                }
            }

            // PDF/A-3 allows transparency drawing in PDF file, add some:
            var gpage = doc.Pages[0].Graphics;
            gpage.FillRectangle(new RectangleF(20, 20, 200, 200), Color.FromArgb(40, Color.Red));

            // PDF/A-3 allows using FormXObjects, add one with transparency:
            var r = new RectangleF(0, 0, 144, 72);
            var fxo = new FormXObject(doc, r);
            var gfxo = fxo.Graphics;
            gfxo.FillRectangle(r, Color.FromArgb(40, Color.Violet));
            TextFormat tf = new TextFormat()
            {
                Font = fnt,
                FontSize = 16,
                ForeColor = Color.FromArgb(100, Color.Black),
            };
            gfxo.DrawString("FormXObject", tf, r, TextAlignment.Center, ParagraphAlignment.Center);
            gfxo.DrawRectangle(r, Color.Blue, 3);
            gpage.DrawForm(fxo, new RectangleF(300, 250, r.Width, r.Height), null, ImageAlign.ScaleImage);

            // PDF/A-3 allows using embedded files, but each embedded file must be associated with a document's element:
            EmbeddedFileStream ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "WordDocs", "ProcurementLetter.docx"));
            // ModificationDate and MimeType should be specified for EmbeddedFile in PDF/A:
            ef.ModificationDate = date;
            ef.MimeType = "application/msword";
            var fs = FileSpecification.FromEmbeddedFile(ef);
            fs.UnicodeFile.FileName = fs.File.FileName;
            fs.Relationship = AFRelationship.Unspecified;
            doc.EmbeddedFiles.Add("ProcurementLetter.docx", fs);
            // Associate embedded file with the document:
            doc.AssociatedFiles.Add(fs);

            // Add an attachment associated with an annotation:
            var sa = new StampAnnotation()
            {
                UserName = "Minerva",
                Font = fnt,
                Rect = new RectangleF(300, 36, 220, 72),
            };
            sa.Flags |= AnnotationFlags.Print;
            // Use a FormXObject to represent the stamp annotation:
            var stampFxo = new FormXObject(doc, new RectangleF(PointF.Empty, sa.Rect.Size));
            var gstampFxo = stampFxo.Graphics;
            gstampFxo.FillRectangle(stampFxo.Bounds, Color.FromArgb(40, Color.Green));
            gstampFxo.DrawString("Stamp Annotation\nassociated with minerva.jpg", tf, stampFxo.Bounds, TextAlignment.Center, ParagraphAlignment.Center);
            gstampFxo.DrawRectangle(stampFxo.Bounds, Color.Green, 3);
            //
            sa.AppearanceStreams.Normal.Default = stampFxo;
            doc.Pages[0].Annotations.Add(sa);
            ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "Images", "minerva.jpg"));
            ef.ModificationDate = date;
            ef.MimeType = "image/jpeg";
            fs = FileSpecification.FromEmbeddedFile(ef);
            fs.UnicodeFile.FileName = fs.File.FileName;
            fs.Relationship = AFRelationship.Unspecified;
            doc.EmbeddedFiles.Add("minerva.jpg", fs);
            sa.AssociatedFiles.Add(fs);

            // Mark the document as conforming to Tagged PDF conventions (required for PDF/A):
            doc.MarkInfo.Marked = true;

            // Metadata.CreatorTool and DocumentInfo.Creator should be the same for a PDF/A document:
            doc.Metadata.CreatorTool = doc.DocumentInfo.Creator;
            // A title should be specified for PDF/A document:
            doc.Metadata.Title = "GcPdf Document";
            doc.ViewerPreferences.DisplayDocTitle = true;

            // Done:
            doc.Save(stream);
        }
    }
}
Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Text
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Common
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.Structure
Imports GrapeCity.Documents.Pdf.MarkedContent
Imports GrapeCity.Documents.Pdf.Graphics
Imports GrapeCity.Documents.Pdf.Annotations
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing
Namespace GcPdfWeb.Samples.Basics
	' This sample shows how to create a PDF/A-3u compliant document.
	Public Class PdfA
		Public Sub CreatePDF(ByVal stream As Stream)
			Dim doc = New GcPdfDocument()
			Dim [date] = New DateTime(1961, 4, 12, 6, 7, 0, DateTimeKind.Utc)

			' Mark the document as PDF/A-3u conformant:
			doc.ConformanceLevel = PdfAConformanceLevel.PdfA3u

			Dim fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arial.ttf"))
			Dim gap = 36

			' PDF/A-3a requires all content to be tagged so create and populate StructElement when rendering:
			Dim sePart As New StructElement("Part")
			doc.StructTreeRoot.Children.Add(sePart)

			Dim tl As TextLayout = Nothing
			' Add 3 pages with sample content tagged according to PDF/A rules:
			For pageNo As Integer = 1 To 3
				' add page
				Dim page = doc.Pages.Add()
				Dim g = page.Graphics
				Dim y As Single = 72
				If doc.Pages.Count = 1 Then
					' Create paragraph element:
					Dim seParagraph = New StructElement("P") With {.DefaultPage = page}
					' Add it to Part element:
					sePart.Children.Add(seParagraph)

					tl = g.CreateTextLayout()
					tl.MarginAll = 72
					tl.MaxWidth = page.Size.Width

					tl.DefaultFormat.Font = fnt
					tl.DefaultFormat.FontBold = True
					tl.DefaultFormat.FontSize = 20
					tl.Append("PDF/A-3A Document")

					' PerformLayout is done automatically in a new TextLayout or after a Clear():
					'tl.PerformLayout(true);

					' Draw TextLayout within tagged content:
					g.BeginMarkedContent(New TagMcid("P", 0))
					g.DrawTextLayout(tl, PointF.Empty)
					g.EndMarkedContent()

					y = tl.ContentRectangle.Bottom + gap

					seParagraph.ContentItems.Add(New McidContentItemLink(0))
				End If

				' Add some sample paragraphs tagged according to PDF/A rules:
				For i As Integer = 1 To 3
					' Create paragraph element:
					Dim seParagraph = New StructElement("P") With {.DefaultPage = page}
					' Add it to Part element:
					sePart.Children.Add(seParagraph)

					Dim sb = New StringBuilder()
					sb.Append(String.Format("Paragraph {0} on page {1}: ", i, pageNo))
					sb.Append(Common.Util.LoremIpsum(1, 2, 4, 5, 10))
					Dim para = sb.ToString()

					tl.Clear()
					tl.DefaultFormat.FontSize = 14
					tl.DefaultFormat.FontBold = False
					tl.MarginTop = y
					tl.Append(para)

					' Draw TextLayout within tagged content:
					g.BeginMarkedContent(New TagMcid("P", i))
					g.DrawTextLayout(tl, PointF.Empty)
					g.EndMarkedContent()

					y += tl.ContentHeight + gap

					' Add content item to paragraph StructElement:
					seParagraph.ContentItems.Add(New McidContentItemLink(i))

					' PDF/A-3 allows embedding files into document, but they should be associated with some document element
					' add embedded file associated with seParagraph:
					Dim ef1 = EmbeddedFileStream.FromBytes(doc, Encoding.UTF8.GetBytes(para))
					' ModificationDate and MimeType should be specified in case of PDF/A:
					ef1.ModificationDate = [date]
					ef1.MimeType = "text/plain"
					Dim fn = String.Format("Page{0}_Paragraph{1}.txt", pageNo, i)
					Dim fs1 = FileSpecification.FromEmbeddedStream(fn, ef1)
					' UnicodeFile.FileName should be specified for PDF/A compliance:
					fs1.UnicodeFile.FileName = fs1.File.FileName
					' Relationship should be specified in case of PDF/A:
					fs1.Relationship = AFRelationship.Unspecified
					doc.EmbeddedFiles.Add(fn, fs1)
					seParagraph.AssociatedFiles.Add(fs1)
				Next i
			Next pageNo

			' PDF/A-3 allows transparency drawing in PDF file, add some:
			Dim gpage = doc.Pages(0).Graphics
			gpage.FillRectangle(New RectangleF(20, 20, 200, 200), Color.FromArgb(40, Color.Red))

			' PDF/A-3 allows using FormXObjects, add one with transparency:
			Dim r = New RectangleF(0, 0, 144, 72)
			Dim fxo = New FormXObject(doc, r)
			Dim gfxo = fxo.Graphics
			gfxo.FillRectangle(r, Color.FromArgb(40, Color.Violet))
			Dim tf As New TextFormat() With {
				.Font = fnt,
				.FontSize = 16,
				.ForeColor = Color.FromArgb(100, Color.Black)
			}
			gfxo.DrawString("FormXObject", tf, r, TextAlignment.Center, ParagraphAlignment.Center)
			gfxo.DrawRectangle(r, Color.Blue, 3)
			gpage.DrawForm(fxo, New RectangleF(300, 250, r.Width, r.Height), Nothing, ImageAlign.ScaleImage)

			' PDF/A-3 allows using embedded files, but each embedded file must be associated with a document's element:
			Dim ef As EmbeddedFileStream = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "WordDocs", "ProcurementLetter.docx"))
			' ModificationDate and MimeType should be specified for EmbeddedFile in PDF/A:
			ef.ModificationDate = [date]
			ef.MimeType = "application/msword"
			Dim fs = FileSpecification.FromEmbeddedFile(ef)
			fs.UnicodeFile.FileName = fs.File.FileName
			fs.Relationship = AFRelationship.Unspecified
			doc.EmbeddedFiles.Add("ProcurementLetter.docx", fs)
			' Associate embedded file with the document:
			doc.AssociatedFiles.Add(fs)

			' Add an attachment associated with an annotation:
			Dim sa = New StampAnnotation() With {
				.UserName = "Minerva",
				.Font = fnt,
				.Rect = New RectangleF(300, 36, 220, 72)
			}
			sa.Flags = sa.Flags Or AnnotationFlags.Print
			' Use a FormXObject to represent the stamp annotation:
			Dim stampFxo = New FormXObject(doc, New RectangleF(PointF.Empty, sa.Rect.Size))
			Dim gstampFxo = stampFxo.Graphics
			gstampFxo.FillRectangle(stampFxo.Bounds, Color.FromArgb(40, Color.Green))
			gstampFxo.DrawString("Stamp Annotation" & vbLf & "associated with minerva.jpg", tf, stampFxo.Bounds, TextAlignment.Center, ParagraphAlignment.Center)
			gstampFxo.DrawRectangle(stampFxo.Bounds, Color.Green, 3)
			'
			sa.AppearanceStreams.Normal.Default = stampFxo
			doc.Pages(0).Annotations.Add(sa)
			ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "Images", "minerva.jpg"))
			ef.ModificationDate = [date]
			ef.MimeType = "image/jpeg"
			fs = FileSpecification.FromEmbeddedFile(ef)
			fs.UnicodeFile.FileName = fs.File.FileName
			fs.Relationship = AFRelationship.Unspecified
			doc.EmbeddedFiles.Add("minerva.jpg", fs)
			sa.AssociatedFiles.Add(fs)

			' Mark the document as conforming to Tagged PDF conventions (required for PDF/A):
			doc.MarkInfo.Marked = True

			' Metadata.CreatorTool and DocumentInfo.Creator should be the same for a PDF/A document:
			doc.Metadata.CreatorTool = doc.DocumentInfo.Creator
			' A title should be specified for PDF/A document:
			doc.Metadata.Title = "GcPdf Document"
			doc.ViewerPreferences.DisplayDocTitle = True

			' Done:
			doc.Save(stream)
		End Sub
	End Class
End Namespace
VB   C#

GrapeCityPDF is not an advanced library for PDFs — it has a limited number of features compared to IronPDF.

IronPDF License Models and Pricing

The 30-Day Money-Back Guarantee: Once the license is purchased, you will receive a 30-day money-back guarantee. If the license is not well suited to your needs, IronPDF will guarantee your money back within 30 days.

Easy Integration: The integration of IronPDF alongside a working project and your environment is a seamless process completed using a single line of code. This can be achieved when integrating using the NuGet Package method or downloaded directly online and integrated into your environment.

Perpetual Licensing: Every license is purchased only once with no renewal requirements.

Free Support and Product Updates: Each license will come with round of house support directly from the team behind the product and also a year of free product updates. It is feasible to buy extensions at any point. Extensions can be viewed prior to purchase.

Immediate Licenses: As soon as payment is received, registered license keys are sent out.

All licenses are perpetual and apply to staging, development, and production.

The Lite Package

  • 1 Developer
  • 1 Location
  • 1 Project
  • Perpetual License

This package allows a single software developer in an organization to utilize Iron Software in one location. IronSoftware can be utilized in a single intranet application, web application, or desktop software program. It is prohibited to share licenses outside of an organization or an agency/client relationship as they are non-transferable. This license type, like all other license types, expressly excludes all rights not expressly granted under the Agreement without OEM redistribution and utilizing the Iron Software as SaaS without purchasing additional coverage.

Pricing: starts from $749 per year.

Professional License

  • 10 Developers
  • 10 Locations
  • 10 Projects
  • Perpetual License

This license allows a predetermined number of software developers in an organization to utilize Iron Software in numerous locations, with up to a maximum of ten. Iron Software can be used in as many websites, intranet applications, or desktop software applications as you like. Licenses are non-transferable, therefore is prohibited to be shared outside of an organization or an agency/client relationship. This license type, like all other license types, expressly excludes all rights not expressly granted under the Agreement, including OEM redistribution and utilizing the Iron Software as SaaS without purchasing additional coverage. This license can be integrated with a single project up to a maximum of 10.

Pricing: Starts from $999 per year.

Unlimited License

  • Unlimited Developers
  • Unlimited Locations
  • Unlimited Projects
  • Perpetual License

This enables you to have an unlimited number of software developers in a single organization to utilize Iron Software in an unlimited number of locations. Iron Software can be used in as many intranet applications, desktop software applications, or websites as you like. Licenses are non-transferable, and they cannot be shared outside of an organization or an agency/client relationship. This license type, like all other license types, expressly excludes all rights not granted under the Agreement, including OEM redistribution and utilizing the Iron Software as a SaaS without purchasing additional coverage.

Pricing: Starts from $ 2999 per year.

Royalty-Free Redistribution: This allows you to distribute the Iron Software as part of several differently packaged commercial products (without having to pay royalties) based on the number of projects covered by the base license. This will allow the deployment of Iron Software within SaaS software services, which is based on the number of projects covered by the base license.

Pricing: Starts from $ 1599 per year.

GrapeCity PDF Installation

GrapeCity PDF License Models and Pricing

Documents for PDF

  • Includes 1 Developer License
  • 1 Distribution Location

This package includes one developer license and only one distribution location with no support and maintenance.

Pricing: Starts from $999 per year.

Documents for PDF Unlimited

  • Includes 1 Developer License
  • Unlimited Distribution Locations

This package includes one developer license with unlimited distribution locations. It does not come with support and maintenance. GrapeCity does not support the SaaS and OEM.

Pricing: starts from $2799 per year.

Documents for PDF Team Unlimited

  • Includes 5 Developer Licenses
  • Unlimited Distribution Locations

This package includes five developer licenses with unlimited distribution locations with no support and maintenance. GrapeCity does not support SaaS and OEM.

Pricing: starts from $5799 per year.

Comparison of GrapeCity PDF Packages

The IronPDF Lite One-Developer package comes with 1-year support and costs around $749. While GrapeCity Documents for PDF, includes a One-Developer package and costs $999 without any support. The IronPDF Professional Package, includes the 10-developer package and comes with one year of support, costs $999. On the other hand, GrapeCity does not have a 10-developer package — with only a 5-developer package that costs $5799.

The IronPDF Lite and Professional packages have SaaS service or OEM, and a 5-year support option as well. The Lite one-developer package provides five years of support, SaaS, and OEM services which cost $2897 USD. While GrapeCity does not have a SaaS, OEM service, or a 5-year support option. The Iron Professional 10 developers package comes with 5-year support, Saas, and OEM services and costs $3397 USD. While GrapeCity does not have any 10 developers package.

Conclusion

GrapeCity Documents for PDF allows developers to export/import, create AcroForms (PDF Forms), and execute PDFs on numerous desktop applications. With GrapeCity Documents for PDF (GcPdf), you are on the way to providing complete PDF solutions to your customers.

We highly recommend IronPDF as the product offers greater accuracy. Competitors alike that perform similar functions, can encounter inaccurate issues such as failure to convert some images resulting in unknown characters. On the other hand, IronPDF provides accurate results.

IronPDF packages provide competitive licensing and support with no ongoing costs. IronPDF starts at $749 with packages including a greater range of features. GrapeCity PDF starts from $1649 per year. IronPDF also supports multiple platforms at a single price!

If you are not yet an IronPDF customer, you can access the free trial to check out all the available features. If you buy the complete Iron Suite, you can get all five products for the price of two. For further details regarding licensing, please follow this link to review the complete package information.