这个问题困扰了我好几天,现在终于解决了,现公布整个过程的注意点。通过.net导出Excel表,除了注意导出的方法外,还要关心资源的回收问题,中间涉及到COM组件的关闭等。
因为对windows系统、.Net不熟,所以中间可能有多余的步骤。最终可以实现就算了,不深究。
1. 导出EXCEL表
添加引用:在“COM”选项卡上,找到“Microsoft Excel 10.0 对象库或 Microsoft Excel 11.0 对象库”,然后单击“选择”。(office2007和2003的版本会有少许区别,我在2007只找到Microsoft Excel 12,但编程的时候却无法显示Excel命名空间的内容,所以还不是我们所要的。最后我是从一个以前的项目的bin目录里,把旧的Interop.Excel.dll导入,缺乏安全及稳定的考虑,所以小孩子不要学我哦,造成的结果自己承担)
代码实现:
这段来自一个高人的,忘了从哪里抄来的,请作者原谅!
using Microsoft.Office.Core;
private void DoExport(DataSet ds, string FilePath)
{
Excel.Application xls = new Excel.Application();
int rowIndex = 1;
int colIndex = 1;
xls.Application.Workbooks.Add(true);
if (ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
foreach (DataColumn col in dt.Columns)
{
xls.Cells[1, colIndex] = col.ColumnName;
colIndex++;
}
foreach (DataRow row in dt.Rows)
{
rowIndex++;
colIndex = 1;
foreach (DataColumn col in dt.Columns)
{
xls.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
colIndex++;
}
}
}
xls.Visible = false;
/* 只能用旧的格式 Excel.XlFileFormat.xlExcel7,office2007不支持 Excel.XlFileFormat.xlExcel9597 */
xls.ActiveWorkbook.SaveAs(FilePath, Excel.XlFileFormat.xlExcel7, null, null, false, false, Excel.XlSaveAsAccessMode.xlNoChange, null, null, null, null, null);
xls.Workbooks.Close();
xls.Quit();
zxpGCCollect.ReleaseComObject(xls); /* 这里是我的一个资源回收的方法,具体请看下面 */
GC.Collect();
}
2. 资源回收。这一步非常重要,否则用户每导出一张表,服务器就会开一个excel的进程。
【 资源回收前的设置 】
容易出现的问题:asp.net操作Excel失败问题(80070005) http://www.hccar.com/index.aspx
在执行页面的目录底下再建多一个web.config
<system.web>
<!--
在这里添加下面这句
-->
<identity impersonate="true" userName="用户名" password="密码"/>
</system.web>
在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG的machine.config
<processModel enable="true" timeout="Infinite" idleTimeout="Infinite" shutdownTimeout="0:00:05" requestLimit="Infinite" requestQueueLimit="5000" restartQueueLimit="10" memoryLimit="60" webGarden="false" cpuMask="0xffffffff" userName="System" password="AutoGenerate" logLevel="Errors" clientConnectedCheck="0:00:05" comAuthenticationLevel="Connect" comImpersonationLevel="Impersonate" responseRestartDeadlockInterval="00:09:00" responseDeadlockInterval="00:03:00" maxWorkerThreads="25" maxIoThreads="25"/>
在上面的userName="machine" 改为 userName="System"
【 资源回收代码 】
http://topic.csdn.net/t/20040323/14/2875770.html
http://blog.csdn.net/hanxuema2008/archive/2008/11/21/3344409.aspx
http://dotnet.chinaitlab.com/CSharp/759079.html
public class zxpGCCollect
{
public zxpGCCollect()
{
}
//这种方法需要处理权限问题
public static void KillExcelProcess(Excel.Application excel)
{
IntPtr ptr = new IntPtr(excel.Hwnd);
int k = 0;
zxpWin32API.GetWindowThreadProcessId(ptr, out k);
System.Diagnostics.Process pro = System.Diagnostics.Process.GetProcessById(k);
pro.Kill();
}
public static void ReleaseComObject(object obj)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
}
}