客戶需求:
上兩篇博客主要介紹了通過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