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<byte[]>(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数据(最新版,批量快速输出)
        /// <summary>
        /// 导出SourceGrid数据
        /// </summary>
        /// <param name="grid">SourceGrid</param>
        /// <param name="rowsStr">需要导出的行</param>
        /// <param name="colsStr">需要导出的列</param>

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


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











          

  • 9
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
具体内容请参考我的BLOG:http://blog.csdn.net/smallwhiteyt/archive/2009/11/08/4784771.aspx 如果你耐心仔细看完本文,相信以后再遇到导出EXCLE操作的时候你会很顺手觉得SO EASY,主要给新手朋友们看的,老鸟可以直接飘过了,花了一晚上的时间写的很辛苦,如果觉得对你有帮助烦请留言支持一下,我会写更多基础的原创内容来回报大家。 C#导出数据EXCEL表格是个老生常谈的问题了,写这篇文章主要是给和我一样的新手朋友提供两种导出EXCEL的方法并探讨一下导出的效率问题,本文中的代码直接就可用,其中部分代码参考其他的代码并做了修改,抛砖引玉,希望大家一起探讨,如有不对的地方还请大家多多包涵并指出来,我也是个新手,出错也是难免的。 首先先总结下自己知道的导出EXCEL表格的方法,大致有以下几种,有疏漏的请大家补充。 1.数据逐条逐条的写入EXCEL 2.通过OLEDB把EXCEL做为数据源来写 3.通过RANGE范围写入多行多列内存数据EXCEL 4.利用系统剪贴板写入EXCEL 好了,我想这些方法已经足够完成我们要实现的功能了,方法不在多,在精,不是么?以上4中方法都可以实现导出EXCEL,方法1为最基础的方法,意思就是效率可能不是太高,当遇到数据量过大时所要付出的时间也是巨大的,后面3种方法都是第一种的衍生,在第一种方法效率低下的基础上改进的,这里主要就是一个效率问题了,当然如果你数据量都很小,我想4种方法就代码量和复杂程度来说第1种基本方法就可以了,或当你的硬件非常牛逼了,那再差的方法也可以高效的完成也没有探讨的实际意义了,呵呵说远了,本文主要是在不考虑硬件或同等硬件条件下单从软件角度出发探讨较好的解决方案。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值