Why iText?
How many times have you been asked to generate a report in an open file format such as PDF? iTextSharp a free C# PDF library ported from the Java-PDF Library iText, gives you a nice option.
IMPORTANT
Getting Started
The following example shows how to:
- Create a centered document header.
- Add a center-aligned image to the document.
- Add a center-aligned paragraph to the document.
- Add tabular formatted data to the document.
Steps 1 - 3
// create PDF and send to client
private void _write_stream() {
Document doc = new Document();
try {
/*
// DON'T DO THIS
using ( MemoryStream ms = new MemoryStream() ) {
// the object required to write to a (output) Stream
PdfWriter.GetInstance(doc, ms);
*/
// INSTEAD DO THIS TO SAVE IN-MEMORY COPY
PdfWriter writer = PdfWriter.GetInstance(doc, Response.OutputStream);
Phrase phrase = new Phrase(
DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") + " GMT",
new Font(Font.COURIER, 8)
);
doc.Open();
// create document's header; shows GMT time when PDF created.
// HeaderFooter class removed in iText 5.0.0;, we must write
// content to an **absolute** position on the document
Rectangle page = doc.PageSize;
PdfPTable head = new PdfPTable(1);
head.TotalWidth = page.Width;
PdfPCell c = new PdfPCell(phrase);
c.Border = Rectangle.NO_BORDER;
c.VerticalAlignment = Element.ALIGN_TOP;
c.HorizontalAlignment = Element.ALIGN_CENTER;
head.AddCell(c);
head.WriteSelectedRows(
// first/last row; -1 writes all rows
0, -1,
// left offset
0,
// ** bottom** yPos of the table
page.Height - doc.TopMargin + head.TotalHeight + 20,
writer.DirectContent
);
/*
*
* iText versions older than 5.0.0
*
// create document's header; shows GMT time when PDF created.
// set header [1] text [2] font style
HeaderFooter header = new HeaderFooter (phrase, false);
// top & bottom borders on by default
header.Border = Rectangle.NO_BORDER;
// center header
header.Alignment = 1;
// add header *before* opening document
doc.Header = header;
doc.Open();
*/
// add image to document
Image gif = Image.GetInstance(
Request.MapPath("~/image/kuujinbo2.gif")
);
gif.Alignment = Image.MIDDLE_ALIGN;
gif.ScalePercent(50f); // change it's size
doc.Add(gif);
// report "title"
Paragraph p = new Paragraph("US Presidents Born in " + _state);
p.Alignment = 1;
doc.Add(p);
// add tabular data
doc.Add( _state_table() );
// PRE iText 5.0.0
// doc.Add( _state_table_pre5() );
/*
* AGAIN DON'T DO THIS
Response.BinaryWrite( ms.ToArray() );
*/
}
catch { throw; }
finally { if (doc != null) doc.Close(); }
}
Creating a simple table is easy; query the database (database code omitted) and add each rowset to the table in the PDF:
Step 4
iText 5.0.0 and above
// add a table to the PDF document
private PdfPTable _state_table() {
string[] col = { "No.", "Name", "City" };
PdfPTable table = new PdfPTable(3);
table.WidthPercentage = 100;
table.SetWidths(new Single[] {1, 5, 4});
table.SpacingBefore = 10;
for (int i = 0; i < col.Length; ++i) {
PdfPCell cell = new PdfPCell(new Phrase(col[i]));
cell.BackgroundColor = new BaseColor(204, 204, 204);
table.AddCell(cell);
}
// !! database code omitted !!
// r.Read is the DbDataReader for whatever flavor
// of database you're connecting to; we're iterating
// over the results returned from the database and
// adding rows to the table in the PDF
while (r.Read()) {
table.AddCell(r["id"].ToString());
table.AddCell(r["name"].ToString());
table.AddCell(r["city"].ToString());
}
}
return table;
}
iText versions older than 5.0.0
// add a table to the PDF document
private Table _state_table() {
// the column headings
string[] col = {"No.", "Name", "City"};
Table table = new Table(3);
// set table style properties
table.BorderWidth = 1;
table.BorderColor = new Color(0, 0, 255);
table.Padding = 4;
table.Width = 100;
// set *column* widths
float[] widths = {.1f, .5f, .4f};
table.Widths = widths;
// create the *table* header row
for (int i = 0; i < col.Length; ++i) {
Cell cell = new Cell(col[i]);
cell.Header = true;
cell.BackgroundColor = new Color(204, 204, 204);
table.AddCell(cell);
}
table.EndHeaders();
// !! database code omitted !!
// r.Read is the DbDataReader for whatever flavor
// of database you're connecting to; we're iterating
// over the results returned from the database and
// adding rows to the table in the PDF
while (r.Read()) {
table.AddCell( r["id"].ToString() );
table.AddCell( r["name"].ToString() );
table.AddCell( r["city"].ToString() );
}
return table;
}
Notes
- The Java library uses getXXX and setXXX methods to do a lot of things, while the .NET port uses properties.
- The .NET documentation is a little lacking. For example, both the Java API and the tutorial specify
Image.MIDDLE to align an image in the middle of the document - I had to find out the hard way that you need Image.MIDDLE_ALIGN. So be prepared to dig in the package's source code!
- Didn't really want to use
ms.ToArray(), but couldn't figure out how to read/send the stream in chunks. (MemoryStream.CanRead returns false) 2007-06-05 update: Duh! After browsing through the mailing list I figured out how to save in-memory copying of the PDF: (1) replace the MemoryStream parameter to PdfWriter.GetInstance() with Response.OutputStream (second parameter), and (2) disable buffering to the client: Response.BufferOutput = false;.
And don't forget to set the correct Content-Type before you write the PDF to the client:
Response.ContentType = "application/pdf";
Response.AddHeader(
"Content-Disposition",
"attachment; filename=itext.pdf"
);
More kuujinbo.info iText examples
iText References