开发者

damaged pdf using ITextSharp and mvc

I am trying to generate a pdf out of an MVC3 webpage. I've viewed all the usual tutorials, but as is often the case when one is in a hurry and doesn't really know what one is doing, I'm making a dog's breakfast of it.

When I click the action link on the view to generate the pdf, the file appears to be created, but when I try to open it, I get the ever so helpful message from Adobe Reader that "... the file is damaged and cannot be repaired".

Where have I gone wrong?

    public FileStreamResult PDFGenerator()
    {
        Stream fileStream = GeneratePDF();

        HttpContext.Response.AddHeader("content-disposition", "attachment; filename=form.pdf");

        return new FileStreamResult(fileStream, "application/pdf");
    }

    private Stream GeneratePDF()
    {
        MemoryStream ms = new MemoryStream();

        Document doc = new Document();
        PdfWriter writer = PdfWriter.GetInstance(doc, ms);
        d开发者_JAVA百科oc.Open();
        doc.Add(new Paragraph("Hello"));

        ms.Position = 0;
        ms.Flush();

        writer.Flush();

        return ms;
    }


You must close the document. Try like this:

public ActionResult PDFGenerator()
{
    var doc = new Document();
    using (var stream = new MemoryStream())
    {
        var writer = PdfWriter.GetInstance(doc, stream);
        doc.Open();
        doc.Add(new Paragraph("Hello"));
        doc.Close();
        return File(stream.ToArray(), "application/pdf", "test.pdf");
    }
}

But that's ugly. I would recommend you a more MVCish approach which consists in writing a custom ActionResult. As an additional advantage of this is that your controller actions will be more easier to unit test in isolation:

public class PdfResult : FileResult
{
    public PdfResult(): base("application/pdf")
    { } 

    public PdfResult(string contentType): base(contentType)
    { }

    protected override void WriteFile(HttpResponseBase response)
    {
        var cd = new ContentDisposition
        {
            Inline = false,
            FileName = "test.pdf"
        };
        response.AppendHeader("Content-Disposition", cd.ToString());

        var doc = new Document();
        var writer = PdfWriter.GetInstance(doc, response.OutputStream);
        doc.Open();
        doc.Add(new Paragraph("Hello"));
        doc.Close();
    }
}

and then in your controller action:

public ActionResult PDFGenerator()
{
    return new PdfResult();
}

Of course this can be taken a step further and have this PdfResult take a view model as constructor argument and generate the PDF based on some properties on this view model:

public ActionResult PDFGenerator()
{
    MyViewModel model = ...
    return new PdfResult(model);
}

Now things are beginning to look nice.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜