I did this through a httpmodule that checks for the querystring PrinterFriendly=True and when that is set on any page in SharePoint, it swaps out the masterpage for a printerfriendly one. Here's some of the code:
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(PrinterFriendlyMasterPage_PreRequestHandlerExecute);
}
void PrinterFriendlyMasterPage_PreRequestHandlerExecute(object sender, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page == null) return;
// If the request originates from a Publishing Page then we have to
// change the master page on the current Sharepoint Web instance object
// (of course we don't want to persist this change since it would
// change the master page permanently..for all users).
if (page is PublishingLayoutPage || page is TemplateRedirectionPage)
{
HttpContext context = HttpContext.Current;
if (ShouldOverrideMasterPage(context))
{
SPContext.Current.Web.MasterUrl = Utility.GetSetting("PrinterFriendlyMasterPage_MasterPageUrl");
SPContext.Current.Web.CustomMasterUrl = Utility.GetSetting("PrinterFriendlyMasterPage_MasterPageUrl");
page.Load += new EventHandler(application_page_Load);
}
}
else
{
// Now, if this is a normal wss 3.0 page hook into
// the PreInit event (just before the ordinary Page event
// cycle starts.
page.PreInit += new EventHandler(PrinterFriendlyMasterPage_PreInit);
}
}
void PrinterFriendlyMasterPage_PreInit(object sender, EventArgs e)
{
try
{
Page page = sender as Page;
if (page == null) return;
if (page.MasterPageFile == null) return;
HttpContext context = HttpContext.Current;
if (ShouldOverrideMasterPage(context))
{
page.MasterPageFile = Utility.GetSetting("PrinterFriendlyMasterPage_MasterPageUrl");
}
}
catch { }
}
private bool ShouldOverrideMasterPage(HttpContext context)
{
return GetQueryStringSwitch(context, Utility.GetSetting("PrinterFriendlyMasterPage_QueryString"));
}
private bool GetQueryStringSwitch(HttpContext context, string queryString)
{
try
{
if (!String.IsNullOrEmpty(context.Request.QueryString[queryString]) &&
Boolean.Parse(context.Request.QueryString[queryString]))
{
return true;
}
}
catch { }
return false;
}