Print envelopes via a web site using ASP.NET and C#

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”);
    }
}

3 responses to “Print envelopes via a web site using ASP.NET and C#

  1. Thanks for the post. Is there a way to send this directly to the printer without ever viewing the envelope? In the case where it would be a loop, if it were a large number of addresses, it would be inconvenient to have to click print for every envelope.

  2. Sorry about my previous post. A coworker was running what I thought was this code, but it turned out to be similar but a little different from a different website. I didn’t notice you were creating multiple pages, which makes my comment about having to click print for every page stupid.
    However, I still have a question with it. When we click print, it is by default trying to print on an 8.5″ x 11″ paper from our default tray. Is there a way to have it automatically choose a different tray and be expecting to print on an envelope?
    Also, I would still like to know if it is possible to print an envelope directly to the printer without a preview. Even though there isn’t a problem of clicking print for multiple envelopes in one job, we would like to save our users the added step of clicking print in the viewer.

  3. Josh, from a web page there isn’t much you can do (that I know of) to influence the printer settings. All I can do from the server side is generate the PDF suitable for printing on envelopes. From there I hand it off to the user to hit print and get it directed to the right tray.
    If you really need full control of the print job I think you would need to write a native app on the client side, or maybe a Java applet if you get the permissions right.…but I’m not a Java person so take that bit with a grain of salt.

Comments are closed.