20 Feb 2012

Using iTextSharp to print Avery Labels PDF with ASP.NET MVC and C#

Tasked with printing labels nicely on Avery L7992 label sheets (or any other type of labels really) from a web application, I did the usual messing around with HTML + CSS in different browsers before deciding to start again and try using PDF generation as a means of getting more control. After a few hours, a bunch of googling, finding tips here and there, I got it to work.

To produce a PDF file, your best bet is to use an existing library. iTextSharp is a powerful PDF generation library for .NET (it's a port of the Java iText library). One downfall is a paucity of good free documentation (although Mike was very helpful: http://www.mikesdotnetting.com).

So, with a reference to itextsharp.dll and a couple of usings in the code (iTextSharp.text and  iTextSharp.text.pdf), this is basically all you need to generate PDF label sheets from your MVC Controller:


 
public ActionResult LabelsPdf()
{
	// Open a new PDF document

	const int pageMargin = 5;
	const int pageRows = 5;
	const int pageCols = 2;
	
	var doc = new Document();
	doc.SetMargins(pageMargin, pageMargin, pageMargin, pageMargin);
	var memoryStream = new MemoryStream();

	var pdfWriter = PdfWriter.GetInstance(doc, memoryStream);
	doc.Open();

	// Create the Label table

	PdfPTable table = new PdfPTable(pageCols);
	table.WidthPercentage = 100f;
	table.DefaultCell.Border = 0;

	var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, false);

	foreach (var Thing in YourCollectionOfThings)
	{
		#region Label Construction

		PdfPCell cell = new PdfPCell();
		cell.Border = 0;
		cell.FixedHeight = (doc.PageSize.Height - (pageMargin * 2)) / pageRows;
		cell.VerticalAlignment = Element.ALIGN_MIDDLE;

		var contents = new Paragraph();
		contents.Alignment = Element.ALIGN_CENTER;

		contents.Add(new Chunk(string.Format("Thing #{0}\n", Thing.ThingId), new Font(baseFont, 11f, Font.BOLD)));
		contents.Add(new Chunk(string.Format("Thing Name: {0}\n", Thing.Name), new Font(baseFont, 8f)));

		cell.AddElement(contents);
		table.AddCell(cell);

		#endregion
	}

	table.CompleteRow();
	doc.Add(table);

	// Close PDF document and send

	pdfWriter.CloseStream = false;
	doc.Close();
	memoryStream.Position = 0;
	
	return File(memoryStream, "application/pdf");
}

7 comments:

  1. Anonymous2:58 pm

    Thanks very match,thats help me a lot

    ReplyDelete
  2. Anonymous8:57 am

    Thank you..!!!

    ReplyDelete
  3. Anonymous4:10 pm

    Thanks for you contribution, it has been quite useful

    ReplyDelete
  4. Anonymous3:38 pm

    Hi, this has been very helpful, but it seems that no matter how I set the margins, the output always looks the same. I'm saving this output to a file, BTW. Any suggestions on this?

    ReplyDelete
  5. Great article! Do you know by any chance, how can i place text fields inside the cell, just like you did, but with an exact position? (x, y) ? I'm creating labels, and some fields need to be placed in different locations...
    Thanks!

    ReplyDelete
  6. Any thoughts on how to handle a gutter between the rows? ie Avery 5160 label

    ReplyDelete
  7. Anonymous4:32 pm

    I'm getting an File cannot be used as method error on the return File()line

    ReplyDelete

Comments are very welcome unless you're a spammer, in which case you should probably kill yourself.

If I helped you out today, you can buy me a beer below. Cheers!