在平时的项目中,将数据导出到Excel的需求是很常见的,在此对一些常见的方法做以总结,并提供一种大数据量导出的实现。

  • OLEDB

    使用OLEDB可以很方便导出Excel,思路很简单,处理时将Excel当做Access处理,利用SQL建表、插入数据。不多说了,直接看代码   

使用OLEDB导出Excel

public static void Export(DataTable dt, string filepath, string tablename)

{

//excel 2003格式

string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";

//Excel 2007格式

//string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=Excel 12.0 Xml;";

try

{

using (OleDbConnection con = new OleDbConnection(connString))

{

con.Open();

StringBuilder strSQL = new StringBuilder();

strSQL.Append("CREATE TABLE ").Append("[" + tablename + "]");

strSQL.Append("(");

for (int i = 0; i < dt.Columns.Count; i++)

{

strSQL.Append("[" + dt.Columns[i].ColumnName + "] text,");

}

strSQL = strSQL.Remove(strSQL.Length - 1, 1);

strSQL.Append(")");

OleDbCommand cmd = new OleDbCommand(strSQL.ToString(), con);

cmd.ExecuteNonQuery();

for (int i = 0; i < dt.Rows.Count; i++)

{

strSQL.Clear();

StringBuilder strfield = new StringBuilder();

StringBuilder strvalue = new StringBuilder();

for (int j = 0; j < dt.Columns.Count; j++)

{

strfield.Append("[" + dt.Columns[j].ColumnName + "]");

strvalue.Append("'" + dt.Rows[i][j].ToString() + "'");

if (j != dt.Columns.Count - 1)

{

strfield.Append(",");

strvalue.Append(",");

}

else

{

}

}

cmd.CommandText = strSQL.Append(" insert into [" + tablename + "]( ")

.Append(strfield.ToString())

.Append(") values (").Append(strvalue).Append(")").ToString();

cmd.ExecuteNonQuery();

}

con.Close();

}

Console.WriteLine("OK");

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}

public static void Export(DataTable dt, string filepath, string tablename)
{
    //excel 2003格式
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";
    //Excel 2007格式
    //string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=Excel 12.0 Xml;";
    try
    {
        using (OleDbConnection con = new OleDbConnection(connString))
        {
            con.Open();
            StringBuilder strSQL = new StringBuilder();
            strSQL.Append("CREATE TABLE ").Append("[" + tablename + "]");
            strSQL.Append("(");
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                strSQL.Append("[" + dt.Columns[i].ColumnName + "] text,");
            }
            strSQL = strSQL.Remove(strSQL.Length - 1, 1);
            strSQL.Append(")");

OleDbCommand cmd = new OleDbCommand(strSQL.ToString(), con);
            cmd.ExecuteNonQuery();

for (int i = 0; i < dt.Rows.Count; i++)
            {
                strSQL.Clear();
                StringBuilder strfield = new StringBuilder();
                StringBuilder strvalue = new StringBuilder();
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    strfield.Append("[" + dt.Columns[j].ColumnName + "]");
                    strvalue.Append("'" + dt.Rows[i][j].ToString() + "'");
                    if (j != dt.Columns.Count - 1)
                    {
                        strfield.Append(",");
                        strvalue.Append(",");
                    }
                    else
                    {
                    }
                }
                cmd.CommandText = strSQL.Append(" insert into [" + tablename + "]( ")
                    .Append(strfield.ToString())
                    .Append(") values (").Append(strvalue).Append(")").ToString();
                cmd.ExecuteNonQuery();
            }
            con.Close();
        }
        Console.WriteLine("OK");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

  生成的Excel是2003还是2007,就是通过连接字符串来控制的(代码中的connString ),同时传递的文件名也要一致(xls or xlsx),不然会出现运行不成功或者生成的文件打不开的情况。

  • Excel Com

  Excel本身提供com组件来实现对Excel的操作,它的优点是显而易见的,可以具体控制到操作excel中的任意一个单元格(内容+格式),利用oledb是做不到这一点的。当项目中需要使用现有模板生成Excel的时候使用该方法是很方便的。但该方法性能上慢,而且需要安装Excel相关组件,生成文件后内存中有时仍旧有Excel进程。如果是web的话不建议使用该方法,否则管理员和服务器都会疯掉的。

com生成Excel

public static void Export(DataTable dt, string filepath)

{

ExcelApp.Application myExcel = new ExcelApp.Application();

//新建文件

ExcelApp._Workbook mybook = myExcel.Workbooks.Add();

//打开现有文件

//ExcelApp._Workbook mybook = myExcel.Workbooks.Open(filepath, 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);

//打开文件在.net4.0中的写法,使用“命名参数”和“可选参数”

//ExcelApp._Workbook mybook = myExcel.Workbooks.Open(Filename: filepath);

myExcel.Visible = true;

try

{

mybook.Activate();

ExcelApp._Worksheet mysheet = mybook.Worksheets.Add();

for (int i = 0; i < dt.Rows.Count; i++)

{

for (int j = 0; j < dt.Columns.Count; j++)

{

ExcelApp.Range cell = mysheet.get_Range(((char)(65 + j)).ToString() + (i + 1).ToString());

cell.Select();

cell.Cells.FormulaR1C1 = dt.Rows[i][j] ?? "";

}

}

//mybook.SaveAs(Filename: filepath);

mybook.Save();

}

catch (Exception ex)

{

}

finally

{

mybook.Close();

myExcel.Quit();

GC.Collect();

}

}

public static void Export(DataTable dt, string filepath)
{
    ExcelApp.Application myExcel = new ExcelApp.Application();
    //新建文件
    ExcelApp._Workbook mybook = myExcel.Workbooks.Add();
    //打开现有文件
    //ExcelApp._Workbook mybook = myExcel.Workbooks.Open(filepath, 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);
    //打开文件在.net4.0中的写法,使用“命名参数”和“可选参数”
    //ExcelApp._Workbook mybook = myExcel.Workbooks.Open(Filename: filepath);
    myExcel.Visible = true;
    try
    {
        mybook.Activate();
        ExcelApp._Worksheet mysheet = mybook.Worksheets.Add();      
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                ExcelApp.Range cell = mysheet.get_Range(((char)(65 + j)).ToString() + (i + 1).ToString());
                cell.Select();
                cell.Cells.FormulaR1C1 = dt.Rows[i][j] ?? "";
            }
        }
        //mybook.SaveAs(Filename: filepath);
        mybook.Save();
    }
    catch (Exception ex)
    {
    }
    finally
    {
        mybook.Close();
        myExcel.Quit();
        GC.Collect();
    }
}

  在使用com组件时,需要先在项目中添加“Microsoft.Office.Interop.Excel”引用。(代码中的ExcelApp是我给相关命名空间提供的别名,using ExcelApp = Microsoft.Office.Interop.Excel;)

  • Open xml

  使用微软提供的Open XML SDK也可以很方便的生成excel。(将office2007(Word、Excel、PPT) 的文件后缀名修改为”.zip”,将得到的压缩包解压,发现里面就是xml文件。),具体代码我就不贴了,在使用中发现初始加载的时候也是比较慢的。

  需要注意的是,该方法只能操作office 2007以上的版本,不支持0ffice 2003.http://www.libxl.com/

  • NPOI

  这个是朋友介绍的,一个开源的组件,使用时不需要安装office(极大的优势),也能具体到对一个单元格的控制。NPOI是POI的.NET版本,POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 97-2003的文件,支持的文件格式包括xls, doc, ppt等。官网(已迁移到googlecode)上提供了许多实际例子,而且atao也给了介绍和入门教程,代码我就不复制了。

  需要注意的是,目前该方法只能操作office2003。

  • 大批量数据

  上面几种方法是比较常见的,但是当遇到大批量数据时,前两种就太不给力了,特别是使用com组件那种,它们都是一条一条的生成。不过,com中可以使用QueryTable来提高效率。

QueryTable批量导出数据

public static void Export( string filepath,string strSQL)

{

ExcelApp.Application myExcel = new ExcelApp.Application();

ExcelApp._Workbook mybook = myExcel.Workbooks.Add();

try

{

mybook.Activate();

ExcelApp._Worksheet mysheet = mybook.Worksheets.Add();

string conn = "ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;";

ExcelApp.QueryTable querytable = mysheet.QueryTables.Add(conn, mysheet.get_Range("A1"), strSQL);

querytable.Refresh(false);

mybook.SaveAs(Filename : filepath,AccessMode:ExcelApp.XlSaveAsAccessMode.xlNoChange);

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

finally

{

mybook.Close();

myExcel.Quit();

}

}

  该方法比一条一条的插入不知道要快上多少倍,但是在我这测试时发现不稳定,同样的代码第一天还很快,到第二天就很慢了(相差特别大),同时,也存在excel进程关不掉的问题。

既然这样,换个思路换个法子,既然一条一条的插入比较慢,那么批量插入呢,SQL语句中就有“select into”,能不能利用这个实现呢?查找资料后得知是可以的,在SQL Server中有OPENDATASOURCE(还有OPENROWSET)的 ,可以直接读取excel中 的数据。

SELECT * 
FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=D:\book.xls;Extended Properties=EXCEL 5.0')...[sheet1$] ;

  也可以写入,

insert into OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=D:\book.xls;Extended Properties=EXCEL 5.0')...[sheet1$]
select Customer .name ,Product .fullname
from [v_Order]

写入的话得要求该文件存在,并且第一行有数据(表头行)。

  在使用OPENDATASOURCE前,需要先执行

exec sp_configure 'Ad Hoc Distributed Queries','1'
RECONFIGURE

  不然的话会报错:“SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问”

  但是,使用OPENDATASOURCE是在SQL Server进程中执行的,这也就导致生成的文件时在SQL Server服务器端的,无法在客户端直接生成。

  也可以利用 BCP 来导出,速度上非常快,但是导出的Excel并不是标准格式的,如果客户不需要标准的格式,可以用这个来实现。

  既然SQL Server中可以这样做,在Access中是不是也可以呢?按照这个思路查找帮助,发现也是可以的,就是用in

select  * from product
in "" [ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;]

  在Access中运行上面的代码后,就可以查询中SQL Server数据库中的数据,不过不支持连接查询(用视图呗),而且要注意保留字的处理(字段添加“[]”)。 当然,使用in不仅仅支持SQL Server,对其他数据库也是支持的,可以看MSDN ,或者ACMAIN_CHM的这篇文章。

  刚开始的时候已经说过,在用Oledb处理Excel时可以把excel当做access,那么只需要将OLEDB导出Excel中的创建表、插入记录的SQL语句替换上面的查询语句就可以了(得将代码改为select into 才行,不然是生不成excel文件的),看看代码

public static void Export(string strSQL, string filepath)
{//string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=Excel 12.0 Xml;";try{using (OleDbConnection conn = new OleDbConnection(connString)){conn.Open();OleDbCommand cmd = new OleDbCommand(strSQL, conn);cmd.ExecuteNonQuery();conn.Close();}Console.WriteLine("OK");}catch (Exception ex){Console.WriteLine(ex.Message);}
}

使用上面的方法时,传递的SQL

select  * into 商品
from product
in "" [ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;]

如果需要添加where、orderby的话就放在上面SQL的后面(into后的表名在Excel中就是sheet的名称)

select  [fullname] as 名称,[alias] as 简称,[price] as 单价
into 商品
from product
in "" [ODBC;Driver=SQL Server;Server=.;uid=sa;pwd=sa;database=sample;]
where id_product  >1
order by fullname

大批量数据导出的时候,需要注意这样的一个问题,Excel2003格式一个sheet只支持65536行,excel 2007 就比较多,是1048576。

大数据导入Excel相关推荐

  1. Java操作大数据量Excel导入导出万能工具类(完整版)

    Java操作大数据量Excel导入导出万能工具类(完整版) 转载自:https://blog.csdn.net/JavaWebRookie/article/details/80843653 更新日志: ...

  2. 转:[Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!...

    引言 项目中常用到将数据导入Excel,将Excel中的数据导入数据库的功能,曾经也查找过相关的内容,将曾经用过的方案总结一下. 方案一 NPOI NPOI 是 POI 项目的 .NET 版本.POI ...

  3. 大数据量Excel Import导致OOM问题

    http://www.iteye.com/topic/199061 正在做一个Excel import的东东,不知道论坛上用POI的朋友有没有考虑过大数据量Excel文件导入导致内存溢出的问题 HSS ...

  4. SAP ABAP 使用 ALSM_EXCEL_TO_INTERNAL_TABLE 批导/上载大数据量 Excel (2)

    SAP ABAP 使用 ALSM_EXCEL_TO_INTERNAL_TABLE 批导/上载大数据量 Excel (2) 引言: 今时不同往日了,特别是在电商和零售行业中,动不动一个导入的 Excel ...

  5. matlab数组 xp,windowsxp系统将matlab数据导入excel的方法

    matlab是一款非常强大的商业数学软件,不仅能够读取Excel表格中的数据,还支持将matlab中的变量导入到Excel表格中.接下来,系统城小编就为大家分享windowsxp系统将matlab数据 ...

  6. Laravel 使用PHP_XLSXWriter实现大数据量Excel导出

    我在去年写过一篇关于laravel的Excel导出文章:Laravel Excel 实现 Excel/CSV 文件导入导出功能,使用的是Laravel Excel实现的. 该扩展包含Excel导入导出 ...

  7. SAP ABAP 探索 CL_FDT_XL_SPREADSHEET 读取大数据量 Excel 的可能性

    SAP ABAP 探索 CL_FDT_XL_SPREADSHEET 读取大数据量 Excel 的可能性 引言: 今时不同往日了,特别是在电商和零售行业中,动不动一个导入的 Excel 就有几十万行几十 ...

  8. php导出1万条数据excel_实用!用PHP导出百万级大数据到Excel

    实用!用PHP导出百万级大数据到Excel 作者:PHPYuan 时间:2018-07-31 03:41:41 关注我们的人 月薪都过万了 一.数据量分析 假设我们需要单日导入的数量为20W+ Exc ...

  9. python导入excel数据-如何把python中的数据导入excel

    python将数据导入excel的方法:1.在python官网下载xlrd第三方库:2.利用xlrd中的open_workbook函数读入excel文件,即可在python中导入excel数据. 一. ...

  10. openrowset excel 科学计数_txt的数据导入excel中身份证或银行卡显示成科学计数如何解决...

    用excel自带的"数据"->"自文本"将txt的数据导入excel中,如果数字特别长比如身份证或者银行卡会显示成科学计数法,如下: 借助sqlcel我们 ...

最新文章

  1. python基础作业第十四天
  2. 学习笔记:二叉搜索树的验证
  3. 使用Python SocketServer快速实现多线程网络服务器
  4. php callback 多线程,PHP cURL并发里的callback那行是什么效能
  5. 不知风险 何谈 5G?
  6. 面试鹅厂,我被虐的体无完肤。。。
  7. CE教程步骤8操作指南
  8. laypage分页java例子_laypage分页控件使用实例详解
  9. 举个栗子~Tableau 技巧(205 ):区域地图中呈现具体位置
  10. 华为2019实习生机试题1
  11. vue 使用html自带title属性 鼠标悬浮展示内容 修改其样式
  12. Effective c++笔记
  13. 点到点法式平面投影点的计算
  14. 有关凸集的证明例题_关于凸集、凸函数的一些证明
  15. android虚拟机固定横屏幕竖屏,用VBox虚拟机安装Android 屏幕90度翻转竖屏设置
  16. PHP前一页 后一页 切换
  17. Structured Program I – Print a Frame
  18. 乳山金岭中学校计算机老师,乳山市金岭中学
  19. Innovation Tour 2017暨Software AG中国区用户大会在京举行
  20. 微信小程序UI自动化实践:python+minium+PO模式(超详细教程附源码供下载)

热门文章

  1. GNS3模拟思科三层交换机(排错细节)
  2. 基于单片机的电子秤(数码管)系统设计(#0416)
  3. PCBA方案开发设计—咖啡秤厨房电子秤PCBA方案
  4. springboot 架构图
  5. Allatori java代码混淆
  6. 合并两个有序数组js
  7. 中国气象局发布实施细则 推进气象数据安全合规有序开放共享
  8. 酒店IPTV数字电视系统解决方案
  9. 基于FlexRay总线的汽车冗余线控转向系统的可靠性(FEMA)分析
  10. 上海电信中兴B860A 4K版破解