3

问题:

我有一个 SSIS 包,它遍历 100 多个 Excel 文件并读取数据,然后将内容复制到 SQL Server 表中。在这些 Excel 文件中,这一列具有超链接。列文本本身类似于 DSH-LN-4,但在 Excel 中单击它会打开一个包含一些图像的文件夹。如何复制此列中的基础链接而不是单元格中的实际文本?

到目前为止我尝试了什么:

我还没有真正尝试过任何事情,因为我发现在 SSIS 中完全没有关于如何做到这一点的资源。无法手动向 Excel 文件添加一列,因为有 100 个文件。我发现的唯一资源是在这个 SO Question中,但这并不表示在不手动操作 Excel 文件的情况下执行此操作的过程。

我想要什么:

在我的 ForEach 循环容器中,我有一个数据流任务,它获取 Excel 内容并将其推送到 SQL 表中。包含超链接的列被调用PhotoReference(因为这些超链接打开了包含照片的文件夹)。我希望此PhotoReference列复制单元格的底层超链接并将其添加到 SQL 列。

例如,我希望该PhotoReference列包含以下内容:

www.companyname.box.com/asjdfbgkjb134kjbsdafo2bm21n4bk

如果我能做到这一点,我的 Power BI 报告运行这些基础数据可能包含一个可点击的文本,可以直接打开图像。

任何帮助,将不胜感激。

更新:

我可以尝试两种不同的方法从我的专栏中提取超链接,但每种方法都有自己的问题:

方法 1:我在ForEach容器中添加了一个脚本任务组件,并在循环每个 Excel 文件时,使用Microsoft.Office.Interop.Excel.Hyperlinks程序集从我的 Excel 列中获取超链接。但是,我不知道之后该怎么办。我认为唯一要做的就是用我提取的超链接覆盖 Excel 列的内容,但我真的不想以任何方式更改我的 Excel 文件。

方法 2:我在 Excel 源和 SQL 目标之间的数据流任务中添加了一个脚本组件对象。在这种方法中,我几乎无法做到这一点,因为Input0_ProcessInputRow自动生成的方法具有Rowtype的参数Input0Buffer。我无法将任何Microsoft.Office.Interop.Excel属性应用于我的Input0Buffer对象。所以我被困住了。

4

2 回答 2

2

如果您必须正确更改 excel 文件,您只需在数据流任务之前添加一个脚本任务,以将 URL 列值替换为超链接。

在这个答案中,我将提供解决此问题的分步解决方案:

创建 Excel 示例

首先,我创建了一些包含以下列的 Excel 文件:

  • 名字(文字)
  • 姓氏(文字)
  • 年龄(数)
  • 照片(超链接)

文件内容如下所示:

在此处输入图像描述

创建 SSIS 包

  1. 首先,您必须添加一个链接到您需要导入的 Excel 文件之一的 Excel 连接管理器。以及一个用于连接 SQL Server 实例的 OLE DB 连接管理器。
  2. 您必须添加一个字符串类型的 SSIS 变量,以便在使用 foreach 枚举器时存储 Excel 文件路径

在此处输入图像描述

  1. 添加一个 Foreach 循环容器并将其配置为遍历 Excel 文件,如下图所示:

在此处输入图像描述

在此处输入图像描述

  1. 在 Foreach 循环容器中添加一个脚本任务和一个数据流任务,如下图所示:

在此处输入图像描述

  1. 现在,打开数据流任务并添加 Excel 源和 OLE DB 目标并配置它们之间的列映射。

  2. 打开脚本任务配置,然后选择 ExcelFilePath 变量(在步骤 2 中创建)作为只读变量,如下图所示:

在此处输入图像描述

  1. 现在,打开脚本编辑器并在解决方案资源管理器窗口中,右键单击引用图标并单击“添加引用...”
  2. 当出现添加参考目录时,单击 COM 选项卡,然后搜索 Excel,然后您应该从结果中选择 Excel 对象库,如下图所示:

在此处输入图像描述

  1. 此外,请确保添加 Microsoft.CSharp.dll 引用。
  2. 在脚本的顶部,您应该添加以下行:

    using Excel = Microsoft.Office.Interop.Excel;
    using System.Runtime.InteropServices;
    
  3. 在 Main() 函数中添加以下行:

    Excel.Application excel = new Excel.Application();
    string originalPath = Dts.Variables["User::ExcelFilePath"].Value.ToString();
    Excel.Workbook workbook = excel.Workbooks.Open(originalPath);
    Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];
    Excel.Range usedRange = worksheet.UsedRange;
    int intURLColidx = 0;
    
    excel.Visible = false;
    excel.DisplayAlerts = false;
    
    for (int i = 1; i <= usedRange.Columns.Count; i++)
    {
    
    
        if ((worksheet.Cells[1, i] as Excel.Range).Value != null &&
            (string)(worksheet.Cells[1, i] as Excel.Range).Value == "Photo")
        {
    
            intURLColidx = i;
            break;
    
        }
    
    
    
    }
    
    for (int i = 2; i <= usedRange.Rows.Count; i++)
    {
    
        if ((worksheet.Cells[i, intURLColidx] as Excel.Range).Hyperlinks.Count > 0)
        {
            (worksheet.Cells[i, intURLColidx] as Excel.Range).Value2 = (worksheet.Cells[i, intURLColidx] as Excel.Range).Hyperlinks.Item[1].Address.ToString();
        }
    }
    
    workbook.Save();
    
    Marshal.FinalReleaseComObject(worksheet);
    
    workbook.Close(Type.Missing, Type.Missing, Type.Missing);
    Marshal.FinalReleaseComObject(workbook);
    
    excel.Quit();
    Marshal.FinalReleaseComObject(excel);
    Dts.TaskResult = (int)ScriptResults.Success;
    

在上面的行中,首先我们搜索包含超链接的列索引(在本例中,列名是“照片”,然后我们将检查每一行,如果超链接地址不为空,我们将用此替换列值超链接地址)

  1. 最后,确保将 Excel 连接管理器配置为使用表达式从创建的变量值(步骤 2)中读取文件路径:

在此处输入图像描述

实验

运行包后,如果我们打开一个 Excel 文件,我们会看到 Cell 值被替换为 URL:

在此处输入图像描述

如下图所示,数据成功导入SQL Server:

在此处输入图像描述


参考

于 2020-01-02T22:30:25.103 回答
0

您可能需要做的是一些涉及 Excel COM API 或宏的黑客行为。事实上,因为您应该远离在 SSIS 中使用 Office COM API。

您可以预处理 excel 以使用 SSIS 中的非标准操作获取该值,例如使用脚本组件。

以下是使用脚本组件导入该数据所需遵循的步骤:

  1. 拖放脚本组件并选择“源”作为脚本选项类型。

  2. 默认情况下,脚本语言是 Microsoft Visual C# 2008,我使用 Microsoft Visual Basic 2008 完成了这个示例。如果需要,可以更改它。

  3. 在“数据类型属性”中使用正确的数据类型定义输出列

  4. 编辑脚本。在 IDE 中,您应该添加参考:

    • Microsoft.Excel 11.0 对象库

(如果该参考不起作用,请尝试使用 Microsoft.Excel 5.0 对象库)

  1. 最后,写一些代码:

Imports Microsoft.Office.Interop.Excel 

Public Overrides Sub getHyperlink()
  Dim oExcel As Object = CreateObject("Excel.Application")
  Dim FileName As String
  FileName = Variables.FileName
  Dim oBook As Object = oExcel.Workbooks.Open(FileName)
  Dim oSheet As Object = oBook.Worksheets(1)
  Output0Buffer.AddRow()
  // change A1 with your correct col & row
  Output0Buffer.Address = cell.range("A1").Hyperlinks(1).Address & "#" & cell.range("A1").Hyperlinks(1).SubAddress

End Sub

(请记住,这是一个可能无法运行的代码,只是为了说明)

您可以在此处查看 C# 中的代码:SSIS 脚本任务中的 C# 脚本将“文本”格式的 Excel 列转换为“常规”

脚本方法的唯一问题是您需要安装 Excel 运行时。

更多关于脚本组件的信息: https ://www.tutorialgateway.org/ssis-script-component-as-transformation/

于 2020-01-02T19:23:01.620 回答