我正在尝试从MVC3网页生成pdf。我已经查看了所有常用的教程,但是当人们匆忙并且不知道自己在做什么的时候经常会这样,我正在制作狗的早餐。
当我单击视图上的操作链接以生成pdf时,该文件似乎已创建,但是当我尝试打开它时,我从Adobe Reader获得了一条非常有用的消息:“...文件是损坏,无法修复“。
我哪里出错?
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);
doc.Open();
doc.Add(new Paragraph("Hello"));
ms.Position = 0;
ms.Flush();
writer.Flush();
return ms;
}
答案 0 :(得分:3)
您必须关闭文档。试试这样:
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");
}
}
但那很难看。我建议你更多MVCish方法,包括编写自定义ActionResult。另外一个优点是,您的控制器操作将更容易单独进行单元测试:
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();
}
}
然后在你的控制器动作中:
public ActionResult PDFGenerator()
{
return new PdfResult();
}
当然这可以更进一步,让PdfResult
将视图模型作为构造函数参数,并根据此视图模型的某些属性生成PDF:
public ActionResult PDFGenerator()
{
MyViewModel model = ...
return new PdfResult(model);
}
现在情况开始好看了。