Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating PDF Tables using C# (.NET 2.0) and iTextSharp

0.00/5 (No votes)
23 Mar 2007 3  
Creating PDF Tables using C# (.NET 2.0) and iTextSharp
Screenshot - iTextSharpPdfTables.png

Introduction

The Tutorials on Creating PDF files using C# (.NET 2.0) and iTextSharp provide insights to a fairly wide variety of PDF files you can create. The focus of this article is on a relatively small, yet very interesting, subset of iTextSharp; the ability to create PDF files in which the data are presented in a table, like the one shown in the picture.

Complication

There are three challenges one faces, even with the narrow mission of creating a PDF Table.

1: The PDF Specification

One of the challenges in creating PDFs, of any kind and not just tabular data, is digesting its many options. These options are described in great detail in free documents available from Adobe, the owner of the PDF formats. (The latest version is over 1,300 pages long!) The picture below shows some of the more common ones.

    Application Screen Shot - Selection

2: iTextSharp Documentation

iTextSharp does a great deal to ease the burden of creating PDFs using C# (.NET 2.0). It largely obviates the need to understand all the minute details of the PDF specifications. However, despite the many examples available, creating non-trivial PDFs with iTextSharp can be bit of a steep climb. A recently released book, iText in Action by the author, is half as long as Adobe's latest specification document. The book is invaluable if you plan to seriously rely on iTextSharp, but you will still have to do some of the heavy lifting. You not only have to glean the concepts underlying Adobe's PDF specifications, but also figure out how iTextSharp is organized to address them. For example, the simple exercise of numbering pages requires you to create an event handler and then make sure you construct and write the appropriate string on the right canvas/layer.

Some additional useful links:

3: Vast variety of data and tables

Tabular data are stored in databases of all kinds (SQL Server, Oracle, Access, MySQL, etc.), in proprietary binaries, in spreadsheets, in text files (tab-delimited, XML), etc. So, no one solution, at least not a simple one like mine, will work for all. Put another way, until some bright soul comes along to save us, we will have to build our own solutions for each variant (of data source and PDF layout) we need to address.

Therefore ...

The net result of these complications is -- it may be useful to have working code that meets a few simple objectives

  • uses a simple but often used data source
  • has a simple UI to easily experiment with the many combinations of selections one can make while creating a PDF (see picture above)
  • contains code to illustrate one way of harnessing iTextSharp (recognizing that one will have to write a fair amount of code to address the various specific combinations of data sources and PDF layouts)

This article attempts to do just that.

WARNING:

Creating simple PDFs is easy once you grasp iTextSharp. But, creating useful, practical, decent-looking PDFs can be harder than it looks at first.

Solution

In its elemental form, tabular data looks like this:
    ReleaseDate Track Title Artist Album
    11/22/1968 29 Revolution 9 Beatles The Beatles [White Album]
    1960 6 Fools Rush In Frank Sinatra Nice 'N' Easy
    11/11/1971 1 One of These Days Pink Floyd Meddle
    1988 7 Where Is My Mind? Pixies Surfer Rosa
    5/1981 9 Can't Find My Mind Cramps Psychedelic Jungle
    6/10/2003 13 Scatterbrain. (As Dead As Leaves.) Radiohead Hail to the Thief
    6/30/1992 3 Dress P J Harvey Dry

Such a table can come from a database, spreadsheet, DataGridView, DataGrid, GridView, etc. It is simply a collections of rows of records and columns of fields.

As XML is widely understood and requires no special databases, this article uses two simple types of XML data sources to represent the data table shown above.

Plain Vanilla XML

In the XML shown below, each row (record) is represented in a single node called song and each column (field) in an attribute of the node.
Notice that there is only one level of nodes below the root, i.e., they do not have any child nodes.

<?xml version="1.0" encoding="utf-8"?>
<root>
  <song ReleaseDate="11/22/1968" Track="29" Title="Revolution 9" 
            Artist="Beatles" Album="The Beatles [White Album]" />
  <song ReleaseDate="1960" Track="6" Title="Fools Rush In" 
            Artist="Frank Sinatra" Album="Nice 'N' Easy" />
  <song ReleaseDate="11/11/1971" Track="1" Title="One of These Days" 
            Artist="Pink Floyd" Album="Meddle" />
  <song ReleaseDate="1988" Track="7" Title="Where Is My Mind?" 
            Artist="Pixies" Album="Surfer Rosa" />
  <song ReleaseDate="5/1981" Track="9" Title="Can't Find My Mind" 
            Artist="Cramps" Album="Psychedelic Jungle" />
  <song ReleaseDate="6/10/2003" Track="13" Title="Scatterbrain. (As Dead As Leaves.)" 
            Artist="Radiohead" Album="Hail to the Thief" />
  <song ReleaseDate="6/30/1992" Track="3" Title="Dress" 
            Artist="P J Harvey" Album="Dry" />
</root>

XmlStore

The XmlStore file shown below contains exactly the same data as the plain vanilla XML above, but with a few differences:

  • The root is named xmlStore
  • It has an additional node called schema
  • The schema has one field node for each attribute of the data row (record), e.g. song
  • Each field node contains information about
    • the name of the attribute of the data row (record)
    • the title displayed in a column header
    • the relative width of the displayed column
<?xml version="1.0" encoding="utf-8"?>
<xmlStore version="1.0">
  <schema datanodename="song">
    <field name="ReleaseDate" title="Release Date"  width="9"/>
    <field name="Track"       title="Track"         width="5"/>
    <field name="Title"       title="Title"         width="40"/>
    <field name="Artist"      title="Artist"        width="15"/>
    <field name="Album"       title="Album"         width="25"/>
  </schema>
  <song ReleaseDate="11/22/1968" Track="29" Title="Revolution 9" 
            Artist="Beatles" Album="The Beatles [White Album]" />
  <song ReleaseDate="1960" Track="6" Title="Fools Rush In" 
            Artist="Frank Sinatra" Album="Nice 'N' Easy" />
  <song ReleaseDate="11/11/1971" Track="1" Title="One of These Days" 
            Artist="Pink Floyd" Album="Meddle" />
  <song ReleaseDate="1988" Track="7" Title="Where Is My Mind?" 
            Artist="Pixies" Album="Surfer Rosa" />
  <song ReleaseDate="5/1981" Track="9" Title="Can't Find My Mind" 
            Artist="Cramps" Album="Psychedelic Jungle" />
  <song ReleaseDate="6/10/2003" Track="13" Title="Scatterbrain. (As Dead As Leaves.)" 
            Artist="Radiohead" Album="Hail to the Thief" />
  <song ReleaseDate="6/30/1992" Track="3" Title="Dress" 
            Artist="P J Harvey" Album="Dry" />
</xmlStore>

For more information on XmlStore see A utility to read, edit, encrypt, decrypt, write XmlStore files.

DISCLAIMER

I undertook this project to learn a few things about Visual Studio 2005, C#, XML, DataGridView, PDFs, etc. Caveat Emptor: Nothing has been properly or adequately tested. More important, there is a good chance, you or someone else can do this better. So, if you do use this code and cannot produce what you expect, there may be little I can do to help you. On the bright side, though, you have the source code and all the technical references in the world you will ever need from Adobe and the good people at iTextSharp.

This solution contains three examples from the iTextSharp tutorial web site two of which were not covered in my Tutorials on Creating PDF files using C# (.NET 2.0) and iTextSharp .

This solution also contains code that reflects my somewhat limited understanding of C#, iTextSharp and PDFs. It is merely a learning device and does not purport to be anything more.

IMPORTANT: The XML files in the project's Data folder were the only ones used to actually test the code. These are:

  • BogusData.xml -- which is an XML version of the data used in Chap 5 Example 18 of the iTextSharp tutorial
  • Passwords_NoSchema.xml -- which is from another XmlStore project
  • PlayList_Small.xml and PlayList.xml, also from the same project
There is no provision for other kinds of XML files. Most plain vanilla XMLs may work without new code. Chances are, however, you will not be able to create a PDF without modifying the code to accomodate other kinds XML files.

The file Watermark.jpg file came from the iTextSharp Tutorial web site.

Using the application

Be sure to read the DISCLAIMER above before you do anything.

Main Window

The solution contains a tab control with three tabs

  • Information displays
    • web pages and PDF's in response to Help menu requests
    • the XmlStore file used (via the Selections tab) to successfully generate a PDF Table
  • Selections displays the button to select an XmlStore (or a plain vanilla XML) file from which the PDF is generated. It also displays all the options shown in the picture above. These are described below.
  • Resulting PDF displays the PDF created based on your Selections.

The Selections tab

The Selections tab contains the facilities needed to create the desired PDF from an XML file. These are briefly described below.

XmlStore File ... button

Use this button to select an XmlStore or a plain vanilla XML file, like the ones shown above. The PDF file is generated immediately, based on the options you've selected (see picture below).

    Application Screen Shot - Selection

The options are described very briefly below. (For more detailed information, you will need to read the documentation provided by Adobe and iTextSharp, via the Help menu or some of the links above, or the recently released book by the creator of iText.)

PDF Document Summary

The information you provide in these four textboxes is embedded in the PDF:
  • Title
  • Subject
  • Author
  • Keywords
These are displayed along with other Document Properties by the Adobe PDF Reader.

Default button

It populates the various options with illustrative defaults.

Show ... options

These options only apply to how this solution generates a PDF Table.
  • Title if checked, displays the Title (from the PDF Document Summary above) in the top margin of every PDF page
  • Page Number if checked, displays the page number in the bottom margin of every PDF page
  • Watermark if checked, will display a watermark in the middle of every page
    • Text will display any word or phrase (such as "CONFIDENTIAL") at a 45 degrees angle
    • File will display the image file you've specified
  • Landscape if checked, will display all pages in landscape orientation
  • Paper Size determines the size of each page. Only three are supported in this solution, namely, Letter and Legal paper sizes used mostly in the US and the ISO A4 size, widely used in much of the rest of the world
  • Scale Factor: Column Widths (default = "1.0") is a multiplier that simply scales the column widths. By default, all the columns span the width of the page (leaving room for the margins). The table is always horizontally centered on each page. So, if you set the scale factor to "0.8", the resulting table will be 20% narrower as the column width of each column is reduced proportionately. Setting the scale factor to, say, "1.05", will widen the table and each column by 5%. (NOTE: If the XML file does not contain column width values, each column defaults to the same width.)

Font options

These options only apply to how this solution generates a PDF Table. They determine the fonts used for the data fields in the Body and each column Header of the table.
  • Type Face determines the names of the fonts used
  • Type Size determines the size (in Points) of the fonts
  • Type Style determines if the fonts are plain, bold, italicized, or both.

View ... options

These options only apply to how this solution generates a PDF Table. They specify your "viewing preferences", namely, how you want Adobe Reader to display the PDF when the file is first opened.
  • 2-Page Layout if checked, uses the PdfWriter.PageLayoutTwoColumnLeft otherwise uses the default value PdfWriter.PageLayoutSinglePage (See iTextSharp for details)
  • Tool bar determines if Adobe Reader displays its tool bar
  • Menu bar determines if Adobe Reader displays its menu bar
  • Window UI determines if Adobe Reader displays things like scroll bars, navigation controls, etc.
  • Resize to Fit Window determines if Adobe Reader should display the initial page "to fit" in its window
  • Center on Screen does just that, but only if the Adobe Reader is in a standalone browser; does not have any effect in this solution
  • Encrypt See the next section

Encrypt ... options

These options only apply to how this solution generates a PDF Table. They determine if the PDF file generated needs to be encrypted and/or contain embedded restrictions on the things a reader can do with your PDF when viewing it in an Adobe PDF Reader
  • Owner password, if provided, will encrypt the file
  • User password, if provided, will require the user to enter the password to open view the contents of the PDF
  • Print if unchecked, will prevent the user from printing the contents
  • Print Degraded if unchecked, will prevent the user from printing a degraded version of the PDF (see Adobe's documentation for details)
  • Modify Contents if unchecked, will prevent the user modifying the contents of the PDF (see Adobe's documentation for details)
  • Copy if unchecked, will prevent the user from copying the PDF (see Adobe's documentation for details)
  • Modify Annotations see Adobe's and/or iTextSharp's documentation for details
  • Fill In see Adobe's and/or iTextSharp's documentation for details
  • Screen Read see Adobe's and/or iTextSharp's documentation for details
  • Assemble see Adobe's and/or iTextSharp's documentation for details
  • Strong Encryption if unchecked, uses 40-bit encryption, if checked, uses 128-bit encryption. Both use the above passwords
BE SURE to see Adobe's and iTextSharp's documentation for details BEFORE you create a real encrypted PDF.

Help Menu

The Help menu contains links to two important sources of information:
  • iTextSharp Tutorial Home
  • Adobe PDF Specifications (various versions)

    Try them. You will see why they are very important, especially if you are determined to create your own PDFs.

    Using the code

    Be sure to read the DISCLAIMER above before you do anything.

    Prerequisite

    This solution was created using Visual Studio 2005 and before building the solution you need to use the VS2005 Project > Add Reference menu command to provide a Reference to iTextSharp.DLL version 4.x. If you don't have this, you can download just the DLL or the source [and build it yourself] using one of these links to SourceForge.net:

    Building the solution

    If you have Visual Studio 2005 then you should be able to use the project source code "out of the box" -- simply build and run. The code itself is not rocket science. It is reasonably documented. More important, you have access to a wealth of information on what the code does via valuable links in the Help menu. If you don't have Visual Studio 2005, you will have to ask a more experienced friend. (Don't ask me, as I am a newbie! I am also clueless about VB.NET!!)

    Code modules

    Side benefits of the code for newbies (like myself): The project includes modules with reasonably documented and self-explantory code. With luck, they may help you learn how to use a few features of the sub-systems employed. (Many of them are described elsewhere in the articles listed at the end.) Here the focus is only those related to creating PDFs using C#.

    VVX_PDF.cs

    VVX.PDF is a wrapper class used to translate the UI options described above and invoke the appropriate iTextSharp capabilities. It contains the following (each grouped in #region ... #endregion tags),

    • Enums
    • Member Variables
    • Properties to set/get values of the member variables
    • private Helper Methods
    • XmlStore methods contains the three important methods that represent the "guts" of this solution

      • DoCreateFromXmlStore(...) This relatively tiny method simply follows the iTextSharp steps 1 through 5. For step 4, however, it turns to the DoLoadDocument(...) method to extract the data from the XML file.

      • DoLoadDocument(...) This is an enhanced and customized version of the LoadDocument method found in Chap0518 and Chap 1202 of the iTextSharp tutorial. Although the code is reasonably documented, it may help you to visit the iTextShart Tutorial web site (perhaps via the Help menu of this solution) and read more about the code.

      • DoConfigPageEventHandler(...) This is a helper method that initializes the custom "new page" Event Handler you must write to implement the Show ... options, namely, Title, Page Numbers, and Watermarks, as well as painting the "gray" background for the column headers.

    VVX_PDF_TableEvents.cs

    VVX.PDF_TableEvents contains essentially a single class that contain the required [by iTextSharp] event handler. It is called after iTextSharp finishes composing each page of a PDF Table. In this class, you

    • keep track of page numbers
    • draw the title in the top margin
    • draw the page number in the bottom margin
    • ... or "decorate" your page and/or table in any way you wish

    iText

    If you want to learn more about iText, on which iTextSharp is based, click here.

    There are alternatives

    If iTextSharp is too difficult you might consider using one of several commercial PDF solutions, some of them are quite inexpensive. However, I haven't had much success with them. (The only place I have found creating PDFs is a breeze is on my iMac; creating PDFs on it from any application is a no-brainer! And you get beautiful PDFs, too.)

    Finally, a word of thanks to you

    I have learned a lot from people like you who have anonymously and freely shared your experiences with the world. Perhaps, you gave a little, but I learned a lot. If this utility helps even one person, you've made my day and given me a chance to give back to the community. So, thank you!

    Other recent contributions

  • "Tutorials on creating PDF files using C# (.NET 2.0) and iTextSharp". March 16, 2007
  • "A utility to read, edit, encrypt, decrypt, write XmlStore files". March 12, 2007
  • "XmlStore Part 2: Printing DataGridView Contents". March 18, 2007
  • "A simple utility to quickly create reflected versions of an image file (*.GIF, *.PNG, etc.)". March 6, 2007
  • "A simple utility to quickly create opaque or transparent image files (*.GIF, *.PNG, etc.)". March 5, 2007
  • If any of these have helped you ...

    Please consider sending in a donation to one of my favorite causes: Year Up or to any similar NGO (non-governmental organization) in the world that is selflessly doing good work and helping people in need. Give a little, get a lot!

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here