I was recently asked if it was possible to add a print feature to a web site. But not the normal "print this page" link you see all the time on the web, this was printing address pulled from a database onto standard envelopes.
I mentally worked though a few possibilities with HTML and CSS, but decided that they might be too fragile. Plus when you print a HTML page, many browsers will put a header and footer on the printout by default. You can, of course, turn off headers and footers in the print setup options of your browser...but it's a bad idea to push that kind of responsibility onto your users if you can avoid it. Any good solution should be as simple as possible and certainly shouldn't ask the users to do something they have never had to do on any other web site.
I decided it would be simplest to create a PDF on the server side and send that to the user for printing. A PDF will print the same way every time. It will print the same in Firefox, IE, and Chrome. You can specify the page size of a PDF, which is important when you are printing onto envelopes. If you specify the PDF as a Landscape document, It's even easy to rotate text. Best of all, I won't have to worry that some strange CSS quirk will push the address halfway off the page when Chrome silently updates to a new version. I will admit that not everyone has a PDF reader installed, but in this particular case, I could count on that being present for everyone using the site.
Since this was a simple task, I thought that one of the open source PDF libraries would work fine. The site needed to work with .NET on Windows, so I checked out a few options and settled on PDF Sharp. Below you will find the proof of concept code that I put together. When the real solution is put together the addresses will be pulled from a database and each envelope will be printed in a loop. For the demo code though, this is sufficient to show that the approach works.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using PdfSharp.Drawing.Layout;
public partial class envelope_test : System.Web.UI.Page
{
protected PdfPage getNewPage()
{
PdfPage page = new PdfPage();
XUnit pdfWidth = new XUnit(4.125, XGraphicsUnit.Inch);
XUnit pdfHeight = new XUnit(9.5, XGraphicsUnit.Inch);
page.Height = pdfHeight;
page.Width = pdfWidth;
page.Orientation = PageOrientation.Landscape;
return page;
}
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
PdfDocument document = new PdfDocument();
PdfPage page = getNewPage();
document.AddPage(page);
XGraphics gfx = XGraphics.FromPdfPage(page);
// Create a font
XFont font = new XFont("Verdana", 12);
// Draw the text
double x = page.Width.Point / 3;
double y = page.Height.Point / 2;
gfx.DrawString(@"Al Crowley", font, XBrushes.Black, new XPoint(x,y));
gfx.DrawString(@"1 Oak Ave.", font, XBrushes.Black, new XPoint(x, y + 12 * 1.5));
gfx.DrawString(@"Marmora, NJ 08223", font, XBrushes.Black, new XPoint(x, y + 12 * 3));
page = getNewPage();
document.AddPage(page);
gfx = XGraphics.FromPdfPage(page);
gfx.DrawString(@"Joe Smith", font, XBrushes.Black, new XPoint(x, y));
gfx.DrawString(@"1 Fairview Drive", font, XBrushes.Black, new XPoint(x, y + 12 * 1.5));
gfx.DrawString(@"Marmora, NJ 08223", font, XBrushes.Black, new XPoint(x, y + 12 * 3));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
document.Save(ms);
Response.Clear();
Response.ContentType = "application/pdf";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(ms.ToArray());
Response.Flush();
ms.Close();
Response.End();
// For testing purposes, also save the file locally
document.Save(@"c:\temp\env.pdf");
}
}