Lists with iTextSharp

Having already looked at how to create a PDF document with iTextSharp, set fonts and their styles and add text, this article turns its attention to lists. Ordered and unordered lists will be covered. You may want to review earlier articles in this series, if you haven't already done so.

Create PDFs in ASP.NET - getting started with iTextSharp
iTextSharp - Working with Fonts
iTextSharp - Adding Text with Chunks, Phrases and Paragraphs

Lists are generated from the iTextSharp.text.List object. A List is a collection of iTextSharp.text.ListItem objects. Actually, it is an ArrayList of ListItem objects. ListItem inherits from Paragraph (which inherits from Phrase, which inherits from ArrayList), so each item in the list is rendered on a new line. As with their html <ul> and <ol> counterparts, Lists can be UNORDERED or ORDERED (numbered). Diving straight into code, here's how to generate a List:

 

string path = Server.MapPath("PDFs");

it.Document doc = new it.Document();

try

{

    PdfWriter.GetInstance(doc, new FileStream(path + "/Lists.pdf", FileMode.Create));

    doc.Open();

    it.List list = new it.List(it.List.UNORDERED);

    list.Add(new it.ListItem("One"));

    list.Add("Two");

    list.Add("Three");

    list.Add("Four");

    list.Add("Five");

    it.Paragraph paragraph = new it.Paragraph();

    string text = "Lists";

    paragraph.Add(text);

    doc.Add(paragraph);

    doc.Add(list);

}

catch (it.DocumentException dex)

{

    Response.Write(dex.Message);

}

catch (IOException ioex)

{

    Response.Write(ioex.Message);

}

finally

{

    doc.Close();

}

 

If you are not familiar with the concept, the way that a List or ListItem is referenced in the above code needs explaining. As you can see, "it." is used as a prefix for some objects. If you are coding your PDF generation within an ASP.NET code-behind file, you will probably be working with the default set of namespaces that Visual Stuido references when the aspx.cs file is created. One of those namespaces is System.Web.UI.WebControls, which also includes a ListItem class. That means that attempting to simply add


ListItem li = new ListItem();

to your code will result in a warning of ambiguity. The way to resolve this is to fully reference the ListItem class you are attempting to use by adding its namespace:


iTextSharp.text.ListItem li = new iTextSharp.text.ListItem();

All that extra typing can get very boring, so you can shortcut the namespace by providing an alias to it:


using
it = iTextSharp.text;

Now you can use the alias instead.

Back to what the code actually does - the first thing is to create a new List object, and to pass in a bool to indicate whether it is an ordered, or numbered list or not. The default is false. The code doesn't do much more except add 5 items to the list. The first is added by creating a new ListItem object, and setting its string value. The second and subsequent items are added directly to the List object as strings. Finally, a Paragraph is created and added to the document, followed by the List being added to the document. The result is this:

As you can see, each item acts like a Paragraph as promised, in that it occupies a new line. You will also note that the default settings provide a boring list with hyphens as symbols for each ListItem, and none of the usual indentation that you would get if you were using Microsoft Word, for example. iTextSharp provides ways to format the List so that it looks a lot better.

 

it.List list = new it.List(it.List.UNORDERED, 10f);

list.SetListSymbol("\u2022");

list.IndentationLeft = 30f;

 

A second argument (float) is passed in to the List constructor, which sets the symbolIndent value at 10 points. This results in the space between the symbol and the item itself being increased. Secondly, the actual symbol is changed to the more traditional bullet point using the setListSymbol() method. Finally, the List is indented 30 points from the left margin of the document. The result looks a little more pleasing:

If you like your ordered lists with Roman numerals, you can use the RomanList class:


RomanList romanlist = new RomanList(true, 20);

romanlist.IndentationLeft = 30f;

romanlist.Add("One");

romanlist.Add("Two");

romanlist.Add("Three");

romanlist.Add("Four");

romanlist.Add("Five");

doc.Add(romanlist);

 

For some odd reason, the symbolIdent value passed into the constructor is an int this time, instead of a float. The first argument is a bool that tells iTextSharp whether you want lowercase symbols or not.

A separate GreekList class supplies list symbols as Greek letters, and two further classes: ZapfDingbatsList and ZapfDingbatsNumberList offer more symbol formatting opportunities as they make use of the ZapfDingBats font. The Greek and Roman lists should never be used for lists that contain more than 24 and 26 items respectively, and the ZapfDingBatsNumberList can only cope with a maximum of 10 items before the numbering runs out and becomes 0.

 

ZapfDingbatsList zlist = new it.ZapfDingbatsList(49, 15);

zlist.Add("One");

zlist.Add("Two");

zlist.Add("Three");

zlist.Add("Four");

zlist.Add("Five");

doc.Add(zlist);

 

Lists can also be nested. Since the List.Add() method accepts an object, all you need to do is to pass in a valid List() object. The following code creates a RomanList first, then an ordered list. The RomanList is added to the ordered list, and iTextSharp indents the RomanList relative to the ordered list to which it belongs:

 

RomanList romanlist = new RomanList(true, 20);

romanlist.IndentationLeft = 10f;

romanlist.Add("One");

romanlist.Add("Two");

romanlist.Add("Three");

romanlist.Add("Four");

romanlist.Add("Five");

 

List list = new List(List.ORDERED, 20f);

list.SetListSymbol("\u2022");

list.IndentationLeft = 20f;

list.Add("One");

list.Add("Two");

list.Add("Three");

list.Add("Roman List");

list.Add(romanlist);

list.Add("Four");

list.Add("Five");

 

doc.Add(paragraph);

doc.Add(list);

 

 

Date Posted: Monday, October 20, 2008 8:32 AM
Last Updated:
Posted by: Mikesdotnetting
Total Views to date: 74825

9 Comments

Friday, January 2, 2009 9:33 AM - NIKHIL

Nice code

Sunday, March 29, 2009 8:03 AM - Nameless

great code, but how about aligment of the list?

Sunday, March 29, 2009 9:54 AM - Mike

@Nameless

Aligning them with what? If you mean managing the indentation of list items, the article discusses that.

Thursday, April 2, 2009 7:48 AM - The Undertaker

How can I make the direction of the list from right to left. I have used PdfWriter.RUN_DIRECTION_RTL but it just align the text to the right side of the document and the bullets remain on the left side

Thursday, April 2, 2009 8:34 AM - Mike

@Undertaker

I believe that you can only set text to run from right to left if one of the following conditions are satisfied: the text is absolutely positioned; or the text appears in a table cell, ColumnText or MultiColumnText object.

If you click the iTextSharp link in the Categories list at the top of the page, you will find a couple of articles on tables and columns that should help.

Thursday, August 20, 2009 12:21 PM - MOHAN LAL

the code which is very fantastic..... i have solve a huge problem by using that.... thanks dud.....

Friday, April 9, 2010 4:40 PM - Sara Mendez

Cool stuff Mike, thanks!
But, how can I position the list somewhere on my document? Can I use it in a column? At the moment, I habe better results if I use a table, with 2 columns, one for the bullets and one for the text. So I can put the table wherever I want. Using lists would be maybe more elegant... what about absolute positoining?
thx and greetings from Vienna.

Wednesday, September 29, 2010 11:31 AM - Baskaran

Hi Mike, can you please tell how to add header and footer to each page. Also i need to know how to insert page numbers for each page.

thanks in advance

Thursday, July 10, 2014 6:54 PM - Scott

Thanks so much for these guides. Using them and other posts I've dug up, I've managed to produce very large pdfs rather quickly.

One problem I found with Lists was that KeepTogether did not work. I could solve that by loading the ListItem with a paragraph (having its own KeepTogether), but that somehow killed the bullet/number (using a Phrase kept the bullet, but that lacks KeepTogether). As such, I had to turn to tables for my solution. I was pleasantly surprised that tables did not add significantly to the document size (though it did seem to lose some speed).
Add your comment

If you have any comments to make about this article, please use this form to do so. Make sure that your comment relates specifically to the article above. More general comments can be posted through the form on the Contact page.

Please note, all comments are moderated, and some may not be published. The kind of things that will ensure your comment is deleted without ever seeing the light of day are as follows:

  • Not relevant to the article
  • Gratuitous links to your own site or product
  • Anything abusive or libellous
  • Spam
  • Anything in a language I don't understand including gibberish.

I do not pass email addresses on to spammers, so a valid one will assist me in responding to you personally if required.

Recent Comments

Gautam 11/20/2014 8:01 AM
In response to I'm Writing A Book On WebMatrix
Hello Mike, I read your book, loved it! However, I have a few request/suggestions: 1) an example...

Bret Dev 11/19/2014 8:39 PM
In response to The Difference Between @Helpers and @Functions In WebMatrix
Excellent post! One concern - where can you place global @Functions code within an MVC project to Is...

Rob Farquharson 11/19/2014 4:28 PM
In response to iTextSharp - Links and Bookmarks
How can I place text at an absolute position on the page? Also, how can I rotate text?...

Andy 11/17/2014 8:08 PM
In response to MVC 5 with EF 6 in Visual Basic - Sorting, Filtering and Paging
Hello I'm testing your sorting instructions above. This is great and I was able to get it to work...

Gautam 11/17/2014 5:51 PM
In response to WebMatrix - Database Helpers for IN Clauses
Hi Mike, I am very new to programming: In the above example if I want to use a delete button the...

donramon 11/17/2014 3:22 PM
In response to Entity Framework 6 Recipe - Alphabetical Paging In ASP.NET MVC
Congratulations on your new website look and the excellent articles. Thank you!...

Gautam 11/17/2014 11:26 AM
In response to Looking At The WebMatrix WebGrid
Hi Mike, I add the jquery script at the end of my html file.. when ajax attribute is added to the be...

Chet Ripley 11/15/2014 6:57 PM
In response to Adding A New Field
It appears the command is case sensitive. I had the same issue as Cameron. When I changed the to it...

Alvin 11/14/2014 12:49 PM
In response to Razor Web Pages E-Commerce - Adding A Shopping Cart To The Bakery Template Site
Great article Mike! When do you plan to extend the bakery shopping cart beyond this point?...

Gautam 11/14/2014 10:16 AM
In response to Web Pages - Efficient Paging Without The WebGrid
to get the count can we use only the below sql, why to join category and author table var sql =...