【问题标题】:C# Script in SSIS Script Task to convert Excel Column in "Text" Format to "General"SSIS脚本任务中的C#脚本将“文本”格式的Excel列转换为“常规”
【发布时间】:2019-12-18 23:22:06
【问题描述】:

我正在使用 SSIS 数据流任务将数据从 SQL Server 导出到 Excel。尽管导出格式,这里所有列都显示为文本。因此,我需要开发一个 SSIS 脚本任务来进行必要的转换。我在开发脚本时遇到了麻烦。

格式化前的 Excel 工作簿

请看,Excel 单元格没有撇号,数字类型也是“常规”,但消息显示 此单元格中的数字格式为文本或前面有撇号

我尝试了互联网上的不同选项,但没有成功。

#region Namespaces
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
#endregion

namespace ST_de899f405b7b4083b0ad8cba6b3df2e3
{

[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
    public void Main()
    {
        string inputFile = (string)Dts.Variables["Target_FullFilePath"].Value;
        Excel.Application ExcelApp = new Excel.Application();
        Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(inputFile);
        Excel.Range formatRange;
        ExcelApp.Visible = true;

        foreach (Excel.Worksheet ExcelWorksheet in ExcelWorkbook.Sheets)
        {
            ExcelWorksheet.Select(Type.Missing);
            ExcelWorksheet.Columns[2].NumberFormat = "";
            ExcelWorksheet.Columns[3].NumberFormat = "";
            ExcelWorksheet.Columns[4].NumberFormat = "0.00000";
            ExcelWorksheet.Columns[5].NumberFormat = "yyyy-MM-dd";
        }

        ExcelWorkbook.Save();

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

        ExcelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
        Marshal.FinalReleaseComObject(ExcelWorkbook);

        ExcelApp.Quit();
        Marshal.FinalReleaseComObject(ExcelApp);
    }   
    enum ScriptResults
    {
        Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
        Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
    };
    #endregion
}
}

预期结果:编号为 B、C、D看起来像十进制/整数的列,也经过类似过滤。 列 E看起来像 Date 并且也进行了类似的过滤。

这是我希望 Excel 文件在通过 SSIS 格式化后的样子

我确认对应的列只有列标题之外的相关值。

【问题讨论】:

  • 我将编辑您的问题并提及您正在导出到 Excel。 CSV(文本文件)是一种选择吗?您还应该描述您的实际问题 - 为什么它不成功?
  • 尼克,csv/文本文件不是一个选项...虽然我可以导出 CSV/TXT 并将其转换为 Excel,如果这能解决我的需要...谢谢。跨度>

标签: c# excel visual-studio ssis number-formatting


【解决方案1】:

在提供解决方案之前,我必须解释一下Excel数字格式的一些要点

什么是数字格式属性?

参考Number format codes 文档:

您可以使用数字格式来更改数字的外观,包括日期和时间,无需更改实际数字。数字格式不会影响 Excel 用于执行计算的单元格值。实际值显示在公式栏中。

什么是通用编号格式?

参考Reset a number to the General format文档:

常规格式是 Excel 在您键入 数字 时应用的默认数字格式。在大多数情况下,使用常规格式格式化的数字会以您键入它们的方式显示。

日期如何存储在 Excel 中?

参考How Dates Work in Excel:

Excel 中的日期实际上是存储为数字,然后格式化显示日期。

您的例外结果

你提到过:

预期结果:编号为 16、17、22 的列将转换为“常规”并且看起来像十进制数字。 第 31 列将被转换为“常规”并且看起来像日期

根据我们提到的内容,您无法将第 31 列转换为“常规”并使其看起来像日期。

解决方案

您只需将NumberFormat 属性设置为空字符串即可将其设置为“常规”

ExcelWorksheet.Columns[16].NumberFormat = "";

实验

我创建了一个包含 4 列的 Excel 文件:NumberColumn、DateColumn、DecimalColumn 和 StringColumn,如上图所示:

我使用以下代码创建了一个控制台应用程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputFile = @"D:\Test.xlsx";

            Excel.Application ExcelApp = new Excel.Application();
            Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(inputFile);
            ExcelApp.Visible = true;

            foreach (Excel.Worksheet ExcelWorksheet in ExcelWorkbook.Sheets)
            {
                ExcelWorksheet.Select(Type.Missing);

                ExcelWorksheet.Columns[1].NumberFormat = "";
                ExcelWorksheet.Columns[2].NumberFormat = "yyyy-MM-dd"; // convert format to date
                ExcelWorksheet.Columns[2].NumberFormat = "";
                ExcelWorksheet.Columns[3].NumberFormat = "0.00000"; // convert format to decimal with 5 decimal digits
                ExcelWorksheet.Columns[3].NumberFormat = "";
                ExcelWorksheet.Columns[4].NumberFormat = "";


            }
            ExcelWorkbook.Save();

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

            ExcelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
            Marshal.FinalReleaseComObject(ExcelWorkbook);

            ExcelApp.Quit();
            Marshal.FinalReleaseComObject(ExcelApp);
        }
    }
}

执行应用程序后,Excel 如下所示:

讨论与结论

从上图中,我们可以看到所有列都更改为通用数字格式,但如果值存储为数字,它们将按存储时显示:日期值显示为 Excel 序列号(数字),十进制值仅显示一位小数,即使我们在将格式重置为常规之前将格式更改为五位。

简而言之,当数字格式为“常规”时,您无法处理值的显示方式,如果您需要将值显示为日期,则必须将数字格式设置为 yyyy-MM-dd 或任何其他日期格式。

参考


更新 1

不要使用ExcelWorksheet.Columns[1].NumberFormat,而是尝试使用以下代码:

ExcelWorksheet.Cells[1,1].EntireColumn.NumberFormat = "";
ExcelWorksheet.Cells[1,2].EntireColumn.NumberFormat = "";

【讨论】:

  • 非常感谢@Hadi 抽出时间来解决我的问题。但是,很抱歉,它仍然没有解决问题。最初,Excel 中的数据是“列格式为文本”。如果将光标移动到单元格的左上角,则会显示“此单元格中的数字格式化为文本或前面用撇号。” .. 尽管 数字格式是通用的,但它仍然存在。 我使用了您的代码。正如您提到的,这改变了列类型,但 此单元格中的数字仍保持为文本格式。 。请您进一步提出建议。
  • 我不知道如何在此处添加屏幕截图以供进一步参考。
  • 既然你提到了the text is preceded by an apostrophe,那么你必须删除它,因为它强制文本格式,即使数字格式属性不是文本。如果您需要一些帮助来编写代码,请回复我。或者如果不需要自动执行此步骤,只需从 excel 中替换它
  • 不,文本没有撇号,它只是该列中被格式化为文本的数字......这就是我想要转换的。我上面的引用是在 Excel 中针对特定单元格显示的 Msg,当对它执行 Text to Column 操作时。告诉你背后的原因。我正在从 SQL Server 中提取数据。数据偶数和日期在 Excel 中保存为文本。要转换它们,我需要在 Excel 中执行文本到列操作并将其保存为常规。手动...我正在尝试通过 SSIS 执行此操作
  • 我已经用 Excel“现有”和“必需”的屏幕截图更新了问题。请查看...非常感谢您抽出宝贵时间。
猜你喜欢
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多