我试图建立一个SSIS包来读取Excel。我发现了一个很好的例子 此处 这是非常接近我所需要的。
我的问题是。从一个空白的解决方案开始,有什么最低限度的步骤 需要让C#脚本组件从一个.xlsx文件中读取?
这是我的代码。
using System;
using System.Data;
using System.Data.OleDb;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
string fileName = @"E:\SFTP\RSS\Results.xlsx";
string cstr = "Provider.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
using (OleDbConnection xlConn = new OleDbConnection(cstr))
{
xlConn.Open();
OleDbCommand xlCmd = xlConn.CreateCommand();
xlCmd.CommandText = "Select top 10 * from Responses";
xlCmd.CommandType = CommandType.Text;
using (OleDbDataReader rdr = xlCmd.ExecuteReader())
{
while (rdr.Read())
{
for (int i = 2; i < rdr.FieldCount; i++) //loop from 3 column to last
{
Output0Buffer.AddRow();
Output0Buffer.Question = rdr.GetName(i);
Output0Buffer.Response = rdr.ToString();
}
}
}
xlConn.Close();
}
}
}
这些是我遇到的问题,我的问题是: 我需要在解决方案层面配置连接管理器吗?在脚本组件上还是代码中包含了我需要的所有内容?
我用什么datatypefunctionmethod来读取一个单元格为数字、日期或字符串?
以下是我得到的一些错误。
(2,14): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'System' (are you missing an assembly reference?)
(3,14): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'System' (are you missing an assembly reference?)
(4,17): error CS0234: The type or namespace name 'SqlServer' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)
(5,17): error CS0234: The type or namespace name 'SqlServer' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)
(8,27): error CS0246: The type or namespace name 'UserComponent' could not be found (are you missing a using directive or an assembly reference?)
+ additional 10 errors
我使用的是: VS2019, SQL Server 2016 SP2, Office 2016.
这是我的Excel Sheet的屏幕截图。
它包含了一个第三方呼叫中心提供的调查问卷的回复。有几个列来识别呼叫,然后每个列头包含问题,列数据是响应。它目前有189列,并将随着时间的推移而增长变化。我的想法是选择前4列,可靠地识别每行加上1列额外的每一个Q&amp;A,并迭代通过表拿起每个列头和内容,以便可以插入到一个表中。当添加更多的列时,它们就会被追加为额外的行。我粘贴的示例代码只显示了2列,因为我想让这个例子简单一些。
这是我试过的方法.1.在ControlFlow中添加一个DataFlow任务。在控制流中添加一个DataFlow任务。
当提示选择源。
双击并打开编辑器。
选择连接管理器。单击 "添加"。
在新行中选择新建连接。
出现添加新的SSIS连接管理器。
这就是我卡住的地方。我一直选择OLEDB连接。
我已经尝试了Access和MS Oledb Simple Provider。事情到这里就开始变得扑朔迷离了。既然脚本中提供了文件名、路径和驱动细节,那么我需要连接管理器的什么细节呢?
我开始玩代码,但我不知道我在上游所做的是否有效或正确。所以我想从头开始。我请求大家帮助我走过设置步骤,以达到C#点。
谢谢大家的回复。
欢呼
皮特
脚本组件GUI中除了输出之外,没有什么需要添加的东西(记得要把数据类型弄正确。
不要设置连接管理器,你是在代码中做的,因为你不希望SSIS试图弄清你的列名,坦白说,我们不知道第4列之后的列名。
这是你的代码。我只修改了一些东西。
public override void CreateNewOutputRows()
{
//Change this to your filename you do not need a connection manager
string fileName = @"E:\SFTP\RSS\Results.xlsx";
string SheetName = "Sheet1";
string cstr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
using (System.Data.OleDb.OleDbConnection xlConn = new System.Data.OleDb.OleDbConnection(cstr))
{
xlConn.Open();
System.Data.OleDb.OleDbCommand xlCmd = xlConn.CreateCommand();
xlCmd.CommandText = "Select * from [" + SheetName + "$]"; //I assume this is the data you want
xlCmd.CommandType = CommandType.Text;
using (System.Data.OleDb.OleDbDataReader rdr = xlCmd.ExecuteReader())
{
while (rdr.Read())
{
for (int i = 4; i < rdr.FieldCount; i++) //loop from 5th column to last
{
//The first 4 columns are static and added to every row
Output0Buffer.AddRow();
Output0Buffer.UniqueID = Int32.Parse(rdr[0].ToString());
Output0Buffer.Year = Int32.Parse(rdr[1].ToString());
Output0Buffer.ReportingWave = rdr.GetString(2);
Output0Buffer.SubmissionDate = rdr.GetString(3);
Output0Buffer.Question = rdr.GetName(i);
Output0Buffer.Answer = rdr.GetString(i);
}
}
}
xlConn.Close();
}
}
这段代码成功导入了一个文件,这个文件看起来是这样的。