我創建了一個特殊的ViewResult類,您可以返回作爲行動的結果。
您可以在bitbucket上看到代碼(查看PdfFromHtmlResult類)。
那麼它基本上是:
- 渲染通過剃刀引擎視圖(或者其他註冊引擎)HTML
- 給HTML以iTextSharp的
- 回報PDF作爲的ViewResult (使用正確的mimetype等)。
我的ViewResult類的樣子:
public class PdfFromHtmlResult : ViewResult {
public override void ExecuteResult(ControllerContext context) {
if (context == null) {
throw new ArgumentNullException("context");
}
if (string.IsNullOrEmpty(this.ViewName)) {
this.ViewName = context.RouteData.GetRequiredString("action");
}
if (this.View == null) {
this.View = this.FindView(context).View;
}
// First get the html from the Html view
using (var writer = new StringWriter()) {
var vwContext = new ViewContext(context, this.View, this.ViewData, this.TempData, writer);
this.View.Render(vwContext, writer);
// Convert to pdf
var response = context.HttpContext.Response;
using (var pdfStream = new MemoryStream()) {
var pdfDoc = new Document();
var pdfWriter = PdfWriter.GetInstance(pdfDoc, pdfStream);
pdfDoc.Open();
using (var htmlRdr = new StringReader(writer.ToString())) {
var parsed = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(htmlRdr, null);
foreach (var parsedElement in parsed) {
pdfDoc.Add(parsedElement);
}
}
pdfDoc.Close();
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", this.ViewName + ".pdf");
byte[] pdfBytes = pdfStream.ToArray();
response.OutputStream.Write(pdfBytes, 0, pdfBytes.Length);
}
}
}
}
有了正確的擴展方法(見到位桶)等,在我的控制器代碼是一樣的東西:
public ActionResult MyPdf(int id) {
var myModel = findDataWithID(id);
// this assumes there is a MyPdf.cshtml/MyPdf.aspx as the view
return this.PdfFromHtml(myModel);
}
注 :您的方法不起作用,因爲您將檢索服務器上的Html,因此您將丟失存儲在客戶端上的所有Cookie(=會話信息)。
來源
2011-08-05 08:50:53
GvS
這樣的工作是否會使用Razor引擎創建的視圖? –
我沒有剃刀測試,但我也沒有參考剃刀。我期望ViewContext足夠智能,可以在需要時使用其他渲染器。 – GvS
好吧,我會給它一個鏡頭......我得到了一個編譯錯誤「不能隱式轉換iTextSharp.text.pdf.PdfWriter到System.IDisposable」在這兩行上:using(var pdfDoc = new Document() ) 使用(var pdfWriter = PdfWriter.GetInstance(pdfDoc,pdfStream)) –