`
xufei0110
  • 浏览: 109281 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

c# 根据模版写Excel(Com) 一

    博客分类:
  • .net
阅读更多

原理很简单:

    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下测试通过

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics