要求使用Excel报告中的列数来标识报告

时间:2019-03-12 05:40:13

标签: sql-server excel ssis etl

我有两个Excel文件,我想将这些文件导入到SQL临时表中。

第一个Excel文件:

 T1      T2      T3     T4  Total
 1,472   1,364   1,422  –   4,258 
-152.6  -152.6  -152.6  –   
 1,958   1,939   1,942  –   
-122.6  -123.7  -122.2  – 

第二个Excel文件:

 T1       T2     T3     T4  T5       Total
 1,472   1,364   1,422  –   12.2     4,258 
-152.6  -152.6  -152.6  –   1000.12
 1,958   1,939   1,942  –   50.23
-122.6  -123.7  -122.2  –   185.25

SSIS中是否可以根据列数来标识文件?我需要根据列号来识别报告。

2 个答案:

答案 0 :(得分:0)

可以在C#脚本任务中使用Microsoft.Office.Interop.Excel命名空间中的

对象执行以下操作。本示例将文件名和列数输出到SSIS对象变量(User::SSISObjectVariable")中,该变量可用于在包中应用进一步的逻辑和处理,例如存储在数据库表中或其他方式。完整的文件路径是对象变量中的第一列,列数是第二列。另外,请确保在脚本中添加对Microsoft.CSharp命名空间的引用。对象变量将需要包含在脚本任务的ReadWriteVariables字段中,并且如果源文件夹存储在变量中(如下所述),则将该变量添加到ReadOnlyVariables字段中。

using Microsoft.Office.Interop.Excel;
using System.Data;
using System.IO;
using System.Collections.Generic;

    List<string> excelFileList = new List<string>();
//get source directory
string filePath = Dts.Variables["User::FilePathVariable"].Value.ToString();
DirectoryInfo di = new DirectoryInfo(filePath);

System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("FilePath", typeof(System.String));
dt.Columns.Add("ColumnCount", typeof(System.Int32));

foreach (FileInfo fi in di.EnumerateFiles())
{
    //optional- check file extension and prefix
    if (fi.Extension == ".xls" && fi.Name.StartsWith("Prefix"))
    {
        //get full file path
        excelFileList.Add(fi.FullName);
    }
}

foreach (string excelFile in excelFileList)
{

 Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); ;
 Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(excelFile);
 Microsoft.Office.Interop.Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[1];

 int columnCount;

//get number of columns
 columnCount = xlWorksheet.Cells.Find("*", System.Reflection.Missing.Value,
  System.Reflection.Missing.Value, System.Reflection.Missing.Value,
  Microsoft.Office.Interop.Excel.XlSearchOrder.xlByColumns, Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious,
  false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Column;

//build data row to hold file path and column count
 DataRow dr = dt.NewRow();
 dr["FilePath"] = excelFile;
 dr["ColumnCount"] = columnCount;

 dt.Rows.Add(dr);

 xlApp.Workbooks.Close();
 xlApp.Quit();

 xlWorkbook = null;
 xlApp = null;
}

GC.Collect();
GC.WaitForPendingFinalizers();

//populate object variable
Dts.Variables["User::SSISObjectVariable"].Value = dt;

答案 1 :(得分:0)

如果需要使用不同的架构导入Excel,则有两种方法:

(1)SSIS方法:脚本任务+ 2个数据流任务

如果只有两个结构,则可以按照以下步骤操作:

  1. 添加类型为System.Int32的变量,例如:@[User::ColumnsCount]
  2. 添加类型为System.String的变量来存储文件路径示例:@[User::FilePath]
  3. 添加脚本任务,并选择@[User::FilePath]作为ReadOnly变量,选择@[User::ColumnsCount]作为ReadWrite变量
  4. 在脚本Task内编写类似的脚本:

    string FilePath = Dts.Variables["User::FilePath"].Value.toString();
    string ExcelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;
                            "Data Source='" + FilePath + 
                            "';Extended Properties=\"Excel 12.0;HDR=YES;\"";
    
    using (OleDbConnection OleDBCon = new OleDbConnection(ExcelConnectionString))
            {
            if (OleDBCon.State != ConnectionState.Open)
                OleDBCon.Open();
    
                using (OleDbCommand cmd = new OleDbCommand(strcommand, OleDBCon))
                {
                    DataTable dtTable = new DataTable("Table1");
    
    
                    cmd.CommandType = CommandType.Text;
                    //replace Sheet1$ with the sheet name if it is different
                    cmd.CommandText = "SELECT * FROM Sheet1$"
                    using (OleDbDataAdapter daGetDataFromSheet = new OleDbDataAdapter(cmd))
                    {
                        daGetDataFromSheet.FillSchema(dtTable, SchemaType.Source);
                        Dts.Variables["User::ColumnsCount"].Value = dt.Columns.Count;
                    }
    
                }
    
            }
    
  5. 为每个Excel结构添加两个Data Flow任务

  6. 将脚本任务链接到这些数据流任务中的每一个
  7. 单击每个优先级约束(任务之间的链接),然后将优先级类型更改为“表达式”和“约束”,并为每种情况添加适当的表达式:

5列:

@[User::ColumnsCount] == 5

6列:

@[User::ColumnsCount] == 6
  1. 将两个数据流任务的Delay Validation属性设置为True

TL DR: 如果只有两个结构,则可以添加两个数据流任务(每个结构一个),然后可以使用脚本任务来标识列根据列数来计数并执行适当的数据流任务(使用优先约束表达式)。

(2)C#方法:SchemaMapper类库

最近,我在Github上启动了一个新项目,该项目是使用C#开发的类库。您可以使用它使用架构映射方法将Excel,Word,Powerpoint,文本,CSV,HTML,JSON和xml中的表格数据导入具有不同架构定义的SQL Server表中。在以下位置查看:

您可以按照此Wiki页面获取逐步指南: