.NET将数据导出到Excel表(如何指定默认文件名)

  在做项目的过程中将表格数据导出到excel保存起来这个功能基本上在桌面项目中都会被用到,网上写的例子也很多,我一开始也是参考的网上的代码。大部分人的做法是实例化一个Microsoft.Office.Interop.Excel.Application对象,然后再增加worksheet对象,然后往里头写入数据,这样相当于打开了一个excel,将保存的工作完全交给了用户,效果如图,

相应代码如下:

//实例化一个Excel.Application对象 
                    Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
                    excel.Visible = true;//设置为可见
                    //新增加一个工作簿,Workbook是直接保存,不会弹出保存对话框,加上Application会弹出保存对话框,值为false会报错 
                    excel.Application.Workbooks.Add(true);
                    //excel.Application.Workbooks.Application.AddChartAutoFormat
                    //生成Excel中列头名称 
                    excel.Cells[1, 1] = "列1";
                    excel.Cells[1, 2] = "列2";
                    excel.Cells[1, 3] = "列3";
                    excel.Cells[1, 4] = "列4";

                    //把datatable的数据保存在Excel中 data是一个DataTable
                    for (int i = 0; i <data.Count ; i++)
                    {
                        for(int j=0;j<4;j++)
                        {
                             excel.Cells[i+2,j+1]=data.Rows[i][j];
                         }
                        
                    }
                    //excel.Save(saveFile);
                    //设置禁止弹出保存和覆盖的询问提示框 
                    //excel.DisplayAlerts = false;
                    //excel.AlertBeforeOverwriting = false;
                    excel.Quit();
                    excel = null;

  这种方式简单,而且不需要考虑用户机器上安装的office版本问题,将处理都交给了用户,相当于用户新建了一个拥有数据的excel。但是这些有点都是站在开发者方面来说,从用户体验上来说不太好,一是突兀,突然就在用户面前打开了一个全屏的excel而且,还能看到哗哗的写入数据过程,这个过程应该被屏蔽的,第二点是无法指定默认的保存文件名,还得用户修改文件名才保存。

  那我们就可以改进一下,先用SaveFileDialog指定保存的文件名,并且得到保存后的文件完整的路径,然后将excel对象设为不可见,并调用excel对象的SaveAs方法保存后再用

excel.Quit()退出即可,这样就可以以一个用户看不见的过程完成导出数据到Excel。但是我在实施的时候又出现另外一个问题,就是这样的话保存的Excel是跟用户机器安装的Excel版本是一样的,比如我装的是2010,但是我用SaveFileDialog时却是用的.xls作为后缀,这样保存的时候成功了,当我打开时却提示我格式与内容不一致,当然也可以强行打开,但是显然这样会让用户以为有问题。

  难不成还要先判断用户安装的是什么版本的Excel,再来指定后缀名,查了一下,相当麻烦,得去注册表查,当然可能是我没找到简单的办法,不管怎样我决定换个思路了。之前因为是Microsoft.Office.Interop.Excel.Application是new出来的,内容自然是与调用的dll有关,但是如果我用Open方法打开一个03版的excel,那内容格式肯定是03版的了,相当于用Excel 2010打开一个xls后缀的文件,修改后再另存为,再关闭excel退出,过程类似,就可以实现我们指定文件名了。完整的方法如下,包括了指定sheet的名字。

     /// <summary>
        ///  将datatable导出到excel 03版的  通过模板控制导出的为03版 即xls后缀的
        /// </summary>
        /// <param name="data">datatable</param>
        /// <param name="headers">表头名称</param>
        /// <param name="sheetName">sheet的名称</param>
        /// <param name="savePath">保存路径</param>
        /// <returns></returns>
         public static bool Datatable2Xls(DataTable data,List<string> headers,string sheetName ,string savePath)
         {
             try
             {
                 //dev 的gridcontrol的这个方法在我的开发电脑上可以  但是装到别的电脑上就不行了 诡异
                 //DevExpress.XtraPrinting.XlsExportOptions options = new DevExpress.XtraPrinting.XlsExportOptions(true);
                 //gridControl1.ExportToXls(sfd.FileName, options);
                 //实例化一个Excel.Application对象 
                 Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
                 excel.Visible = false;
                 string source = Application.StartupPath + @"\data\template.xls";
                 //打开空白模版工作簿 模版为2003版的 如果是直接new的话会根据客户机上安装的excel版本来增加  这样导致了不确定性
                 Microsoft.Office.Interop.Excel._Workbook workbook = excel.Application.Workbooks.Open(source, Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                 // creating new Excelsheet in workbook
                 Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
                 // store its reference to worksheet
                 worksheet = workbook.ActiveSheet as Microsoft.Office.Interop.Excel._Worksheet;
                 if (sheetName != null && sheetName.Length > 0)
                 {
                     worksheet.Name = sheetName;
                 }
                 int rowStart = 1;//数据行起始位置
                 if (headers != null && headers.Count > 0)
                 {
                     for (int i = 0; i < headers.Count; i++)
                     {
                         excel.Cells[1, i + 1] = headers[i];
                     }
                     rowStart = 2;
                 }

                 //把DataTable的数据保存在Excel中 
                 for (int i = 0; i < data.Rows.Count ; i++)
                 {
                     for (int j = 0; j < data.Columns.Count; j++)
                     {
                         excel.Cells[i + rowStart, j + 1] = data.Rows[i][j].ToString();
                     }
                 }
                 excel.DisplayAlerts = false;
                 //设置禁止弹出保存和覆盖的询问提示框 
                 excel.AlertBeforeOverwriting = false;
                 // save the application
                 workbook.SaveAs(savePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                 excel.Quit();
                 excel = null;
                 return true;
             }
             catch (Exception ex)
             {
                 Trace.WriteLine(ex);
                 return false;
             }
         }

 


posted @ 2013-05-06 10:03  ValiancyHe  阅读(715)  评论(0编辑  收藏  举报