.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