C#导出数据到Excel的两种方式:基于COM组件和NPIO

来源:互联网 发布:golang defer return 编辑:程序博客网 时间:2024/06/05 16:48

基于项目需求,需要将程序中的数据导出到Excel表格中,我在网上发现有很多这方面的资料,比较常见的是基于COM组件的,即使用之后 Microsoft.Office.Interop.Excel.Application进行导出,逻辑相对较简单;另一种则是使用NPIO类库中的方法,看起来稍微复杂一些,但是效率要高很多。

基于COM组件的Excel导出

1.使用该方法需要先在项目中引用这两个命名空间:Microsoft.Office.Interop.Excel;System.Reflection。
2.New一个Microsoft.Office.Interop.Excel.Application,并设置其属性。如果app为null,则说明该计算机上没有安装Excel应用程序,缺乏必要的组件。

 Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); app.Visible = false;  app.UserControl = true;

3.创建工作薄_Worksheet

 Microsoft.Office.Interop.Excel.Workbooks workbooks = app.Workbooks; Microsoft.Office.Interop.Excel._Workbook workbook = workbooks.Add();  Microsoft.Office.Interop.Excel.Sheets sheets = workbook.Sheets; Microsoft.Office.Interop.Excel._Worksheet worksheet =   (Microsoft.Office.Interop.Excel._Worksheet)sheets.get_Item(1); //第一个工作薄。 if (worksheet == null)    return; worksheet.Columns.AutoFit(); //自动调整列宽。

4.写入数据
4.1.先写入列头

worksheet.Cells[1, 1] ="时间s";worksheet.Cells[1, 2] = "温度℃";

4.2写入内容,将点列表 List list中的数据写入Excel

 for (int i = 0; i <list.Count; i++)    {       int row_ = 1 + i;  //Excel模板上列头1行,根据实际模板需要修改;       worksheet.Cells[row_, 1] =list[i].X;       worksheet.Cells[row_, 2] =list[i].Y;    }

5.保存成Excel文件

  string savaPath ="test.xls";//保存路径  workbook.SaveAs(aFilePath, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

6.使用 app.Quit();退出。这一句很重要,若不在导出完成后使用该句代码结束New的Excel进程,则后台中会一直存在该进程,只能通过打开资源管理器手动结束该进程。

调用NPIO类库来导出Excel

1.添加NPIO.DLL的引用。如需下载该DLL,请点这里:NPIO.DLL下载
2.添加以下几个命名空间:

  • using NPOI.HSSF.UserModel;
  • using NPOI.SS.UserModel;
  • using NPOI.HPSF;

3.创建工作薄并插入行数据

            HSSFWorkbook workbook = new HSSFWorkbook();            ISheet sheet = workbook.CreateSheet();            try            {                ICellStyle dateStyle = workbook.CreateCellStyle();                IDataFormat format = workbook.CreateDataFormat();                dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");                IRow headerRow = sheet.CreateRow(0);  //列头行                ICellStyle headStyle = workbook.CreateCellStyle();                headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;                IFont font = workbook.CreateFont();                font.FontHeightInPoints = 12;                font.Boldweight = 600;                headStyle.SetFont(font);                headerRow.CreateCell(0).SetCellValue("时间s");                headerRow.GetCell(0).CellStyle = headStyle;                headerRow.CreateCell(1).SetCellValue("温度℃");                headerRow.GetCell(1).CellStyle = headStyle;                for (int i = 0; i < list.Count; i++)                {                    int row_ = 1 + i;  //Excel模板上列头占了1行                    IRow aCellRow = sheet.CreateRow(row_);     aCellRow.CreateCell(0).SetCellValue(list[i].X);                    aCellRow.GetCell(0).CellStyle = aCellStyle;                    aCellRow.CreateCell(1).SetCellValue(list[i].Y);                    aCellRow.GetCell(1).CellStyle = aCellStyle;                }

4.将工作薄内容添加到MemoryStream并保存

  using (MemoryStream ms = new MemoryStream())       {          workbook.Write(ms);          ms.Flush();          ms.Position = 0;          using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))            {                byte[] data = ms.ToArray();                fs.Write(data, 0, data.Length);                fs.Flush();                data = null;            }         }

两种方法的比较

经过两种方法测试比较,使用COM方法要比NPIO方法,效率低很多,且导出的数据量大时,COM方法会直接报错,提示“系统调用失败。 (异常来自 HRESULT:0x80010100 (RPC_E_SYS_CALL_FAILED))。原因通常是创建此 RuntimeCallableWrapper 的 COM 上下文 0x1fd3200 已断开连接,或者该上下文正忙于执行其他操作”。以下截图是我保存较少的相同数据量时耗时比较(约2K行数据,共五列),供大家参考。
耗时比较

写在后面的话

第一次认真分析C#中导出数据到Excel的代码,收获还是挺多的。虽然现在对两种方法的了解还不是很深入,只是会简单的使用,但期待自己能有更深入的学习,也希望大家能多多鼓励,指出我的不足与错误,相互学习共同进步!

0 0
原创粉丝点击