.NET經過調用Office組件導出Word文檔sql
最近作項目須要實現一個客戶端下載word表格的功能,該功能是用戶點擊"下載表格",服務端將該用戶的數據查詢出來並生成數據到Word模板中,再反饋給客戶端下載。數據庫
實現思路以下:windows
利用微軟提供的Office的組件來完成,在服務器端指定目錄放置一個word模板(該模板中須要替換的數據信息用書籤標記好),當請求過來的時候,讀取模板信息並將書籤內容替換成從數據庫得到的信息在返回給客戶端下載便可,代碼以下:瀏覽器
#region 根據申請單ID號和模板生成word下載文件(書籤的形式) public void DownLoadWordOld(string id) { if (string.IsNullOrEmpty(id)) { id = "0"; } string sql = "SELECT ID,ProposerName,PhoneNo,ProposerAddress,HouseArea,HouseType,HouseNature,ApplyDate" + " from BettingStationApply where ID=@id "; SqlParameter[] parm = new SqlParameter[] { new SqlParameter("@id", int.Parse(id)) }; //根據ID號取得當前申請單的詳細信息 DataTable dt = DBHelper.GetDataSet(sql, parm); if (dt.Rows.Count > 0) { DataRow dr = dt.Rows[0]; //一、先建立一個建立word的Application Word.Application wordApp = new Word.ApplicationClass(); //二、建立一個word文檔 Word.Document docFile = null; try { wordApp.Visible = false; //模板對象 object objTemplete = Server.MapPath(@"/BettingStation/templete.docx"); object objTrue = true; object objFalse = false; object objDocType = Word.WdDocumentType.wdTypeDocument; //實例化word文檔(已經讀取到模板的word文檔) docFile = wordApp.Documents.Add(ref objTemplete, ref objFalse, ref objDocType, ref objTrue); //定義書籤變量 object ProposerName = "ProposerName"; object PhoneNo = "PhoneNo"; object ProposerAddress = "ProposerAddress"; object HouseArea = "HouseArea"; object HouseType = "HouseType"; object HouseNature = "HouseNature"; object ApplyDate = "ApplyDate"; //獲取全部的書籤 Word.Bookmarks books = docFile.Bookmarks; //給書籤賦值 if (books.Exists("ProposerName")) { books.get_Item(ref ProposerName).Range.Text = dr["ProposerName"].ToString(); } if (books.Exists("PhoneNo")) { books.get_Item(ref PhoneNo).Range.Text = dr["PhoneNo"].ToString(); } if (books.Exists("ProposerAddress")) { books.get_Item(ref ProposerAddress).Range.Text = dr["ProposerAddress"].ToString(); } if (books.Exists("HouseArea")) { books.get_Item(ref HouseArea).Range.Text = dr["HouseArea"].ToString(); } if (books.Exists("HouseType")) { books.get_Item(ref HouseType).Range.Text = dr["HouseType"].ToString(); } if (books.Exists("HouseNature")) { books.get_Item(ref HouseNature).Range.Text = dr["HouseNature"].ToString(); } if (books.Exists("ApplyDate")) { if (dr["ApplyDate"] != DBNull.Value) { books.get_Item(ref ApplyDate).Range.Text = Convert.ToDateTime(dr["ApplyDate"].ToString()).ToString("yyyy-MM-dd HH:mm:ss"); } } object fileName = Server.MapPath(@"/BettingStation/投注站申請表.docx"); object nothing = Type.Missing; //將當前文件保存到臨時文件中 docFile.SaveAs2(ref fileName, ref nothing, ref nothing, ref nothing, ref nothing, ref nothing , ref nothing, ref nothing, ref nothing, ref nothing, ref nothing, ref nothing , ref nothing, ref nothing, ref nothing, ref nothing, ref nothing); //關閉當前word文檔 docFile.Close(ref nothing, ref nothing, ref nothing); //退出當前word程序的調用 wordApp.Quit(ref nothing, ref nothing, ref nothing); docFile = null; //從服務器臨時文件夾中下載文件返回給客戶端 ExtWord(fileName.ToString(), dr["ProposerName"].ToString() + "_投注站申請表.docx"); //調用客戶端js方法 } catch (Exception ex) { writeLog.WriteErrorLog("根據模板生成Word文件出錯!錯誤信息:" + ex.Message); //出異常記得釋放相關資源 object nothing = Type.Missing; //關閉當前word文檔 docFile.Close(ref nothing, ref nothing, ref nothing); //退出當前word程序的調用 wordApp.Quit(ref nothing, ref nothing, ref nothing); docFile = null; Message.show("根據模板生成Word文件出錯!錯誤信息:" + ex.Message); } } else { writeLog.WriteErrorLog("id=" + id + "沒有查找到任何數據!"); Message.show("id=" + id + "沒有查找到任何數據!"); } } #endregion
調用offic組件須要添加Interop.Microsoft.Office.Interop.Word.dll的引用,我電腦上裝的Office2010,因此添加Microsoft Word 14.0 Object Library的引用安全
Word模板在服務器端生成好後,在利用Response方法將生成的word文檔發送給客戶端下載,代碼以下:
#region 從服務器指定路徑下載Word /// <summary> /// 從服務器指定路徑下載Word /// </summary> /// <param name="fileFullName">臨時文件在服務器上的完整路徑</param> /// <param name="wordname">下載的Word文件名</param> public void ExtWord(string fileFullName, string wordname) { //輸出word FileInfo file = new System.IO.FileInfo(fileFullName); HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Charset = "GB2312"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; // 添加頭信息,爲"文件下載/另存爲"對話框指定默認文件名 HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(wordname, System.Text.Encoding.UTF8)); // 添加頭信息,指定文件大小,讓瀏覽器可以顯示下載進度 HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString()); // 指定返回的是一個不能被客戶端讀取的流,必須被下載 HttpContext.Current.Response.ContentType = "application/ms-word"; // 把文件流發送到客戶端 HttpContext.Current.Response.WriteFile(file.FullName); // 中止頁面的執行 HttpContext.Current.ApplicationInstance.CompleteRequest(); } #endregion
測試,運行沒問題。服務器
將開發環境測試OK的程序發佈到正式的服務器環境後發現,不能運行,導出會出現錯誤。解決方法以下:app
一、確保服務器上已經安裝了並激活word程序(建議安裝word2010);ide
二、當開發的經過word模板生成word程序完成後,部署在windows相關的服務器上時,若是出現如下的錯誤(讀取word組件的Com權限問題):工具
三、查看錯誤的字面意思,應該是COM組件的配置有問題,網上查閱相關資料發現是權限的配置的問題!測試
四、如下步驟重點是給iis授予com組件的訪問權限:
步驟一:找到導出word所用到的com組件;
(1)控制面板-》管理工具-》組件服務-》計算機-》個人電腦-》DCOM配置-》Mircosoft Word文檔;
注:若是這樣操做找不到Mircosoft word相關文檔,不用慌,嘗試如下方法:
Cmd-》mmc -32-》文件-》添加/刪除管理單元-》選擇組件服務-》肯定-》計算機-》個人電腦-》DCOM配置-》找到Mircosoft Word 97-2003文檔,按照如下的方法操做便可;
步驟二:找到word文檔後,在它上面點擊右鍵,而後點擊"屬性",
彈出"Microsoft word 應用程序屬性"對話框,
步驟一:點擊"標識"標籤,選擇"交互式用戶"
步驟三:點擊"安全"標籤,在"啓動和激活權限"上點擊"自定義",而後點擊對應的"編輯"按鈕,在彈出的"安全性"對話框中填加 IIS_IUSRS帳戶(IIS帳戶),並按照以下圖所示授予相關權限:
,
步驟四:依然是"安全"標籤,在"訪問權限"上點擊"自定義",而後點擊"編輯",配置的帳號和方法和上一步操做同樣;
六:重啓網站並運行,點擊下載表格按鈕即成功。