效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】) 转
效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】)
本文目录:
(一)背景
(二)数据库数据导入到Excel的方法比较
(三)SSIS的简介
(四)数据库中存储过程示例(SSIS应用需要)
(五)Excel模板的制作(这步这么简单,稍微介绍一下)
(六)SSIS操作过程(生成Package,用来调用)(下一篇随笔将详细讲解制作Package包的过程,图片太多,篇幅过长,因此本文将直接采用生成的Package包进行应用)
(七)C#中如何调用SSIS创建的Package和Excel模板(可以自己编写逻辑代码进行重复利用),用来生成Excel数据
(八)总结
(一)背景
如何将数据库中的数据导入到EXCEL文件中,我们经常会碰到。本文将比较常用的几种方法,并且将详细讲解基于SSIS的用法。笔者认为,基于SSIS的方法,对于海量数据来说,应该是效率最好的一种方法。个人认为,这是一种值得推荐的方法,因此,本人决定将本人所知道的、以及自己总结的完整的写出来,一是提高一下自己的写作以及表达能力,二是让更多的读者能够在具体的应用中如何解决将海量数据导入到Excel中的效率问题。
(二)方法的比较
方案一:SSIS(SQL Server数据集成服务),追求效率,Package制作过程复杂一点(容易出错)。
方案二:采用COM.Excel组件。一般,对于操作能够基本满足,但对于数据量大时可能会慢点。下面的代码,本人稍微修改了下,如下所示:该方法主要是对单元格一个一个的循环写入,基本方法为 excel.WriteValue(ref vt, ref cf, ref ca, ref chl, ref rowIndex, ref colIndex, ref str, ref cellformat)。当数据量大时,肯定效率还是有影响的。
方案三:采用Excel组件。一般,对于操作能够基本满足,但对于数据量大时可能会慢点。下面的代码,本人在原有基础上稍微修改了下,如下所示:

2 {
3 beforeTime = DateTime.Now;
4 Excel.Application excel;
5 Excel._Workbook xBk;
6 Excel._Worksheet xSt;
7 int rowIndex = 1;
8 int colIndex = 1;
9 excel = new Excel.ApplicationClass();
10 xBk = excel.Workbooks.Add(true);
11 xSt = (Excel._Worksheet)xBk.ActiveSheet;
12 int add=0;
13 foreach (System.Data.DataTable dt in dtList)
14 {
15 colIndex = 1;
16 //取得整个报表的标题
17 excel.Cells[rowIndex , 1] = smallTitle[add];
18 add++;
19 ////设置整个报表的标题格式
20 xSt.get_Range(excel.Cells[rowIndex, 1], excel.Cells[rowIndex , dt.Columns.Count]).Font.Bold = true;
21 xSt.get_Range(excel.Cells[rowIndex, 1], excel.Cells[rowIndex , dt.Columns.Count]).Font.Size = 22;
22 ////设置整个报表的标题为跨列居中
23 xSt.get_Range(excel.Cells[rowIndex , 1], excel.Cells[rowIndex , dt.Columns.Count]).Select();
24 xSt.get_Range(excel.Cells[rowIndex , 1], excel.Cells[rowIndex, dt.Columns.Count]).HorizontalAlignment = Excel.XlHAlign.xlHAlignCenterAcrossSelection;
25 rowIndex++;
26 foreach (DataColumn col in dt.Columns)
27 {
28 excel.Cells[rowIndex, colIndex] = col.ColumnName;
29 //设置标题格式为居中对齐
30 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).Font.Bold = true;
31 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter;
32 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).Select();
33 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).Interior.ColorIndex = titleColorindex;
34 colIndex++;
35 }
36 //取得表格中的数据
37 foreach (DataRow row in dt.Rows)
38 {
39 rowIndex++;
40 colIndex = 1;
41 foreach (DataColumn col in dt.Columns)
42 {
43 if (col.DataType == System.Type.GetType("System.DateTime"))
44 {
45 if (!string.IsNullOrEmpty(row[col.ColumnName].ToString()))
46 {
47 excel.Cells[rowIndex, colIndex] = (Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("yyyy-MM-dd");
48 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter; }
49 }
50 else if (col.DataType == System.Type.GetType("System.String"))
51 {
52 excel.Cells[rowIndex, colIndex] = "'" + row[col.ColumnName].ToString();
53 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter;r; }
54 else
55 {
56 excel.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
57 xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter; }
58 colIndex++;
59 }
60 }
61 rowIndex ++;
62 }
63 afterTime = DateTime.Now;
64 xSt.Name = strTitle;
65 string filename = typeName + DateTime.Now.ToString("yyyyMMdd") + ".xls";
66 // excel.Save(FilePath+filename);
67 excel.ActiveWorkbook.SaveCopyAs(FilePath + filename);
68 #region 结束Excel进程
69 xBk.Close(null, null, null);
70 excel.Workbooks.Close();
71 excel.Quit();
72 #endregion
73 return filename;
74 }

方法四:采用DataGrid,GridView自带的属性。如下:
(三)SSIS的简介
SQL Server 2005 提供的一个集成化的商业智能开发平台,主要包括:
*SQL Server Analysis Services(SQL Server数据分析服务,简称SSAS)
*SQL Server Reporting Services(SQL Server报表服务,简称SSRS)
*SQL Server Integration Services(SQL Server数据集成服务,简称SSIS)
SQL Server 2005 Integration Services (SSIS) 提供一系列支持业务应用程序开发的内置任务、容器、转换和数据适配器。可以创建 SSIS 解决方案来使用 ETL 和商业智能解决复杂的业务问题,管理 SQL Server 数据库以及在 SQL Server 实例之间复制 SQL Server 对象。
(四)数据库中存储过程示例(SSIS应用过程中需要的,最好拿个本子把需要的内容记下)
在SQL SERVER 2005中,以SSISDataBase数据库作为应用,仅包括2张表City,Province.(主要是为了简单,便于讲解)
其中存储过程如下:

(
@provinceId int=0
)
as
begin
select P.EName as 省份拼音,P.CName as 省份名,C.CName as 城市名 from City C left join Province P
on C.ProvinceId = P.ProvinceId
where C.ProvinceId =@provinceId and @provinceId is not null or @provinceId is null or @provinceId=0
end

其中,在这一步中我们必须要记住相关的内容,如上标识(红色);为什么这么做?主要是在制作SSIS包的时候很容易混淆,建议拿个本子把需要的内容写好。

这一步是最主要的过程,当然,也是很容易出错的一步。笔者会另外详细介绍制作Package包的过程,本文将直接将生成的包放到VS项目中进行运用。
利用SQL Server 2005数据库自带的SQL Server Business Intelligence Development Studio(SQL Server商业智能开发平台),最终生成的项目如下图所示:




2 {
3 //构造sql语句 作为参数传递给数据包
4 string sqlParams = Jasen.SSIS.Core.SsisToExcel.BuildSql("dbo.ProvinceSelectedCityInfo", "@provinceId", int.Parse(ddlProvice.SelectedValue));
5 Jasen.SSIS.Core.SsisToExcel ssis = new Jasen.SSIS.Core.SsisToExcel();
6 string rootPath = Request.PhysicalApplicationPath;
7 string copyFilePath;
8 //执行SSIS包的操作 生成EXCEL文件
9 bool result = ssis.ExportDataBySsis(rootPath, sqlParams, out copyFilePath, "Package.dtsx", "ProviceCityInfoExcel.xls", "ProviceCityInfo");
10 if (result == false){
11 if (System.IO.File.Exists(copyFilePath)) System.IO.File.Delete(copyFilePath);
12 }
13 else
14 {
15 ssis.DownloadFile(this, "ProviceCityInfoClientFile.xls", copyFilePath, true);
16 }
17 }

你肯定会说:“哥,你这个也太简单了吧?”。就是这么简单,不就是多写一个类给你调用就可以了吗。调用接口,这个你总会吧。不过你得了解各个参数才行。
首先,我们必须引用2个DLL,Microsoft.SQLServer.ManagedDTS.dll和Microsoft.SqlServer.DTSPipelineWrap.dll(系统自带的)。先看下我们生成Excel文件数据的步骤,如下:

/// 导出数据到EXCEL文件中
/// </summary>
/// <param name="rootPath"></param>
/// <param name="sqlParams">执行包的传入参数</param>
/// <param name="copyFile">生成的Excel的文件</param>
/// <param name="packageName">SSIS包名称</param>
/// <param name="execlFileName">SSIS EXCEL模板名称</param>
/// <param name="createdExeclPreName">生成的Excel的文件前缀</param>
/// <returns></returns>
public bool ExportDataBySsis(string rootPath, string sqlParams, out string tempExcelName, string packageName, string execlFileName, string createdExeclPreName)
{
//数据包和EXCEL模板的存储路径
string path = rootPath + @"Excel导出\";
//强制生成目录
if (!System.IO.Directory.Exists(path)) System.IO.Directory.CreateDirectory(path);
//返回生成的文件名
string copyFile = this.SaveAndCopyExcel(path, execlFileName, createdExeclPreName);
tempExcelName = copyFile;
//SSIS包路径
string ssisFileName = path + packageName;
//执行---把数据导入到Excel文件
return ExecuteSsisDataToFile(ssisFileName, tempExcelName, sqlParams);
}

代码注释如此清楚,想必也不需要再多做解释了吧,下面就是最最最重要的一步,需要看清楚了----->

2 {
3 Application app = new Application();
4 Package package = new Package();
5 //加载SSIS包
6 package = app.LoadPackage(ssisFileName, null);
7 //获取 数据库连接字符串
8 package.Connections["AdoConnection"].ConnectionString = Jasen.SSIS.Common.SystemConst.ConnectionString;
9 //目标Excel属性
10 string excelDest = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"EXCEL 8.0;HDR=YES\";", tempExcelName);
11 package.Connections["ExcelConnection"].ConnectionString = excelDest;
12 //给参数传值
13 Variables vars = package.Variables;
14 string str = vars["用户::SqlStr"].Value.ToString();
15 vars["用户::SqlStr"].Value = sqlParams;
16 //执行
17 DTSExecResult result = package.Execute();
18 if (result == DTSExecResult.Success){
19 return true;
20 }
21 else{
22 if (package.Errors.Count > 0){
23 //在log中写出错误列表
24 StringBuilder sb=new StringBuilder();
25 for (int i = 0; i < package.Errors.Count; i++){
26 sb.Append("Package error:" + package.Errors[i].Description +";");
27 }
28 throw new Exception(sb.ToString());
29 }
30 else{
31 throw new Exception("SSIS Unknow error");
32 }
33 return false;
34 }
35 }

上面标注为红色的就是最重要的几个步骤了,相对来说,就是(1)加载包,(2)设置包的数据库连接串,(3)设置Excel的连接串,(4)设置参数变量,(5)执行操作
其次是如何巧妙的将Excel模板复制,使模板可以重复利用(当然也要注意将生成的文件下载到客户端后,将服务器上生成的Excel临时文件删除,你也可以写自己的算法进行清理不必要的Excel临时文件),如下代码所示,方法将复制模板,然后返回生成的临时文件的路径,如果需要删除该文件,System.IO.File.Delete(filePath)就可以删除文件了:


效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】) 转的更多相关文章
- Unity读取Excel文件(附源代码)
今天想弄个Unity读取Excel的功能的,发现网上有许多方法,采用其中一种方法:加入库文件 Excel.dll 和ICSharpCode.SharpZipLib.dll库文件,(还有System.D ...
- 使用SSIS创建同步数据库数据任务
国外相关的文章:http://blog.dxuf.com/sql-tutorial/use-ssis-to-create-the-synchronization-database-data-task. ...
- [转]使用SSIS创建同步数据库数据任务
本文转自:http://www.cnblogs.com/heqichang/archive/2012/09/19/2693214.html SSIS(SQL Server Integration Se ...
- SQL JOB 调用 SSIS package 权限问题
来自: http://www.cnblogs.com/sodacc/archive/2012/11/26/2789135.html 第一次用SQL给SSIS包排JOB的时候,都会遇到这样一个问题:单独 ...
- SSIS获取Oracle数据库数据
获取Oracle数据库步骤如下: 1.目标服务器获取连接Oracle数据库权限2.安装Oracle客户端,名称为win32_11gR2_client 安装管理员版本的.3.将配置文件tnsnames. ...
- 配置ODBC DSN数据源,导出数据库数据到Excel过程记录
一.前言 工作中我们可能遇到这样的需要:查询数据库中的信息,并将结果导出到Excel文件.这本来没什么,但数据量比较大时,用PLSQL.toad导出Excel会出现内存不足等情况,使用odbc+Mic ...
- XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)
XML序列化 #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...
- jxl读数据库数据生成xls 并下载
1.所需jar jxl-2.6.10.jar jxls-core-1.0-RC-3.jar jxls-reader-1.0-RC-3.jar 2. excel修改行宽度封装 SheetColumn.j ...
- CAD二次开发---导入外部文件中的块并输出预览图形(五)
思路: 1)首先要定义一个数据库对象来表示包含块的文件,改数据库对象会被加载到内存中,但不会被显示在CAD窗口中. 2)调用Database类的ReadDwgFile函数将外部文件DWG文件读入到新创 ...
随机推荐
- Openstack的nova-network的vlan模式扩展
openstack的nova-network的vlan模式是可以在安装的时候,将网络划分为多个子网,每个项目一个或者多个子网进行虚拟机创建.但是他现在代码级别上不支持:如果一开始安装的环境的vlan网 ...
- php正则表达式 常用记录
一正则汉字匹配数字id 汉字 $str = '<a href="http://music.baidu.com/song/121353608" target="_bl ...
- GoLang语言
1 Go语言基础 1.1 语法详解 1.1.1 注释 /* regexp 包为正则表达式实现了一个简单的库. 该库接受的正则表达式语法为: 正则表达式: 串联 { '|' 串联 } 串联: { 闭包 ...
- redis和memcached
Redis 1.主从配置(主从复制不会阻塞master.) 1)bind 192.168.1.2(请修改成本机的IP地址,要不然,客户端无法进行访问) 2)slaveof 192.168.1.1 6 ...
- linux两台服务器之间文件/文件夹拷贝
跨服务器拷贝需要用到的命令是scp. ----------------------拷贝文件夹---------------------------------------------- 把当前文件夹t ...
- Masonry的使用
1.//添加了这个宏,就不用带mas_前缀了 #define MAS_SHORTHAND //添加了这个宏,equalTo就等于mas_equalTo #define MAS_SHORYHAND_G ...
- libevent源码分析:hello-world例子
hello-world是libevent自带的一个例子,这个例子的作用是启动后监听一个端口,对于所有通过这个端口连接上服务器的程序发送一段字符:hello-world,然后关闭连接. /* * gcc ...
- 浮动div中的图片垂直居中
table-cell方法垂直水平居中 <!DOCTYPE html> <html> <head> <meta name="description&q ...
- mysql 查询表,视图,触发器,函数,存储过程
1. mysql查询所有表: SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '数据库名' AND TAB ...
- java源代码跟踪
首先我们要学会的是将JDK源码加载Eclipse中. 1.点“窗口”——>"首选项",选择左边的"Java"——>"已安装的JRE&quo ...