原理很简单:
1 copy模版文件到临时文件夹,并改名。(我用的是时间)
2 修改这个临时文件。(这部分还没有想好怎么作, 毕竟是C#菜鸟啊)
3 下载这个临时文件。
4 删除临时文件。
在系统中不会留下任何进程, 哈哈。
微软的东西, 你用到了就一定要关闭。
代码中 close()方法关闭掉了大部分。
但还有一些
private Excel.Range oRng;
对象没有关掉的话 系统中会留下 EXcel.exe 进程, 很危险啊!!!!
要引入
Microsoft.Office.Interop.Excel.dll 我的版本是 12.0.0.0
using System; using System.Data; using System.Configuration; using System.Diagnostics; using Excel = Microsoft.Office.Interop.Excel; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Web; /// <summary> /// 根据模版写Excel文件,并提供下载 /// </summary> public class ExcelComManager { private Excel.ApplicationClass ExcelObj = null; //Excel对象 private Excel._Workbook xBk; //工作薄 private Excel._Worksheet xSt; //工作Sheet private Excel.Range xRng; //操作单元格样式 private object missing = System.Reflection.Missing.Value; /// <summary> /// 模板文件名 完全路径 /// </summary> private string templateFilePath; /// <summary> /// 模版描述文件 完全路径 /// </summary> private string templateDiscriptionFilePath; public ExcelComManager() { } /// <summary> /// 根据Excel模版,创建Excel临时文件并传输 /// </summary> /// <param name="templatName">模版名</param> public void createExcelAndSend(string templatName, Object dataObject) { templateFilePath = getTemplatePath(templatName, ".xls"); //模板文件 templateDiscriptionFilePath = getTemplatePath(templatName, ".xml"); //模板描述文件 string tempFilePath = getTempFileName(); //临时文件全名 copyFile(templateFilePath, tempFilePath); //拷贝模版文件到临时文件夹 connectTempExcel(tempFilePath); //打开临时Excel文件 //这里应该根据不同的模版调用不同的写入方法 //还没有完成 writeExcelContent(dataObject); //操作临时Excel文件 sendExcelFile(tempFilePath, "cc.xls"); //发送文件到客户端 deleteTempFile(tempFilePath); //删除临时文件 } #region copy模版文件到指定目录 并改名 /// <summary> /// copy模版文件到指定目录 并改名 /// </summary> /// <param name="scrFile">要拷贝的原文件全路径名</param> /// <param name="destFile">要生成的目标文件的全路径名</param> /// <returns></returns> private void copyFile(string scrFile, string destFile) { try { System.IO.File.Copy(scrFile, destFile); } catch(Exception e) { throw new Exception("拷贝文件出错"); } } #endregion #region 删除临时Excel文件 /// <summary> /// 删除临时Excel文件 /// </summary> /// <param name="tempFile">临时文件全路径名</param> private void deleteTempFile(string tempFile) { try { System.IO.FileInfo file = new System.IO.FileInfo(tempFile); if(file.Exists){ file.Delete(); } } catch (Exception e) { throw new Exception("删除文件出错"); } } #endregion #region 打开临时Excel文件 /// <summary> /// 打开临时Excel文件,(copy过来的并改好名字的模版) /// </summary> /// <param name="filePath">Excel文件全路径名</param> public void connectTempExcel(string filePath) { try { ExcelObj = new Excel.ApplicationClass(); xBk = ExcelObj.Workbooks.Open(filePath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing); xSt = (Excel._Worksheet)xBk.ActiveSheet; } catch (Exception e) { close(); throw new Exception("打开Excel文件出错"); } } #endregion #region 连接Excel public void connectExcel() { try { object missing = System.Reflection.Missing.Value; //如果模版名为空 或 模版文件没有找到 则新建一个 if (string.IsNullOrEmpty(templateFilePath)) { xBk = ExcelObj.Workbooks.Add(true); } else { xBk = ExcelObj.Workbooks.Open(templateFilePath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing); if(xBk == null){ throw new Exception("打开模版文件出错"); } } xBk.SaveAs(getTempFileName(), Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); xSt = (Excel._Worksheet)xBk.ActiveSheet; } catch (Exception e) { close(); throw; } } #endregion #region 根据数据结果集, 修改临时文件内容 /// <summary> /// 根据数据结果集,修改临时文件内容 /// </summary> /// <param name="ds">要传入到Excel的数据集</param> /// <returns></returns> private void writeExcelContent(Object o) { try { ExcelObj.Visible = false; ExcelDescriptions a = new ExcelDescriptions(); Hashtable templateXml = a.parseXml(templateDiscriptionFilePath); WookSheetWrite wStW = new WookSheetWrite(xSt); wStW.setWorksheet(o, templateXml); //xSt.Cells[2, 2] = "aa"; //xSt.Cells[25, 2] = "aa"; //xRng = xSt.get_Range("B2", missing); //xRng.Value2 = "aa"; //xRng = xSt.get_Range(xSt.Cells[2, 2], xSt.Cells[2, 2]); //xRng.HorizontalAlignment = -4108; //xRng.Borders.LineStyle = 1; //如果用到 xRng = xSt.get_Range(xSt.Cells[2, 2], xSt.Cells[2, 2]); 就必须关掉 //否则系统里就会有一个没关掉的 Excel.exe进程 //System.Runtime.InteropServices.Marshal.ReleaseComObject(xRng); //xSt.Cells[2, 5] = "bb"; //xRng = xSt.get_Range(xSt.Cells[2, 5], xSt.Cells[2, 5]); //xRng.HorizontalAlignment = -4108; //xRng.Borders.LineStyle = 1; //System.Runtime.InteropServices.Marshal.ReleaseComObject(xRng); xBk.Save(); } catch (Exception e) { close(); throw new Exception(e.Message + "操作临时Excel文件时出错"); } finally { close(); } } #endregion #region 根据传入的模版名设置绝对路径中的模板名 /// <summary> /// 根据传入的模版名设置绝对路径中的模板名 /// </summary> /// <param name="strTemplateName">模板名</param> /// <returns></returns> private string getTemplatePath(string templateName, string postfix) { if (string.IsNullOrEmpty(templateName)) { throw new Exception("模版文件名为空"); } //从配置文件中读取,Excel模版文件存放位置 string templateFolderPath = System.Configuration.ConfigurationSettings.AppSettings["ExcelTemplatePath"]; if (string.IsNullOrEmpty(templateFolderPath)) { throw new Exception("没有找到模版文件夹路径"); } return templateFolderPath + templateName + postfix; } #endregion #region 生成临时文件的文件名 /// <summary> /// 设置保存到临时文件中的文件名。 /// 带路径的。 /// 这是一个线程安全的方法。 /// </summary> /// <returns>临时文件名</returns> [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)] private string getTempFileName() { string tempFilePath = System.Configuration.ConfigurationSettings.AppSettings["ExcelTempFilePath"]; String strFile = System.DateTime.Now.ToFileTimeUtc().ToString() + ".xls";//创建一个临时文件名 if (string.IsNullOrEmpty(tempFilePath)) { throw new Exception("没有找到临时文件路径"); } return tempFilePath + strFile; } #endregion #region 下载文件 /// <summary> /// /// 在网络上 传一个文件 /// /// </summary> /// <param name="srcFileName">要传输的文件的名字</param> /// /// <param name="newFileName">新的文件的名字</param> public void sendExcelFile(string srcFileName, string newFileName) { if (!string.IsNullOrEmpty(srcFileName)) { //这里应该判断srcFileName 是否是全路径名 //System.IO.FileInfo file = new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + srcFileName); System.IO.FileInfo file = new System.IO.FileInfo(srcFileName); if (file.Exists) { string FileName = newFileName; string ExtendName = file.Name; if (ExtendName.Length > 4) { int i = ExtendName.LastIndexOf("."); ExtendName = ExtendName.Substring(i); FileName += ExtendName; } //Response.AppendHeader(@"Content-Disposition", @"attachment;filename=" + HttpUtility.UrlEncode("报表.xls",System.Text.Encoding.UTF8)); //这句话中的 attachment 改成 inline 就可以了 HttpContext.Current.Response.Clear(); HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8)); HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString()); HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.Filter.Close(); HttpContext.Current.Response.WriteFile(file.FullName); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.Close(); //HttpContext.Current.Response.End(); } else { HttpContext.Current.Response.Write("对不起,文件" + AppDomain.CurrentDomain.BaseDirectory + srcFileName + "不存在"); } } } #endregion #region 关闭使用到的Excel进程 /// <summary> /// 关闭使用到的Excel进程 /// </summary> private void close() { //if的顺序不能变 if (ExcelObj != null) { if (xBk != null) { xBk.Close(null, null, null); } ExcelObj.Workbooks.Close(); ExcelObj.Quit(); } if (xRng != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(xRng); xRng = null; } if (xSt != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(xSt); xSt = null; } if (xBk != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(xBk); xBk = null; } if (ExcelObj != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelObj); ExcelObj = null; } GC.Collect(); } #endregion }
配置文件
<appSettings > <add key="ExcelTempaltePath" value="F:/koide_sufen/ExcelTemplate/"/> <add key="ExcelTempFilePath" value="F:/koide_sufen/ExcelTempFile/"/> </appSettings>
调用
protected void Button1_Click(object sender, EventArgs e) { ExcelComManager a = new ExcelComManager(); a.createExcelAndSend("LOTO_SAMPLE.xls"); }
vs2008下测试通过