前兩篇是將外部的網頁轉為PDF
而這次要將專案內的頁面轉為PDF輸出
像是契約書、合約等等文件,可以利用Html建立樣板
再將資料帶入欄位中,最後將頁面轉成PDF檔
首先寫一個測試用的頁面
public ActionResult HtmlToPdf()
{
ViewData["test"] = "假裝打資料進入頁面";
return View("HtmlToPdf");
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<p>測試網頁:@ViewData["test"]</p>
<ul>
<li>你好</li>
<li>我是</li>
<li>Leon</li>
</ul>
<table border="1">
<tr>
<td>身高</td><td>180公分</td>
</tr>
<tr>
<td>體重</td><td>70公斤</td>
</tr>
</table>
</body>
</html>
再來主要的原理是
在產生報表的過程中,對目標網頁發送請求並取得回傳值
其實跟上一篇做的事差不多
但差別在這次的請求是透過Controller做處理
程式碼如下
public static byte[] GetPDFByActionResult(ActionResult ActionResult, ControllerContext ControllerContext)
{
//Html字串
string htmlString = string.Empty;
//建立StringBuilder,最後toString傳給htmlString
StringBuilder sb = new StringBuilder();
//利用StringWriter將response回傳的內容寫入StringBuilder
StringWriter sw = new StringWriter(sb);
//建立回應
HttpResponse tempResponse = new HttpResponse(sw);
//建立HttpContext,利用這次的Request內容對目標發送請求
HttpContext tempContext = new HttpContext(HttpContext.Current.Request, tempResponse);
//建立ControllerContext
ControllerContext tempControllerContext = new ControllerContext(
new HttpContextWrapper(tempContext), ControllerContext.RouteData, ControllerContext.Controller);
//先將真正的HttpContext暫存起來
HttpContext oldContext = HttpContext.Current;
//將目前的HttpContext設為tempContext
HttpContext.Current = tempContext;
//執行請求,取得回應並將內容帶入StringWriter
ActionResult.ExecuteResult(tempControllerContext);
//將HttpContext還原為真正的HttpContext
HttpContext.Current = oldContext;
//StringWriter內容寫入StringBuilder
sw.Flush();
//轉為字串
htmlString = sb.ToString();
//將html內引用JavaScript和CSS的路徑,取代為實體路徑
htmlString = htmlString.Replace("/Scripts/", AppDomain.CurrentDomain.BaseDirectory + "Scripts/");
htmlString = htmlString.Replace("/Content/", AppDomain.CurrentDomain.BaseDirectory + "Content/");
HtmlToPdfDocument document = new HtmlToPdfDocument();
//接續前兩篇的內容
return pdf;
}
Controller也要修改一下
//取得PDF
//byte[] pdf = PDFConverter.GetPDF("https://www.google.com.tw/")
byte[] pdf = PDFConverter.GetPDFByActionResult(HtmlToPdf(), this.ControllerContext);
//設定標頭
Response.AddHeader("Content-disposition", "attachment; filename=\"" + filename + "" + "\"");
//接續前兩篇的內容
執行結果