我需要创建一个SSIS包,用于将数据从多个Excel文件导入SQL数据库。我计划使用嵌套的Foreach循环容器来实现这一目标。一个Foreach文件枚举器并嵌套在其中,一个Foreach ADO.net模式行集枚举器
需要考虑的问题:Excel文件的工作表名称不同,但结构保持不变。
我创建了一个Excel连接管理器,但Schema Rowset Enumerator不接受Enumerator配置中的连接管理器。
经过研究,我发现您可以使用Jet Ole数据库提供程序连接到excel文件。但是,我只能指定Microsoft Access数据库文件作为数据源。尝试插入Excel文件作为数据源失败
经过更多研究后,我发现您可以将Odbc数据提供程序与连接字符串而不是DSN一起使用。插入指定Excel文件的连接字符串后,这也失败了
我被告知不要使用脚本任务来实现这一点,即使在尝试最后一次努力从表单中提取数据后,通过索引访问表单我发现不同excel文件中表单的索引是不同的
非常感谢任何帮助
答案 0 :(得分:87)
这是一种可行的方法,基于这样的假设:Excel文件中不会有任何空白页,并且所有工作表都遵循完全相同的结构。此外,假设文件扩展名仅为.xlsx
以下示例是使用 SSIS 2008 R2 和 Excel 2007 创建的。此示例的工作文件夹为F:\Temp\
在文件夹路径F:\Temp\
中,创建一个名为States_1.xlsx
的Excel 2007电子表格文件,其中包含两个工作表。
Sheet 1
包含以下数据
States_1.xlsx 的
Sheet 2
包含以下数据
在文件夹路径F:\Temp\
中,使用两个工作表创建另一个名为States_2.xlsx
的Excel 2007电子表格文件。
Sheet 1
包含以下数据
States_2.xlsx 的
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
。 Foreach循环容器将为 FilePath 分配一个值,但我们需要一个有效的路径来开始设计时间,它当前填充了第一个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循环容器,如下所示:
配置名为循环表的第一个Foreach循环容器,如下所示:
在数据流任务中,放置Excel源,派生列和OLE DB目标,如下所示:
配置Excel源以读取相应的Excel文件和当前正在循环的工作表。
配置派生列以创建文件名和工作表名称的新列。这只是为了演示这个例子,但没有意义。
配置OLE DB目标以将数据插入SQL表。
下面的屏幕截图显示了包的成功执行。
下面的屏幕截图显示,在此答案开头创建的2个Excel电子表格中的4个工作簿中的数据已正确加载到SQL表dbo.Destination中。
希望有所帮助。
答案 1 :(得分:12)
我遇到了一篇文章,该文章说明了一种方法,在这种方法中,可以在选定的表中导入来自同一Excel工作表的数据,直到excel中没有对数据类型进行修改。
如果数据被新的插入或覆盖,导入过程将成功完成,数据将被添加到SQL数据库的表中。
可在此处找到该文章:http://www.sqlshack.com/using-ssis-packages-import-ms-excel-data-database/
希望它有所帮助。
答案 2 :(得分:0)
我遇到了类似的问题,发现尽快删除Excel文件要简单得多。作为我的软件包第一步的一部分,我使用Powershell将Excel文件中的数据提取到CSV文件中。我自己的Excel文件很简单,但这里
Extract and convert all Excel worksheets into CSV files using PowerShell
是Tim Smith关于从多个Excel文件和/或多个工作表中提取数据的优秀文章。
将Excel文件转换为CSV后,数据导入就不那么复杂了。