如何遍历 Excel 文件并使用 SSIS 包将它们加载到数据库中?
Posted
技术标签:
【中文标题】如何遍历 Excel 文件并使用 SSIS 包将它们加载到数据库中?【英文标题】:How to loop through Excel files and load them into a database using SSIS package? 【发布时间】:2011-11-16 17:24:47 【问题描述】:我需要创建一个 SSIS 包,用于将多个 Excel 文件中的数据导入 SQL 数据库。我计划使用嵌套的 Foreach 循环容器来实现这一点。一个 Foreach 文件枚举器并嵌套在其中,一个 Foreach ADO.net 架构行集枚举器
要考虑的问题:Excel 文件之间的工作表名称不同,但结构保持不变。
我创建了一个 Excel 连接管理器,但架构行集枚举器不接受枚举器配置中的连接管理器。
经过研究,我发现您可以使用 Jet Ole db 提供程序连接到 excel 文件。但是,我只能将 Microsoft Access 数据库文件指定为数据源。尝试插入 Excel 文件作为数据源失败
经过更多研究,我发现您可以使用带有连接字符串而不是 DSN 的 Odbc 数据提供程序。在插入指定 Excel 文件的连接字符串后,这也失败了
我被告知不要使用脚本任务来完成此任务,即使在尝试从工作表中提取数据的最后努力之后,通过索引访问工作表我发现不同 excel 文件中工作表的索引是不同的
任何帮助将不胜感激
【问题讨论】:
文件名以“.xslx”结尾。文件枚举器搜索这些文件:“[wildcard].xls[wildcard]”。 Excel 连接管理器自动检测到格式为“Microsoft Excel 2007”。 【参考方案1】:这是一种可行的方法,它假设 Excel 文件中没有任何空白工作表,并且所有工作表都遵循完全相同的结构。另外,假设文件扩展名只有.xlsx
以下示例是使用 SSIS 2008 R2 和 Excel 2007 创建的。这个例子的工作文件夹是F:\Temp\
在文件夹路径F:\Temp\
中,创建一个名为States_1.xlsx
的Excel 2007 电子表格文件,其中包含两个工作表。
Sheet 1
包含以下数据
Sheet 2
of States_1.xlsx 包含以下数据
在文件夹路径 F:\Temp\
中,创建另一个名为 States_2.xlsx
的 Excel 2007 电子表格文件,其中包含两个工作表。
Sheet 1
包含以下数据
Sheet 2
包含以下数据
使用以下创建脚本在 SQL Server 中创建一个名为 dbo.Destination 的表。 Excel 工作表数据将插入到此表中。
CREATE TABLE [dbo].[Destination](
[Id] [int] IDENTITY(1,1) NOT NULL,
[State] [nvarchar](255) NULL,
[Country] [nvarchar](255) NULL,
[FilePath] [nvarchar](255) NULL,
[SheetName] [nvarchar](255) NULL,
CONSTRAINT [PK_Destination] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO
该表当前为空。
创建一个新的 SSIS 包并在包上创建以下 4 个变量。 FolderPath 将包含存储 Excel 文件的文件夹。 FilePattern 将包含将循环通过的文件的扩展名,此示例仅适用于.xlsx
。 FilePath 将由 Foreach 循环容器分配一个值,但我们需要一个有效的路径作为设计时的开始,并且它当前填充了第一个 Excel 文件的路径 F:\Temp\States_1.xlsx
。 SheetName 将包含实际的工作表名称,但我们需要填充初始值 Sheet1$
以避免设计时错误。
在包的连接管理器中,使用以下配置创建一个 ADO.NET 连接,并将其命名为 ExcelSchema。
在 .Net Providers for OleDb 下选择提供程序 Microsoft Office 12.0 Access Database Engine OLE DB Provider
。提供文件路径F:\Temp\States_1.xlsx
单击左侧的All
部分并将属性扩展属性设置为Excel 12.0
以表示Excel 的版本。在这种情况下,12.0 表示Excel 2007
。点击测试连接,确保连接成功。
创建一个名为 Excel 的 Excel 连接管理器,如下所示。
创建一个名为 SQLServer
的 OLE DB 连接 SQL Server。所以,我们应该在包上有三个连接,如下所示。
我们需要对连接字符串进行如下更改,以便 Excel 文件在文件循环时动态更改。
在连接 ExcelSchema 上,配置表达式 ServerName
以使用变量 FilePath
。点击省略号按钮配置表达式。
同样在连接Excel上,配置表达式ServerName
使用变量FilePath
。单击省略号按钮以配置表达式。
在控制流上,将两个 Foreach 循环容器放在另一个中。第一个Foreach Loop container
命名的循环文件将循环遍历这些文件。第二个Foreach Loop container
将通过容器内的工作表。在每个循环容器的内部,放置一个数据流任务,它将读取 Excel 文件并将数据加载到 SQL 中
配置第一个名为循环文件的Foreach循环容器,如下所示:
配置第一个名为 Loop sheet 的 Foreach 循环容器,如下所示:
在数据流任务中,放置一个 Excel Source、Derived Column 和 OLE DB Destination,如下所示:
配置 Excel 源以读取适当的 Excel 文件和当前正在循环的工作表。
配置派生列以创建文件名和工作表名称的新列。这只是为了演示这个例子,没有任何意义。
配置 OLE DB 目标以将数据插入 SQL 表。
下面的截图显示了包的成功执行。
下面的屏幕截图显示,在此答案开头创建的 2 个 Excel 电子表格中的 4 个工作簿中的数据已正确加载到 SQL 表 dbo.Destination 中。
希望对您有所帮助。
【讨论】:
谢谢西瓦。这是一个有用的答案。然而,它一直在我这边失败。一天结束时,我最终编写了一个 Powershell 脚本来检测目标工作表并更改名称。使所有工作表都具有相同的名称来引用它们。谢谢你的回答 这对我很有用。起初它一直失败,这是因为我必须将调试 64 位设置为 FALSE。为此,请转到 Project --> YourProjectProperties --> Debugging --> Run64BitRuntime = FALSE 这非常有用,但我想让文件名动态化,我不想每次都自己放文件名。有没有可能? 抱歉,我不明白本示例中使用的 ExcelSchema 连接管理器是什么。请问有人能解释一下吗?【参考方案2】:我遇到了一篇文章,该文章说明了一种方法,该方法可以将同一 Excel 工作表中的数据导入所选表中,直到 Excel 中没有数据类型的修改。
如果数据被插入或被新数据覆盖,则导入过程将成功完成,并将数据添加到SQL数据库的表中。
文章可以在这里找到:http://www.sqlshack.com/using-ssis-packages-import-ms-excel-data-database/
希望对你有帮助。
【讨论】:
【参考方案3】:我遇到了类似的问题,发现尽快删除 Excel 文件要简单得多。作为我包中第一步的一部分,我使用 Powershell 将 Excel 文件中的数据提取到 CSV 文件中。我自己的 Excel 文件很简单,但在这里
Extract and convert all Excel worksheets into CSV files using PowerShell
是 Tim Smith 撰写的一篇关于从多个 Excel 文件和/或多个工作表中提取数据的优秀文章。
一旦将 Excel 文件转换为 CSV,数据导入就不会那么复杂了。
【讨论】:
以上是关于如何遍历 Excel 文件并使用 SSIS 包将它们加载到数据库中?的主要内容,如果未能解决你的问题,请参考以下文章
将数据从平面文件加载到 Sql Server 表,并使用 SSIS 导出到 excel
SSIS 包将文件从一个文件夹移动到 SFTP (WinSCP) 中的另一个文件夹(SSIS 的 SFTP 任务)