客戶需求:
上兩篇博客主要介紹了通過Word進行費用報銷憑證的打印及批量打印。
雖然可以進行打印,但是還是存在問題,有的客戶機器MS Office 安裝會有問題,那麼通過DocX產生的Word在客戶機器上無法打開,所以還是有些瑕疵。
還有一個問題,就是這樣的打印體驗很不好,因為每次打印要把word下載下來進行打印,所以,用戶體驗不是很好。
之前,有想過通過office控件進行處理,但是由於每個客戶端的浏覽器不同對插件的支持程度不同,所以這方案很快被否掉了。
最後,決定將Word在服務端轉換成PDF,然後在線打開PDF進行憑證的打印。
解決方案:
將Word在服務端轉換成PDF,然後在線打開PDF進行憑證的打印。
在此使用的第三方插件為NETOffice。
.NET包裝程序集件,用於訪問以下MS Office應用程序: Office,Excel,Word,Outlook,PowerPoint,Visio
Office集成,無版本限制
包括Office版本2000,2002,2003,2007,2010,2013的所有功能
具體介紹請參考官網:http://netoffice.codeplex.com/
Demo程式代碼:
demo界面:


生產Word程式代碼:

1 private void ExportWord()
2 {
3
4
5 //模板路徑
6 string mWordTemplateSrc = Request.PhysicalPath.Replace("ExportWordAPI.aspx", "ExportWordTemplate.docx");
7
8 //Word文件路徑
9 string mGuid = System.Guid.NewGuid().ToString();
10 string mWordSrc = Request.PhysicalPath.Replace("ExportWord\\ExportWordAPI.aspx", "WordToPDF\\Temp\\" + mGuid + ".docx");
11 string IsPDF = Request.QueryString["IsPDF"];
12
13 MemoryStream stream = new MemoryStream();
14 using (DocX docPrint = DocX.Create(stream, DocumentTypes.Template))
15 {
16 DocX doc;
17 string mIds = Request.QueryString["SheetNo"];
18 string[] mSheets = mIds.Split('|');
19 //int iLength = 0;
20 int iPrintCount = 0;
21 int mParagraphsIndex = 0;
22 foreach (string sheetNo in mSheets)
23 {
24 //iLength++;
25 if (string.IsNullOrEmpty(sheetNo.Trim())) continue;
26
27 iPrintCount++;
28
29 //加載模板
30 doc = DocX.Load(mWordTemplateSrc);
31 //輸出打印內容到模板
32 ExportWord(ref doc, "FYBX", sheetNo);
33
34 if (iPrintCount > 1)
35 {
36 mParagraphsIndex = docPrint.Paragraphs.Count - 1;
37 docPrint.Paragraphs[mParagraphsIndex].InsertPageBreakAfterSelf();
38 mParagraphsIndex = docPrint.Paragraphs.Count - 1;
39 docPrint.Paragraphs[mParagraphsIndex].SetLineSpacing(LineSpacingType.Line, 0);
40 docPrint.Paragraphs[mParagraphsIndex].SetLineSpacing(LineSpacingType.Before, 0);
41 docPrint.Paragraphs[mParagraphsIndex].SetLineSpacing(LineSpacingType.After, 0);
42 }
43 //將打印內容插入打印word中
44 docPrint.InsertDocument(doc, true);
45 }
46 if (IsPDF == "Y")
47 {
48 docPrint.SaveAs(mWordSrc);
49 }
50 else
51 {
52 docPrint.Save();
53 }
54 }
55
56
57 if (IsPDF == "Y")
58 {
59 Response.Redirect("../WordToPDF/WordToPDF.aspx?guid=" + mGuid);
60 }
61 else
62 {
63 byte[] tAryByte = stream.ToArray();
64 Response.Clear();
65 Response.AddHeader("Content-Length", tAryByte.Length.ToString());
66 Response.AppendHeader("Content-Disposition", string.Format("attachment;filename=ExportWord_{0}.docx", DateTime.Now.ToString("yyMMddHHmmss")));
67 Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
68 Response.BinaryWrite(tAryByte);
69 Response.Flush();
70 Response.End();
71 }
72 }
73
74 private void ExportWord(ref DocX doc, string pFormID, string pSheetNO)
75 {
76 IDictionary par = new Dictionary<string, object>();
77 string sql = "SELECT * FROM head WHERE head001=@head001 AND head002=@head002 ";
78 par.Clear();
79 par.Add("head001", pFormID);
80 par.Add("head002", pSheetNO);
81 DataTable dtHead = SqlDBHelper.ExecuteDataTable(this.SqlServerConnection, sql, par);//單頭數據
82
83 sql = "SELECT * FROM body WHERE body001=@body001 AND body002=@body002 ";//單身數據
84 par.Clear();
85 par.Add("body001", pFormID);
86 par.Add("body002", pSheetNO);
87 DataTable dtBody = SqlDBHelper.ExecuteDataTable(this.SqlServerConnection, sql, par);
88
89
90 thisReplaceText(ref doc, "head002", dtHead.Rows[0]["head002"].ToString());
91 thisReplaceText(ref doc, "head003", dtHead.Rows[0]["head003"].ToString());
92 thisReplaceText(ref doc, "head004", dtHead.Rows[0]["head004"].ToString());
93 thisReplaceText(ref doc, "head005", dtHead.Rows[0]["head005"].ToString());
94 thisReplaceText(ref doc, "head006", dtHead.Rows[0]["head006"].ToString());
95 thisReplaceText(ref doc, "head008", dtHead.Rows[0]["head008"].ToString());
96 thisReplaceText(ref doc, "head009", dtHead.Rows[0]["head009"].ToString());
97 thisReplaceText(ref doc, "M", dtHead.Rows[0]["head010"].ToString());
98
99 int bodyRowIndex = 0;
100
101 int rowLength = 8;
102 Row insertRow = doc.Tables[0].Rows[rowLength];
103
104 int mRowsLength = 0;
105 foreach (DataRow dr in dtBody.Rows)
106 {
107 mRowsLength += 1;
108 if (mRowsLength <= 5)
109 {
110 doc.Tables[0].Rows[2 + mRowsLength].Cells[0].Paragraphs[0].Append(dr["body003"].ToString());
111 doc.Tables[0].Rows[2 + mRowsLength].Cells[1].Paragraphs[0].Append(dr["body004"].ToString());
112 doc.Tables[0].Rows[2 + mRowsLength].Cells[2].Paragraphs[0].Append(dr["body005"].ToString());
113 }
114 else
115 {
116 //獲取到模板行的對象(一般是一個空行,只有架子沒有數據的)
117 doc.Tables[0].Rows[rowLength + bodyRowIndex].Xml.AddAfterSelf(insertRow.Xml);
118 bodyRowIndex += 1;
119 doc.Tables[0].Rows[rowLength + bodyRowIndex].Cells[0].Paragraphs[0].Append(dr["body003"].ToString());
120 doc.Tables[0].Rows[rowLength + bodyRowIndex].Cells[1].Paragraphs[0].Append(dr["body004"].ToString());
121 doc.Tables[0].Rows[rowLength + bodyRowIndex].Cells[2].Paragraphs[0].Append(dr["body005"].ToString());
122 }
123 }
124 //刪除模板行,要不然會有一個空行
125 doc.Tables[0].RemoveRow(rowLength);
126 }
127
128 private void thisReplaceText(ref DocX document, string o, string n)
129 {
130 string OO = "[" + o + "]";
131 document.ReplaceText(OO, n, false, System.Text.RegularExpressions.RegexOptions.None, null, null, MatchFormattingOptions.SubsetMatch, true, false);
132 }
View Code
Word轉換成PDF代碼:

1 string guid = Request.QueryString["guid"];
2
3 //模板路徑
4 string mWordSrc = Request.PhysicalPath.Replace("WordToPDF.aspx", "\\Temp\\" + guid + ".docx");
5 string mPDFSrc = Request.PhysicalPath.Replace("WordToPDF.aspx", "\\Temp\\" + guid + ".pdf");
6
7 try
8 {
9 Word.Application wordApplication = new Word.Application();
10 Word.Document pDoc = wordApplication.Documents.Open(mWordSrc);
11 pDoc.Activate();
12
13 pDoc.SaveAs(mPDFSrc, WdSaveFormat.wdFormatPDF);
14 wordApplication.Quit();
15 wordApplication.Dispose();
16
17 if (System.IO.File.Exists(mPDFSrc))
18 {
19 byte[] tAryByte = System.IO.File.ReadAllBytes(mPDFSrc);
20 Response.Clear();
21 Response.AddHeader("Content-Length", tAryByte.Length.ToString());
22 Response.AppendHeader("Content-Disposition", string.Format("inline;filename=ExportWord2PDF_{0}.docx", DateTime.Now.ToString("yyMMddHHmmss")));
23 Response.ContentType = "application/pdf";
24 Response.BinaryWrite(tAryByte);
25 Response.Flush();
26 Response.End();
27
28 }
29 }
30 catch (Exception ex)
31 {
32 Response.Clear();
33 Response.Write(ex.Message);
34 Response.Flush();
35 Response.End();
36 }
37 finally
38 {
39 //刪除緩存文件
40 if (System.IO.File.Exists(mPDFSrc)) System.IO.File.Delete(mPDFSrc);
41 if (System.IO.File.Exists(mWordSrc)) System.IO.File.Delete(mWordSrc);
42
43 }
View Code
代碼地址: http://pan.baidu.com/s/1sltlp5j