把數據輸出到Word (非插件形式)

項目開發過程當中,咱們要把數據以各類各樣的形式展示給客戶。把數據以文檔的形式展示給客戶相信是一種比較頭疼的問題,若是沒有好的方法會html

使得個人開發繁瑣,並且知足不了客戶的需求。接下來我會經過兩種開發方式介紹如何將數據輸出到Word 文檔上。我會分兩篇文章介紹,第一篇前端

介紹不使用插件的狀況下操做word,第二篇文章將介紹一種強大的插件操做word。下面開始第一篇文章。[本次實例源代碼從這裏下載]後端

 

文章梗概:服務器

♦ 不使用模板將數據輸出到 wordapp

     ♦ 輸出數據到 word 在後端設置輸出內容ide

     ♦ 輸出數據到 word 在前端設置輸出內容post

♦ 經過設置模板將數據輸出到 word測試

     ♦ 經過把word另存爲html 文件的形式作成模板輸出到word字體

     ♦ 經過把word另存爲mht 文件的形式作成模板輸出到wordui

 

1、不用模板將數據輸出到 word

一、輸出數據到 word 在後端設置輸出內容

前端定義兩個服務器按鈕:

1 <div id="container" style="">
2         不利用模板:<br />
3         <br />
4         <asp:Button ID="CreateWordBehind" runat="server" Text="輸出數據到word(後臺設置內容)" OnClick="CreateWordBehind_Click" />
5         <asp:Button ID="CreateWordFront" runat="server" Text="輸出數據到word(前臺設置內容)" OnClick="CreateWordFront_Click" />
6         <hr />
7     </div>

後端代碼輸出到word,代碼很簡單隻要設置輸出頭爲word,而輸出的內容放到 StringBuilder 裏,而且經過 StringBuilder實例,去設置要輸出的內容,包括字體、顏色....

 1         /// <summary>
 2         /// 輸出數據到word(後臺設置內容)
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         protected void CreateWordBehind_Click(object sender, EventArgs e)
 7         {
 8             HttpContext.Current.Response.Clear();
 9             HttpContext.Current.Response.Buffer = true;
10             HttpContext.Current.Response.Charset = "";
11 
12             // 設置輸出頭
13             HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode("CreateWord", System.Text.Encoding.UTF8) + ".doc");
14 
15             // 設置輸出的編碼格式
16             HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default;
17 
18             // Response.ContentType指定文件類型 能夠爲application/ms-excel || application/ms-word || application/ms-txt || application/ms-html
19             // 由於是輸出word 因此這裏就指定爲 application/ms-word
20             HttpContext.Current.Response.ContentType = "application/ms-word";
21 
22             // 定義StringBuilder 把要輸出的內容寫到裏面,而且能夠設置字體、顏色、大小等...
23             StringBuilder sb = new StringBuilder();
24             sb.AppendLine("<div style='text-align:center;font-size:18px;font-weight:bold;'>導出數據到word</div>");
25             sb.AppendLine("這是導出到word的數據<br />");
26             sb.AppendLine("<span style='color:blue;'>這是導出到word的數據</span>");
27 
28             HttpContext.Current.Response.Output.Write(sb);
29             HttpContext.Current.Response.Flush();
30             HttpContext.Current.Response.End();
31         }

運行、點擊按鈕、打開word文檔,效果以下:

二、輸出數據到 word 在前端設置輸出內容

前端設置輸出的html內容。以輸出一個表格爲例。其中有兩個div 標記了runat="server",這樣後臺就能夠取到這個id,用途一會介紹。

 1 <div id="WordContent" runat="server">
 2         <div runat="server" id="title">表頭</div>
 3         <table border="1" style="width:400px;line-height: 25px;">
 4             <tr style="width:400px; height:25px;">
 5                 <td>
 6                     編號
 7                 </td>
 8                 <td>
 9                     姓名
10                 </td>
11                 <td>
12                     成績
13                 </td>
14             </tr>
15             <tr style="width:400px; height:25px;">
16                 <td>
17                 </td>
18                 <td>
19                 </td>
20                 <td>
21                 </td>
22             </tr>
23         </table>
24     </div>

至此前端的所有代碼以下:

 1 <form id="form1" runat="server">
 2     <div id="WordContent" runat="server">
 3         <div runat="server" id="title">表頭</div>
 4         <table border="1" style="width:400px;line-height: 25px;">
 5             <tr style="width:400px; height:25px;">
 6                 <td>
 7                     編號
 8                 </td>
 9                 <td>
10                     姓名
11                 </td>
12                 <td>
13                     成績
14                 </td>
15             </tr>
16             <tr style="width:400px; height:25px;">
17                 <td>
18                 </td>
19                 <td>
20                 </td>
21                 <td>
22                 </td>
23             </tr>
24         </table>
25     </div>
26     <div id="container" style="">
27         不利用模板:<br />
28         <br />
29         <asp:Button ID="CreateWordBehind" runat="server" Text="輸出數據到word(後臺設置內容)" OnClick="CreateWordBehind_Click" />
30         <asp:Button ID="CreateWordFront" runat="server" Text="輸出數據到word(前臺設置內容)" OnClick="CreateWordFront_Click" />
31         <hr />
32     </div>
33     </form>
View Code

 

後端代碼輸出到word的代碼和就是把以前的StringBuilder 換成了StringWriter,StringWriter的信息其實也是經過Stringbulider存儲的。另外加上一個

HtmlTextWriter對象,HtmlTextWriter能夠把前端渲染後的頁面以流的形式輸出。

這是候咱們就能夠看出在前端html中標記的id的用途了,這樣就能夠把id標記爲WordContent的裏面的內容所有輸出到word,而其餘的內容也不會輸出到word上了。

又因爲前端html中id標記了title的div標籤在後臺設置了title.Style.Add(HtmlTextWriterStyle.Display, "none");因此它也不會被輸出到word上。

 1 /// <summary>
 2         /// 輸出數據到word(前臺設置內容)
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         protected void CreateWordFront_Click(object sender, EventArgs e)
 7         {
 8             HttpContext.Current.Response.Clear();
 9             HttpContext.Current.Response.Buffer = true;
10             HttpContext.Current.Response.Charset = "";
11 
12             // 設置輸出頭
13             HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode("CreateWord", System.Text.Encoding.UTF8) + ".doc");
14 
15             // 設置輸出的編碼格式
16             HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default;
17 
18             // Response.ContentType指定文件類型 能夠爲application/ms-excel || application/ms-word || application/ms-txt || application/ms-html
19             // 由於是輸出word 因此這裏就指定爲 application/ms-word
20             HttpContext.Current.Response.ContentType = "application/ms-word";
21 
22             // 定義輸出流,其信息也是存儲在StringBuilder中的
23             System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
24 
25             // 定義一個服務器控件輸出流(能夠把前端渲染後的頁面以流的形式輸出)
26             System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
27 
28             // 控制前端的樣式 (HtmlTextWriterStyle 枚舉用來控制 顯示、字體、大小、顏色...)
29             title.Style.Add(HtmlTextWriterStyle.Display, "none");
30             
31             // 這樣會把前端的整個頁面輸出,因爲有些其餘元素不須要輸出,因此註釋
32             //this.RenderControl(oHtmlTextWriter);
33 
34             // 指定咱們前端標記要輸出的容器,容器包含的內容均可以輸出
35             this.WordContent.RenderControl(oHtmlTextWriter);
36 
37             HttpContext.Current.Response.Output.Write(oStringWriter);
38             HttpContext.Current.Response.Flush();
39             HttpContext.Current.Response.End();
40         }

運行、點擊按鈕發現報錯,提示"只能在執行 Render() 的過程當中調用 RegisterForEventValidation;"這個錯誤的緣由就是懷疑經過post方法發送惡意的數據,解決方法:

在當前aspx頁面頭部加上:EnableEventValidation="false",默認爲true。

1 <%@ Page Language="C#" AutoEventWireup="true" EnableEventValidation="false" CodeBehind="OperateWord.aspx.cs"
2     Inherits="OperateWordPro.OperateWordDemo1.OperateWord" %>

 

再運行、點擊按鈕、打開word,效果以下(固然需求不可能那麼簡單,具體輸出的樣式就要在html中慢慢的調整了):

 

2、經過提早設置模板將數據輸出到 word

      由於若是用前面的方式,將數據都是本身拼接的,包括樣式全是本身控制,難度將很是大,而且效果也很讓到客戶的滿意(如:要求頁眉、頁腳)。因此若是可以程序直接讀取word模板把要輸出的內容填充進去將會大大的縮短咱們的時間,最主要的是版式不用咱們太關心。

 

一、 經過把word另存爲html 文件的形式作成模板輸出到word

 

      把word文檔作成模板的思路就是把word文檔保存爲html程序能夠直接讀取的形式。因爲篇幅的問題,具體把word另存爲html的細節能夠請參考這篇博文。下面有這樣一個結構的word文檔須要輸出,經過用讀取模板的形式咱們只要把下面幾個站位符替換掉就能夠了(如,要輸出名字的地方加上了{name}...),思路很簡單。

 前臺html代碼:

1         利用模板輸出到word:<br /><br />
2         <asp:Button ID="CreateWordByHtmlTemplate" runat="server" Text="經過htm模板生成Word" OnClick="CreateWordByHtmlTemplate_Click" />
3         <asp:Button ID="CreateWordBymhtTemplate" runat="server" Text="經過mht模板生成Word" OnClick="CreateWordBymhtTemplate_Click" />

在項目中添加一個Document文件夾,將模板文件「通知.html」拷貝到這個問價夾下。

下面是後臺代碼:

 1 /// <summary>
 2         /// 經過htm模板生成Word
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         protected void CreateWordByHtmlTemplate_Click(object sender, EventArgs e)
 7         {
 8             // 獲取模板的路徑 經過ExprotToWord處理返回 字符串
 9             string strWord = DealTemplate(Server.MapPath("../Document/通知.html"));
10         
11             Response.ContentEncoding = System.Text.Encoding.Default;
12             Response.ClearContent();
13             Response.ClearHeaders();
14             Response.AddHeader("content-disposition", "attachment;filename=合同.doc"); //必須的
15             Response.AddHeader("Content-type", "application");
16             Response.ContentType = "application/ms-html";
17             Response.ContentEncoding = System.Text.Encoding.Default; 
18            
19             Response.Write(strWord);
20             Response.Flush();
21             Response.Close();
22         }
23 
24 /// <summary>
25         /// 處理模板 返回處理結果
26         /// </summary>
27         /// <param name="templatePath"></param>
28         /// <returns></returns>
29         public string DealTemplate(string templatePath)
30         {
31             StringBuilder sb = new StringBuilder(1024);
32 
33             // 讀取文檔內容並轉換成流的形式 編碼爲默認編碼
34             StreamReader sr = new StreamReader(templatePath, Encoding.Default);
35 
36             // 將流轉換成字符串加進StringBuilder中
37             sb.Append(Encoding.Default.GetString(Encoding.Default.GetBytes(sr.ReadToEnd()))); 
38 
39             // 把文檔中咱們設置的標誌位換成咱們想要的內容
40             sb.Replace("{name}", "張三");
41             sb.Replace("{orderNumber}", "ooxx124512");
42             sb.Replace("{tel}", "1383838383");
43             
44             return sb.ToString();
45         }
View Code

 運行、點擊按鈕、打開word,效果以下

 

 

二、 經過把word另存爲mht 文件的形式作成模板輸出到word

      經過把word存儲爲html的形式解決了大量手工拼接數據和word的基本版式問題,可是若是這個word中含有圖片和頁眉頁腳就沒法經過這種方式處理了,由於html存儲的是單文件,是和圖片這些「其餘元素」分開的。因此若是仍是要經過模板的方式解決那麼這個模板要含有文字、圖片、頁眉設置、頁腳設置。通過一番測試,發現把word另存爲.mht的方式能夠解決這個問題。上網查了資料說.mht就是htm和圖片等的複合文件。那麼咱們繼續吧。

      製做一個word在上一個word的基礎上添加了一個含有圖片的word:

把這個word另存爲"通知2.mht",並複製到Document文件夾下。

 後臺代碼和上面代碼同樣,只是換了個模板而已,可是編碼格式要作微調,紅字部分標註了:

 1 /// <summary>
 2         /// 經過mht模板生成Word
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         protected void CreateWordBymhtTemplate_Click(object sender, EventArgs e)
 7         {
 8             // 獲取模板的路徑 經過ExprotToWord處理返回 字符串
 9             string strWord = DealTemplate(Server.MapPath("../Document/通知2.mht"));
10 
11             Response.ContentEncoding = System.Text.Encoding.Default;
12             Response.ClearContent();
13             Response.ClearHeaders();
14             Response.AddHeader("content-disposition", "attachment;filename=合同.doc"); //必須的
15             Response.AddHeader("Content-type", "application");
16             Response.ContentType = "application/ms-html";
17             Response.ContentEncoding = System.Text.Encoding.Default;
18 
19             Response.Write(strWord);
20             Response.Flush();
21             Response.Close();
22         }
23 
24 /// <summary>
25         /// 處理模板 返回處理結果
26         /// </summary>
27         /// <param name="templatePath"></param>
28         /// <returns></returns>
29         public string DealTemplate(string templatePath)
30         {
31             StringBuilder sb = new StringBuilder(1024);
32 
33             // 讀取文檔內容並轉換成流的形式 此處編碼要設置爲UTF8
34             StreamReader sr = new StreamReader(templatePath, Encoding.UTF8);
35 
36             // 將流轉換成字符串加進StringBuilder中
37             sb.Append(Encoding.Default.GetString(Encoding.Default.GetBytes(sr.ReadToEnd())));
38 
39             // 把文檔中咱們設置的標誌位換成咱們想要的內容
40             sb.Replace("{name}", "張三");
41             sb.Replace("{orderNumber}", "ooxx124512");
42             sb.Replace("{tel}", "1383838383");
43 
44             return sb.ToString();
45         } 

運行、點擊按鈕、打開word效果以下:

 

總結

      以上文章介紹的是沒有經過組件將數據輸出到word上,若是客戶需求簡單,格式不是太難控制徹底能夠根據文章中經過模板的方式輸出到word。其中最容易出問題的我認爲就是編碼問題,模板格式不同可能程序中的編碼格式也要作相應的調整。

     雖然以上方式演示沒問題,可是實際開發中需求並無上面的例子簡單。若是客戶要求的word版式比較複雜,且數據要循環輸出那麼經過上面任何一種方式都很差解決。可是經過第三方組件就能夠解決這種問題,若是這個組件用熟練了,上面的方式我相信你幾乎不會用的。下一篇文章將介紹用第三方組件的方式把內容輸出到word。

相關文章
相關標籤/搜索