C#报表数据批量快速导出到Excel(百万级数据秒级内完成)

       我做的C#前端(winfor),在报表数据输出到Excel中大致分为两种方式:      

一种方式是把数据传输给后台,让后台制作成Excel文件之后返回给前端然后保存到客户的电脑上(速度秒级);      

还有一种方式是前端通过office或者wps插件将数据制作成Excel文件保存到客户端上(其中又分三种制作方法,      

1:一种是一格一格的对应数据填入Excel表格中(速度很慢);      

2:一种是以行为单位填入Excel表格中(比较快);      

3:最后一种是批量把数据组合成二维数组一次性填入Excel表格中(非常快))。

一、借用后台的方式(简单讲):

一般后台会以字符串(string)类型返回Excel文件(假设是reportData);

如果文件是压缩的则解压:reportData = StringConvert.unCompress(reportData);

得到Excel文件之后调用FolderBrowserDialog将文件输出到指定位置:

            FolderBrowserDialog frm = new FolderBrowserDialog();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    string resName = "test";
                    string path = frm.SelectedPath + "\\" + resName + ".xls";
                    FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                    byte[] data = JsonConvertor.DeserializeObject(reportData);
                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                    fs.Close();
                    ModuleBaseUserControl.ShowInfomation("导出完毕!路径:" + path);
                }
                catch (Exception ex)
                {
                    ModuleBaseUserControl.ShowError(ex.Message);
                }
            }

(后台的方法这里不做详细说明,只说C#前端的方法)。


二、C#前端

第一和第二种方法我就不说了,百度一下都能搜索到,第三中百度也能找到,个人觉得不够好,所以在此整理讲解一下。

假设现在我要导出SourceGrid数据到Excel表格中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SCFBaseLib;
using TYYW.AGTJ.Common;
using System.Drawing;
using System.Reflection;
using Microsoft.Office.Interop.Excel;

//以上是所需要的引用

#region 导出SourceGrid数据(最新版,批量快速输出)
        ///


        /// 导出SourceGrid数据
        ///

        /// SourceGrid
        /// 需要导出的行
        /// 需要导出的列

        //Excel导出的时候有两种软件插件可以使用(一种是office一种wps),因为各个插件的dll使用的方法不一样,因此要判断用户安装了哪个软件。
        public static void NewExportSourceGridCell(SourceGrid.Grid grid, List rowsStr, List colsStr)
        {

            //个人做的是政府项目,讲究国产化,在这里我先判断用户是否安装了wps。
            string excelType = "wps";
            Type type;
            type = Type.GetTypeFromProgID("ET.Application");//V8版本类型
            if (type == null)//没有安装V8版本
            {
                type = Type.GetTypeFromProgID("Ket.Application");//V9版本类型
                if (type == null)//没有安装V9版本
                {
                    type = Type.GetTypeFromProgID("Kwps.Application");//V10版本类型
                    if (type == null)//没有安装V10版本
                    {
                        type = Type.GetTypeFromProgID("EXCEL.Application");//MS EXCEL类型
                        excelType = "office";
                        if (type == null)
                        {
                            ModuleBaseUserControl.ShowError("检测到您的电脑上没有安装office或WSP软件,请先安装!");
                            return;//没有安装Office软件
                        }
                    }
                }
            }
            if (excelType == "wps")
            {
                WpsExcel(type, grid, rowsStr, colsStr);
            }
            else
            {
                OfficeExcel(type, grid, rowsStr, colsStr);
            }
        }


        //安装了wps

       
public static void WpsExcel(Type type, SourceGrid.Grid grid, List rowsStr, List colsStr)
        {
            dynamic _app = Activator.CreateInstance(type);  //根据类型创建App实例
            dynamic _workbook;  //声明一个文件
            _workbook = _app.Workbooks.Add(Type.Missing); //创建一个Excel
            ET.Worksheet objSheet; //声明Excel中的页
            objSheet = _workbook.ActiveSheet;  //创建一个Excel
            ET.Range range; 
            try
            {
                range = objSheet.get_Range("A1", Missing.Value);
                object[,] saRet = new object[rowsStr.Count, colsStr.Count];  //声明一个二维数组
                for (int iRow = 0; iRow < rowsStr.Count; iRow++)  //把sourceGrid中的数据组合成二维数组
                {
                    int row = rowsStr[iRow];
                    for (int iCol = 0; iCol < colsStr.Count; iCol++)
                    {
                        int col = colsStr[iCol];
                        saRet[iRow, iCol] = grid[row, col].Value;
                    }
                }
                range.set_Value(ET.ETRangeValueDataType.etRangeValueDefault, saRet);  //把组成的二维数组直接导入range
                _app.Visible = true;
                _app.UserControl = true;
            }
            catch (Exception theException)
            {
                String errorMessage;
                errorMessage = "Error: ";
                errorMessage = String.Concat(errorMessage, theException.Message);
                errorMessage = String.Concat(errorMessage, " Line: ");
                errorMessage = String.Concat(errorMessage, theException.Source);
                MessageBox.Show(errorMessage, "Error");
            }
        }

        //安装了office
public static void OfficeExcel(Type type, SourceGrid.Grid grid, List rowsStr, List colsStr)
        {
            dynamic _app = new Microsoft.Office.Interop.Excel.Application();
            dynamic _workbook;
            _workbook = _app.Workbooks.Add(true);
            _Worksheet objSheet;
            objSheet = _workbook.ActiveSheet;
            Range range;
            try
            {
                range = objSheet.get_Range("A1", Missing.Value);
                range = range.get_Resize(rowsStr.Count, colsStr.Count);
                object[,] saRet = new object[rowsStr.Count, colsStr.Count];
                for (int iRow = 0; iRow < rowsStr.Count; iRow++)
                {
                    int row = rowsStr[iRow];
                    for (int iCol = 0; iCol < colsStr.Count; iCol++)
                    {
                        int col = colsStr[iCol];
                        saRet[iRow, iCol] = grid[row, col].Value;
                    }
                }
                range.set_Value(Missing.Value, saRet);
                _app.Visible = true;
                _app.UserControl = true;
            }
            catch (Exception theException)
            {
                String errorMessage;
                errorMessage = "Error: ";
                errorMessage = String.Concat(errorMessage, theException.Message);
                errorMessage = String.Concat(errorMessage, " Line: ");
                errorMessage = String.Concat(errorMessage, theException.Source);
                MessageBox.Show(errorMessage, "Error");
            }
        }
#endregion

最后说明:需要注意的是在此引用了wps的 Kingsoft ET 2.0 Object Library(WPS需要用到 ET.dll 和 KSO.dll),在电脑中下载了wsp之后在引用的COM中引用。我的开发环境中在其它地方用到Microsoft.Office.Interop.Excel.dll,因此在声明Excel的时候默认是office的,WPS需要加上ET引用。


注:需要转载此文章请说明出处。











          

你可能感兴趣的:(C#)