單的 ASP.NET 頁面看上去就像普通的 HTML 頁面。
Hello RUNOOB.COM
在開始學習 ASP.NET 之前,我們先來構建一個簡單的 HTML 頁面,該頁面將在瀏覽器中顯示 "Hello RUNOOB.COM":
Hello RUNOOB.COM! |
用 HTML 編寫的 Hello RUNOOB.COM
下面的代碼將以 HTML 頁面的形式顯示實例:
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
</center>
</body>
</html>
如果您想親自嘗試一下,請保存上面的代碼到一個名為 "firstpage.htm" 的文件中,并創建一個到該文件的鏈接:firstpage.htm。
用 ASP.NET 編寫的 Hello RUNOOB.COM
轉換 HTML 頁面為 ASP.NET 頁面最簡單的方法是,直接復制一個 HTML 文件,并把新文件的擴展名改成 .aspx 。
下面的代碼將以 ASP.NET 頁面的形式顯示實例:
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
</center>
</body>
</html>
如果您想親自嘗試一下,請保存上面的代碼到一個名為 "firstpage.aspx" 的文件中,并創建一個到該文件的鏈接:firstpage.aspx。
它是如何工作的?
從根本上講,ASP.NET 頁面與 HTML 是完全相同的。
HTML 頁面的擴展名是 .htm。如果瀏覽器向服務器請求一個 HTML 頁面,服務器可以不進行任何修改,就直接發送頁面給瀏覽器。
ASP.NET 頁面的擴展名是 .aspx。如果瀏覽器向服務器請求個 ASP.NET 頁面,服務器在將結果發回給瀏覽器之前,需要先處理頁面中的可執行代碼。
上面的 ASP.NET 頁面不包含任何可執行的代碼,所以沒有執行任何東西。在下面的實例中,我們將添加一些可執行的代碼到頁面中,以便演示靜態 HTML 頁面和動態 ASP 頁面的不同之處。
經典 ASP
Active Server Pages (ASP) 已經流行很多年了。通過 ASP,可以在 HTML 頁面中放置可執行代碼。
之前的 ASP 版本(在 ASP.NET 之前)通常被稱為經典 ASP。
ASP.NET 不完全兼容經典 ASP,但是只需要經過少量的修改,大部分經典 ASP 頁面就可以作為 ASP.NET 頁面良好地運行。
如果您想學習更多關于經典 ASP 的知識,請訪問我們的 ASP 教程。
用經典 ASP 編寫的動態頁面
為了演示 ASP 是如何顯示包含動態內容的頁面,我們將向上面的實例中添加一些可執行的代碼(紅色字體標識):
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
<p><%Response.Write(now())%></p>
</center>
</body>
</html>
<% --%> 標簽內的代碼是在服務器上執行的。
Response.Write 是用來向 HTML 輸出流中寫東西的 ASP 代碼。
Now() 是一個返回服務器當前日期和時間的函數。
如果您想親自嘗試一下,請保存上面的代碼到一個名為 "dynpage.asp" 的文件中,并創建一個到該文件的鏈接:dynpage.asp。
用 ASP .NET 編寫的動態頁面
下面的代碼將以 ASP.NET 頁面的形式顯示實例:
<html>
<body bgcolor="yellow">
<center>
<h2>Hello RUNOOB.COM!</h2>
<p><%Response.Write(now())%></p>
</center>
</body>
</html>
如果您想親自嘗試一下,請保存上面的代碼到一個名為 "dynpage.aspx" 的文件中,并創建一個到該文件的鏈接:dynpage.aspx。
ASP.NET 對比經典 ASP
上面的實例無法演示 ASP.NET 與經典 ASP 之間任何的不同之處。
正如最后的兩個實例中,您看不出 ASP 頁面和 ASP.NET 頁面兩者之間的不同之處。
在下一章中,您將看到服務器控件是如何讓 ASP.NET 比經典 ASP 更強大的。
有的服務器控件都必須出現在 <form> 標簽中,<form> 標簽必須包含 runat="server" 屬性。
ASP.NET Web 表單
所有的服務器控件都必須出現在 <form> 標簽中,<form> 標簽必須包含 runat="server" 屬性。runat="server" 屬性表明該表單必須在服務器上進行處理。同時也表明了包含在它內部的控件可被服務器腳本訪問:
<form runat="server">
...HTML + server controls
</form>
注釋:該表單總是被提交到自身頁面。如果您指定了一個 action 屬性,它會被忽略。如果您省略了 metion 屬性,它將會默認設置 method="post"。同時,如果您沒有指定 name 和 id 屬性,它們會由 ASP.NET 自動分配。
注釋:一個 .aspx 頁面只能包含一個 <form runat="server"> 控件!
如果您在一個包含不帶有 name、method、action 或 id 屬性的表單的 .aspx 頁面中選擇查看源代碼,您會看到 ASP.NET 添加這些屬性到表單上了,如下所示:
<form name="_ctl0" method="post" action="page.aspx" id="_ctl0">
...some code
</form>
提交表單
表單通常通過點擊按鈕來提交。ASP.NET 中的 Button 服務器控件的格式如下:
<asp:Button id="id" text="label" OnClick="sub" runat="server" />
id 屬性為按鈕定義了一個唯一的名稱,text 屬性為按鈕分配了一個標簽。onClick 事件句柄規定了一個要執行的已命名的子例程。
在下面的實例中,我們在 .aspx 文件中聲明了一個 Button 控件。點擊按鈕運行改變按鈕上文本的子例程:
實例
個人需求,需要將html格式轉換成PDF并加上水印圖片。于是乎第一次接觸這種需求的小菜鳥博主我,在某度搜索引擎上不斷地查閱關鍵字資料、踩坑,終于有了一個相應的解決方案。以下是解決步驟,記錄下來方便以后的回顧,以及各位大神們的品鑒。
1、在 NuGet 搜索 itextsharp 關鍵字 下載以下截圖圈中的兩個包,一般下載完后項目會自動引用。
2、在項目文件中引入以下命名空間(建議下面提及的代碼封裝成類庫,方便項目間調用,個人取舍)
3、Html字符串轉pdf文件流,加水印圖片以及未加水印重載 精簡幫助類(由博主踩坑整理,僅完成個人業務需求)
1 /// <summary>
2 /// Html字符串轉PDF輸出幫助類
3 /// </summary>
4 public class HtmlToPdfHelper
5 {
6 #region HtmlToPDF
7
8 /// <summary>
9 /// 判斷是否有亂碼
10 /// </summary>
11 /// <param name="txt"></param>
12 /// <returns></returns>
13 private static bool IsMessyCode(string txt)
14 {
15 var bytes = Encoding.UTF8.GetBytes(txt);
16 for (var i = 0; i < bytes.Length; i++)
17 {
18 if (i < bytes.Length - 3)
19 if (bytes[i] == 239 && bytes[i + 1] == 191 && bytes[i + 2] == 189)
20 {
21 return true;
22 }
23 }
24 return false;
25 }
26
27 /// <summary>
28 /// 將Html字符串 輸出到PDF檔里
29 /// </summary>
30 /// <param name="htmlText"></param>
31 /// <returns></returns>
32 public static byte[] ConvertHtmlTextToPdf(string htmlText)
33 {
34 return ConvertHtmlTextToPdf(htmlText, "", 0, 0, 0, 0);
35 }
36
37 /// <summary>
38 /// 將Html字符串 輸出到PDF檔里,并添加水印
39 /// </summary>
40 /// <param name="htmlText">網頁代碼</param>
41 /// <param name="picPath">水印路徑</param>
42 /// <param name="left">距離左邊距離</param>
43 /// <param name="top">距頂部距離</param>
44 /// <param name="width">水印寬度</param>
45 /// <param name="height">水印高度</param>
46 /// <returns></returns>
47 public static byte[] ConvertHtmlTextToPdf(string htmlText, string picPath, int left, int top, int width, int height)
48 {
49 if (string.IsNullOrEmpty(htmlText))
50 {
51 return null;
52 }
53 //避免當htmlText無任何html tag標簽的純文字時,轉PDF時會掛掉,所以一律加上<p>標簽
54 htmlText = "<p>" + htmlText + "</p>";
55 MemoryStream outputStream = new MemoryStream();//要把PDF寫到哪個串流
56 byte[] data = Encoding.UTF8.GetBytes(htmlText);//字串轉成byte[]
57 MemoryStream msInput = new MemoryStream(data);
58 Document doc = new Document();//要寫PDF的文件,建構子沒填的話預設直式A4
59 PdfWriter writer = PdfWriter.GetInstance(doc, outputStream);
60 //指定文件預設開檔時的縮放為100%
61 PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
62 //開啟Document文件
63 doc.Open();
64
65 //寫入水印圖片
66 if (!string.IsNullOrEmpty(picPath))
67 {
68 Image img = Image.GetInstance(picPath);
69 //設置圖片的位置
70 img.SetAbsolutePosition(width + left, (doc.PageSize.Height - height) - top);
71 //設置圖片的大小
72 img.ScaleAbsolute(width, height);
73 doc.Add(img);
74 }
75 try
76 {
77 //使用XMLWorkerHelper把Html parse到PDF檔里
79 XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8);
80 //將pdfDest設定的資料寫到PDF檔
81 PdfAction action = PdfAction.GotoLocalPage(1, pdfDest, writer);
82 writer.SetOpenAction(action);
83 }
84 catch (Exception)
85 {
86 return null;
87 }
88 doc.Close();
89 msInput.Close();
90 outputStream.Close();
91 //回傳PDF檔案
92 return outputStream.ToArray();
94 }
95
96 #endregion
97
98 }
4、獲取網頁字符串的方法
1 /// <summary>
2 /// 獲取網站內容,包含了 HTML+CSS+JS
3 /// </summary>
4 /// <returns>String返回網頁信息</returns>
5 public static string GetWebContent(string inpath)
6 {
7 try
8 {
9 WebClient myWebClient = new WebClient();
10 //獲取或設置用于向Internet資源的請求進行身份驗證的網絡憑據
11 myWebClient.Credentials = CredentialCache.DefaultCredentials;
12 //從指定網站下載數據
13 Byte[] pageData = myWebClient.DownloadData(inpath);
14 //如果獲取網站頁面采用的是GB2312,則使用這句
15 string pageHtml = Encoding.UTF8.GetString(pageData);
16 bool isBool = IsMessyCode(pageHtml);//判斷使用哪種編碼 讀取網頁信息
17 if (!isBool)
18 {
19 string pageHtml1 = Encoding.UTF8.GetString(pageData);
20 pageHtml = pageHtml1;
21 }
22 else
23 {
24 string pageHtml2 = Encoding.Default.GetString(pageData);
25 pageHtml = pageHtml2;
26 }
27 return pageHtml;
28 }
29 catch (WebException webEx)
30 {
31 return webEx.Message;
32 }
33 }
5、MVC設計模式下獲取控制器視圖Html方法,很XX的一個問題就是只能獲取調用此方法的控制器下所有視圖,不能跨控制器獲取視圖,有待優化
1 /// <summary>
2 /// 獲取MVC視圖Html
3 /// </summary>
4 /// <param name="context">控制器上下文</param>
5 /// <param name="viewName">視圖名稱</param>
6 /// <param name="param"></param>
7 /// <returns></returns>
8 public static string GetViewHtml(ControllerContext context, string viewName)
9 {
10 if (string.IsNullOrEmpty(viewName))
11 viewName = context.RouteData.GetRequiredString("action");
12 using (var sw = new StringWriter())
13 {
14 ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
15 var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw);
16 try
17 {
18 viewResult.View.Render(viewContext, sw);
19 }
20 catch (Exception ex)
21 {
22 throw;
23 }
24
25 return sw.GetStringBuilder().ToString();
26 }
27 }
6、將pdf流輸出至客戶瀏覽器下載方法
1 /// <summary>
2 /// 將pdf文件流輸出至瀏覽器下載
3 /// </summary>
4 /// <param name="pdfFile">PDF文件流</param>
5 public static void PdfDownload(byte[] pdfFile)
6 {
7 byte[] buffer = pdfFile;
8 Stream iStream = new MemoryStream(buffer);
9 try
10 {
11 int length;
12 long dataToRead;
13 string filename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";//保存的文件名稱
14 dataToRead = iStream.Length;
15 HttpContext.Current.Response.Clear();
16 HttpContext.Current.Response.ClearHeaders();
17 HttpContext.Current.Response.ClearContent();
18 HttpContext.Current.Response.ContentType = "application/pdf"; //文件類型
19 HttpContext.Current.Response.AddHeader("Content-Length", dataToRead.ToString());//添加文件長度,進而顯示進度
20 HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(filename, Encoding.UTF8));
21 while (dataToRead > 0)
22 {
23 if (HttpContext.Current.Response.IsClientConnected)
24 {
25 length = buffer.Length;
26 HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);
27 HttpContext.Current.Response.Flush();
28 buffer = new Byte[length];
29 dataToRead = dataToRead - length;
30 }
31 else
32 {
33 dataToRead = -1;
34 }
35 }
36 }
37 catch (Exception ex)
38 {
39 HttpContext.Current.Response.Write("文件下載時出現錯誤!");
40 }
41 finally
42 {
43 if (iStream != null)
44 {
45 iStream.Close();
46 }
47 //結束響應,否則將導致網頁內容被輸出到文件,進而文件無法打開
48 HttpContext.Current.Response.Flush();
49 HttpContext.Current.Response.End();
50
51 }
52 }
7、MVC控制器下調用Demo(步驟4、6 方法封裝至幫助類)
1 public class HomeController : Controller
2 {
3 //
4 // GET: /Home/
5
6 public ActionResult Index()
7 {
8 //從網址下載Html字符串(方法一)
9 string inpath = System.Web.HttpContext.Current.Server.MapPath("~/PDFTemplate/test.html");
10 string htmlText = HtmlToPdfHelper.GetWebContent(inpath);//此處調用步驟4方法
11
12 //獲取MVC視圖Html字符串(方法二)
13 //string htmlText = GetViewHtml(ControllerContext, "Test");//此處調用步驟5方法
14
15 //水印圖片路徑
16 string picPath = Server.MapPath("~/PDFTemplate/TemplateImg/authentication-iocn.png");
17 //html轉pdf并加上水印
18 byte[] pdfFile = HtmlToPdfHelper.ConvertHtmlTextToPdf(htmlText, picPath, 100, 200, 100, 100);
19 //輸出至客戶端
20 HtmlToPdfHelper.PdfDownload(pdfFile);//此處調用步驟6方法
21
22 return View();
23 }
24
25 public ActionResult Test()
26 {
27 return View();
28 }
29
30 /// <summary>
31 /// 獲取MVC視圖Html
32 /// </summary>
33 /// <param name="context"></param>
34 /// <param name="viewName">視圖名稱</param>
35 /// <returns></returns>
36 public static string GetViewHtml(ControllerContext context, string viewName)
37 {
38 if (string.IsNullOrEmpty(viewName))
39 viewName = context.RouteData.GetRequiredString("action");
40 using (var sw = new StringWriter())
41 {
42 ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
43 var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData,
44 context.Controller.TempData, sw);
45 try
46 {
47 viewResult.View.Render(viewContext, sw);
48 }
49 catch (Exception ex)
50 {
51 throw;
52 }
53
54 return sw.GetStringBuilder().ToString();
55 }
56 }
57 }
總結:我理解的解決思路是將html讀取轉換成字符串,之后再通過 itextsharp 轉換成 pdf 比特幣 傳輸至客戶端或直接保存至服務器生成鏈接供用戶下載。(新手上路,不妥之處,歡迎各位大神指教)
以上代碼僅滿足個人業務邏輯需求,謝謝瀏覽。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。