.NET中匯出到Office文檔(word,excel)有我理解的兩種方法.一種是將匯出的檔案存放在伺服器某個檔案夾下面,利用response輸出到瀏覽器地址欄,直接開啟;還有直接利用javascript來匯出html中的標籤。
1.javascript匯出
function AllAreaWord(areaId) { var myDate = new Date(); //日期函數 try { var fileName = myDate.getYear() + (myDate.getMonth() + 1) + myDate.getDate() + myDate.getMinutes() + myDate.getSeconds(); //檔案名稱 var areaRes = document.getElementById("showPage"); //指定要輸入地區 //建立word對象 var wordObj = new ActiveXObject("Word.Application"); //指定輸出類型 var docObj = wordObj.Documents.Add("", 0, 1); var oRange = docObj.Range(0, 1); var sel = document.body.createTextRange(); sel.moveToElementText(areaRes); sel.select(); sel.execCommand("Copy"); oRange.Paste(); wordObj.Application.Visible = true; docObj.saveAs("D://" + fileName + ".doc") //匯出檔案到指定目錄 } catch (e) { alert("儲存失敗,請重新整理本頁面重新嘗試!"); } finally { window.location.reload(); } }
這個方法需要瀏覽器建立Activex,需要勾選未知簽名的Activex控制項。但是這樣會降低瀏覽器的安全性,所以總是在開啟瀏覽器時出現這樣提示使用者還原預設安全設定的提示。如果不是很瞭解,還原後還是不能建立ActiveXObject對象就無法建立word的對象;所以這個方法有很大的局限性。
2.利用.NET com組件
功能:將資料庫內的欄位匯出產生匯入英語口語成績的模板
查詢指定資料庫欄位
/// <summary> /// 查詢資料庫表欄位 /// </summary> /// <param name="tablename">資料庫表名</param> /// <returns></returns> public DataSet GetTableName(string tablename) { //查詢資料庫表欄位sql語句 StringBuilder str = new StringBuilder("SELECT name FROM syscolumns WHERE (id = (SELECT id FROM sysobjects WHERE name = '"+tablename+"'))"); //返回表名 DataSet ds = DBUtility.DbHelperSQL.Query(str.ToString()); return ds; }
核心代碼:SELECT name FROM syscolumns WHERE (id = (SELECT id FROM sysobjects WHERE name = tablename)
這裡還有很多有趣的sql語句,之前沒有接觸過的。像什麼查詢出該整個伺服器所有的資料庫名稱等。
有興趣見:http://www.cnblogs.com/eter/archive/2011/08/15/2139063.html
匯入到excel
/// <summary> /// 下載匯入成績的模板 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void DownLoadTemplate(object sender, EventArgs e) { //找到資料庫欄位 QuerySpokenEnglishScoreBLL spokenEnglishScorebll = new QuerySpokenEnglishScoreBLL(); string strTablename = "T_SpokenScores"; DataSet ds = spokenEnglishScorebll.QueryTableName(strTablename); ArrayList tablename = new ArrayList(); tablename.Add("學號"); tablename.Add("分值"); //for (int i = 0; i < ds.Tables[0].Rows.Count; i++) //{ // tablename.Add(ds.Tables[0].Rows[i][0]); //} //將資料庫欄位寫入excel //建立excel對象 Excel.Application excel = new Excel.Application(); //建立Microsoft Excel 活頁簿 Excel.Workbook Nowbook; //判斷伺服器未安裝Excel應用程式 if (excel == null) { throw new Exception("伺服器未安裝Excel應用程式,此功能無法使用"); } //建立工作薄賦值給Nowbook Nowbook = excel.Workbooks.Add(); int lengthTableName = 3; for (int i = 1; i < lengthTableName; i++) { Nowbook.Sheets[1].Cells[1, i] = tablename[i - 1]; } //儲存在伺服器中指定的實體路徑檔案 string strpath = Server.MapPath("~/UploadFile/DownFile") + "/" + "匯入口語成績模板" + ".xls"; //指定檔案夾存放,其實是複製一份源檔案 Nowbook.SaveCopyAs(strpath); Nowbook.Close(SaveChanges: false); Nowbook = null; excel.Quit(); excel = null; //直接轉向檔案路徑,直接開啟 Response.Redirect("../../UploadFile/DownFile/" + "匯入口語成績模板.xls"); }
其中在測試過程中,遇到一些的問題也是比較有意思的。
問題一:
讀取Excel檔案時出現錯誤“HRESULT中的異常:0X800A03EC”。
查閱MSDN,微軟的同志們是這樣跟我說的。就是我每次加入到工作薄中的單元格的內容太多,太長導致的。我試了試,因為我之前用的中文最後發現不是這個問題。而是我的迴圈裡面從0開始的。Nowbook.Sheets[1].Cells[1, i],這樣導致根本就無法建立這個單元格就更別談什麼插入內容了。所以這樣看來,微軟的大牛把我給忽悠了一番啊!哈哈
問題二:
看到這個我首先想打的是可能會不會是許可權的問題,我很快否定這個。因為根據代碼,我已經建立了這個xls檔案。最後發現我的檔案不是放在了指定的我訪問的檔案路徑,這樣就對了。所以我這個用伺服器的路徑這樣就可以存在指定的實體路徑了。
預設情況下:使用Nowbook.saveas儲存是在我的文件檔案夾下的。
使用伺服器位址
//儲存在伺服器中指定的實體路徑檔案
string strpath = Server.MapPath("~/UploadFile/DownFile") + "/" + "匯入口語成績模板" + ".xls";
//指定檔案夾存放,其實是複製一份源檔案
Nowbook.SaveCopyAs(strpath);
就可以了。
總結
其實對於後種方式也是有缺陷的,在開啟的時候總是會提示我們是否要開啟檔案格式好副檔名不匹配的檔案。這個方法,主要是對於excel這麼一個非託管的類來實現的。在下面的連結裡面有其他的方法,大家有興趣的可以研究研究。
來自百度文庫:
MSDN: 如何使用 Visual C# 2005 或 Visual C# .NET 向 Excel 活頁簿傳輸資料
http://support.microsoft.com/kb/306023/zh-cn
如何:使用 COM Interop 建立 Excel 電子錶格(C# 編程指南)
http://msdn.microsoft.com/zh-cn/library/ms173186(VS.80).aspx
如何在 Microsoft Visual C# .NET 中實現 Microsoft Excel 自動化
http://support.microsoft.com/kb/302084/zh-cn
C#中建立、開啟、讀取、寫入、儲存Excel的一般性代碼
http://hi.baidu.com/zhaochenbo/blog/item/f6d70ff7bf32fa2a730eec39.html
與 XML 一起使用 Visual Basic 和 ASP 產生 Excel 2003 活頁簿
http://msdn.microsoft.com/zh-cn/library/aa203722(office.11).aspx