- ASP.NET MVC 2 Cookbook
- Andrew Siemer, Richard Kimber
- 734字
- 2025-03-31 05:30:56
We have spent quite a bit of time looking at all the various ways to render images and what we can do with those rendered images. It's time to turn away from image rendering and look at something perhaps equally useful. In this recipe, we will look at how we can generate a PDF from an action. We will specifically look at how to render an order summary. Obviously, you could take this in many directions!
There are a couple of things that we will need to do to get ready for this recipe. First of all, we are going to use the iTextSharp library (another project ported from the Java world). You can get this here: http://sourceforge.net/projects/itextsharp/. Make sure you download the 2.0 version. There is also a copy in the dependencies folder.
Then I am going to have you go fetch a helper class that will make working with iTextSharp way easier. The class we are going to use is called HtmlToPdfBuilder
and was created by "Hugo Bonacci". You can find it here http://somewebguy.wordpress.com/2009/05/08/itextsharp-simplify-your-html-to-pdf-creation/ or in the Models
folder of this recipe's code.
- Create a new ASP.NET MVC project.
- Add a new class to the
Models
folder calledPdfResult
. - Set your new
PdfResult
class to inherit fromActionResult
. Then create theExecuteResult
.PdfResult.cs:
public class PdfResult : ActionResult { public override void ExecuteResult(ControllerContext context) { } }
- Now we have somewhere to build a PDF. Inside the
ExecuteResult
method, we will piece together a PDF. First off, we need to create an instance ofHtmlToPdfBuilder
.HtmlToPdfBuilder builder = new HtmlToPdfBuilder(PageSize.LETTER);
- Now we can create an instance of
HtmlPdfPage
, which we will use to create one page in our PDF.HtmlPdfPage page1 = builder.AddPage();
- Using the instance of
HtmlPdfPage
, we can create a page by feeding in chunks of HTML. You can programmatically do this either one chunk at a time, or you can feed in one big blob of HTML. Both methods work!page1.AppendHtml("<p>Order #19807</p>"); page1.AppendHtml("<p>Andrew Siemer<br>"); page1.AppendHtml("4254 Some Street<br>"); page1.AppendHtml("Los Angeles, CA</p>"); page1.AppendHtml("<table><tr><td><b>Product</b></td><td><b>Price </b></td></tr>"); page1.AppendHtml("<tr><td>ASP.NET MVC Cookbook</td> <td>$40.00</td></tr></table>");
- From this point onwards, the code is very similar to rendering an image—in that we need to convert the PDF into an array of bytes to be pushed down to the browser. To convert the PDF into an array of bytes is a simple task though.
byte[] file = builder.RenderPdf();
- Now we need to set our buffer size, declare the content type of our response stream, and create the stream we intend to send to the requester.
HttpResponseBase response = context.HttpContext.Response; response.ContentType = "application/pdf"; MemoryStream pdfStream = new MemoryStream(file);
- Once we are set up to send our stream down to the client, we can iterate through chunks of the stream, and write them out to the requester in the response's output stream.
while (true) { int read = pdfStream.Read(buffer, 0, buffer.Length); if (read == 0) break; response.OutputStream.Write(buffer, 0, read); } response.End();
- Now that our
PdfResult
is built, we can go to our HomeController. In our HomeController we will create a new method namedGetPdf
. This action will be aPdfResult
. Because we coded our PDF generation directly in theActionResult
, all we need to do is declare the method.HomeController.cs:
public PdfResult GetPdf() { return new PdfResult(); }
- With our new action declared, we can move out to our "Index" view. In the view, we will simply create a link to the action, which will generate a PDF for us.
Index.aspx:
Click <%= Html.ActionLink("here","GetPdf", "Home") %> to get your order in PDF format!
- Now you can hit F5 and view your PDF.
In this recipe, we created a PDF using the iTextSharp
product. We were able to do it so easily because we used the HtmlToPdfBuilder
that Hugo Bonacci created. This class is an easy-to-use wrapper for a great but not so easy-to-use PDF generation tool.
Once we had the PDF, we converted it into an array of bytes. Once you have something converted into an array of bytes, streaming it down to the client that requested the resource is rather straightforward using the HTTP
response.