使用 SSIS 导入 Excel (.xlsx) 并使用包含多个小节的工作表导入 Excel 源

Import Excel (.xlsx) with SSIS and Excel source with worksheet containing multiple subsections

我需要你的帮助。

我有一个 .xlsx 文件,如下所示:

我的目标是创建一个 SSIS 包,将此数据推送到数据库 table。

现在,col1 到 col5 没问题,但是每个部分上面都有一个名称,应该是 table 中的第 6 列。 所以最终目的地 table 看起来像:

col1 | col2 | col3 | col4 | col5 | col6(从顶部开始的名字姓氏)

到目前为止我已经尝试过:

  1. 正在从 excel sheet
  2. 中创建记录集
  3. 使用 Ado foreach 枚举器逐行读取记录集
  4. 在每个枚举器中,我有一组代表列的变量
  5. 我将这些变量刷新到一个数据流任务中,该任务转换 使用派生列将变量添加到列并将其推入 ODBC 目标

显然这对我不起作用,当我 运行 包时,我总是收到消息“0 行插入到 ODBC 目标”。

老实说,我不太确定如何解决这个问题。

非常感谢任何帮助!!!

提前致谢!!!

编辑:

PS:我不能在这里使用任何一次或 Power BI / 查询技巧。它必须是纯 SSIS。

我会为此使用 Power Query。它内置于 Excel,也存在于 Power BI 和 Power Automate 中,并且具有比 SSIS 数据流更灵活的数据转换。您可以使用“M”(Power Query 语言)进行编码,但我很少这样做 - UI 几乎可以满足您的所有需求。

例如,一旦你想出一个计算列来创建“column6”,它就有一个“向下填充”功能,可以将每个组的值向下推到详细的行上。

这将是我计算“column6”的方法:

  1. 数据功能区/来自 Table/range。指定 sheet 和范围
  2. 在 Power Query 编辑器中,select [Column1],然后 Add Column / Extract / First Characters / 1
  3. Select [第一个字符],然后 转换/数据类型/整数
  4. Select [第一个字符],然后 替换值/替换错误/null
  5. 添加列/条件列,指定新列名称=“Column6”,如果“Column1”等于“column1”则为“null”否则如果“Column1”等于“null”然后 (Select 一列) [Column1] Else "null"
  6. Select[Column6],然后变换/填充/向下

获得有效查询后,您可以将 PQ 代码复制到 SSIS 的 PQ 源中:

https://docs.microsoft.com/en-us/sql/integration-services/data-flow/power-query-source

我能想到的解决办法,就是通过脚本任务,在这些步骤中

  1. 从第 4 行读取 Excel 文件
  2. 将名称添加到数据行的脚本任务
  3. 通过条件拆分删除列标题
  • 第一步打开 Excel 源属性,取消选择第一行中的列名称,并将 OpenRowset 设置为从第四行 (Sheet1$A4:E) 读取:

  • 第二步创建脚本组件转换。 Select 将 5 列作为输入并创建一个新的输出变量(在本例中为名称)

脚本本身:

public class ScriptMain : UserComponent
{


    string keepname;
    
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        if (Row.F5_IsNull)
            { keepname = Row.F1;
            
        }
        else
        {
            if (Row.F5 != "col5")
            {
                Row.Name = keepname;
            }

        }
    }
    
}

解释:检查它是否是包含名称的行(col5 为空),如果是,它将名称保存到变量 keepname。 如果不是那样,并且它不是标题 (col1='col1'),则更新变量名称。

  • 最后一步只是通过条件拆分进行清理

这样做的目的是拆分 'name rows' 或标题的行。你只需要携带一个默认输出即可。

测试:

我认为导入此类文件的最佳方法是创建一个脚本任务,将 Excel 文件转换为 CSV,然后将 CSV 作为简单的平面文件源上传到数据库中.

  1. 创建两个名为 VarDataPath 的变量,其中 Excel 文件的路径和 VarCSVPath 的 CSV 生成文件的路径。
  2. 使用以下 VB.net 片段创建脚本任务。不幸的是,目前我的电脑上没有 SSIS,所以我无法尝试我的代码。

导入系统 进口 System.Data 进口 System.Math 进口 Microsoft.SqlServer.Dts.Runtime

Public Class ScriptMain

Public Sub Main()

    Dim xl As Object
    Dim wb As Object
    Dim sh As Object
    Dim NumSheets As Integer

    Dim counter As Long

    Dim fs As Object
    Dim conv_file As Object
    Dim line As String

    Dim strDataPath As String = Dts.Variables("VarDataPath").Value.ToString() 'This variable contains the Excel path
    Dim strFileName As String = Dts.Variables("VarCSVPath").Value.ToString() 'This variable contains the CSV path

    Dim myArray As Integer() = New Integer() {4, 10, 16} ' Row number of FirstName/LastName

    xl = CreateObject("Excel.Application")
    wb = xl.WorkBooks.Open(strDataPath)
    sh = wb.Sheets(1)

    fs = CreateObject("Scripting.FileSystemObject")
    conv_file = fs.CreateTextFile(strFileName, True)

    ' CSV file head
    conv_file.writeline("Name,Col1,Col2,Col3,Col4,Col5")

    For Each val In myArray
    For a = 2 To 5 ' I have to loop all 4 rows of tables starting from 2 rows down the FirstName/LastName cell
    ' Each line I wrote valeu of Name,Col1,Col2,Col3,Col4,Col5
            line = ""
            line=line & sh.Cells(val, 1).ToString & ";" 'Name
            line=line & sh.Cells(val+a, 1).ToString & ";" 'Col1
            line=line & sh.Cells(val+a, 2).ToString & ";" 'Col2
            line=line & sh.Cells(val+a, 3).ToString & ";" 'Col3
            line=line & sh.Cells(val+a, 4).ToString & ";" 'Col4
            line=line & sh.Cells(val+a, 5).ToString & ";" 'Col5
            conv_file.writeline(line)
        Next
    Next
    
    
    conv_file.close()

    sh = Nothing
    wb.Close(False)
    wb = Nothing
    xl.Quit()
    xl = Nothing

    Dts.TaskResult = Dts.Results.Success
End Sub

结束Class

  1. 执行包让 SSIS 创建 CSV 文件。
  2. 在包中添加数据流,将生成的CSV上传到数据库中。

另外,你可以看看这些文章: