Creating PDF documents dynamically using Umbraco and XSL-FO part 2
Posted
by
Vizioz Limited
on Vizioz Umbraco Blog
See other posts from Vizioz Umbraco Blog
or by Vizioz Limited
Published on 2010-11-15T13:24:00.000-08:00
Indexed on
2010/12/06
17:00 UTC
Read the original article
Hit count: 843
Umbraco CMS
|xsl-fo
|URL rewriting
|Dynamic PDF
|Umbraco Extension
|Umbraco Development
|xslt
The issue with the filenames comes down to the way that the PDF's are being generated by using an alternative template in Umbraco, this means that all you need to do is add " /pdf " to the end of a case study URL and it will create a PDF version of the case study. The down side is that your browser will merrily download the file and save it as PDF.PDF because that is the name of the last part of the URL.
What you need to do is set the content-disposition header to be equal to the name you would like the file use, Darren Ferguson mentioned this on the Change the name of the PDF forum post.
We have used the same technique for downloading dynamically generated excel files, so I thought it would be useful to create a small macro to set both this header and also to set the caching headers to prevent any caching issues, I think in the past we have experienced all possible issues, including various issues where IE behaves differently to other browsers when you are using SSL and so the below code should work in all situations!
The template for the PDF alternative template is very simple:
<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
<umbraco:Macro Alias="PDFHeaders" runat="server"></umbraco:Macro>
<umbraco:Macro xsl="FO-CaseStudy.xslt" Alias="PDFXSLFO" runat="server"></umbraco:Macro>
</asp:Content>
The following code snippet is the XSLT macro that simply creates our file name and then passes the file name into the helper function:
<xsl:template match="/">
<xsl:variable name="fileName">
<xsl:text>Vizioz_</xsl:text>
<xsl:value-of select="$currentPage/@nodeName" />
<xsl:text>_case_study.pdf</xsl:text>
</xsl:variable>
<xsl:value-of select="Vizioz.Helper:AddDocumentDownloadHeaders('application/pdf', $fileName)"/>
</xsl:template>
And the following code is the helper function that clears the current response and adds all the appropriate headers:
public static void AddDocumentDownloadHeaders(string contentType, string fileName)
{
HttpResponse response = HttpContext.Current.Response;
HttpRequest request = HttpContext.Current.Request;
response.Clear();
response.ClearHeaders();
if (request.IsSecureConnection & request.Browser.Browser == "IE")
{
// Don't use the caching headers if the browser is IE and it's a secure connection
// see: http://support.microsoft.com/kb/323308
}
else
{
// force not using the cache
response.AppendHeader("Cache-Control", "no-cache");
response.AppendHeader("Cache-Control", "private");
response.AppendHeader("Cache-Control", "no-store");
response.AppendHeader("Cache-Control", "must-revalidate");
response.AppendHeader("Cache-Control", "max-stale=0");
response.AppendHeader("Cache-Control", "post-check=0");
response.AppendHeader("Cache-Control", "pre-check=0");
response.AppendHeader("Pragma", "no-cache");
response.Cache.SetCacheability(HttpCacheability.NoCache);
response.Cache.SetNoStore();
response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
}
response.AppendHeader("Expires", DateTime.Now.AddMinutes(-1).ToLongDateString());
response.AppendHeader("Keep-Alive", "timeout=3, max=993");
response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + "\"");
response.ContentType = contentType;
}
I will write another blog soon with some more details about XSL-FO and how to create the PDF's dynamically.
Please do re-tweet if you find this interest :)
© Vizioz Umbraco Blog or respective owner