c# - 在 SSIS .net 脚本任务中格式化 Excel 列

标签 c# excel ssis etl script-task

我有一个构建 Excel 文件的脚本任务。业务需要以特定方式格式化的特定列。代码在下面,我很好奇是否有办法使用现有流程来格式化列,或者一旦创建并加载它,然后格式化列?
更新:我决定做的是让 OLE 进程完成它并创建文件,然后编写一些互操作代码来格式化文件,但似乎 OLE 进程正在锁定文件,可能 Excel 只是在背景。我找不到任何不同的方法来确保 OLE 连接完全关闭。我还尝试将互操作部分放在不同的任务中,但在尝试打开文件时出现某种版本错误。
错误:
System.Runtime.InteropServices.COMException (0x800A03EC):无法访问“TA_Enrollment__106648_20210518.xlsx”。
在 Microsoft.Office.Interop.Excel._Workbook.SaveAs(对象文件名,对象文件格式,
对象密码、对象 WriteResPassword、对象 ReadOnlyRecommended、对象 CreateBackup、XlSaveAsAccessMode AccessMode、
对象 ConflictResolution、对象 AddToMru、对象 TextCodepage、对象 TextVisualLayout、对象本地)
任何帮助将不胜感激。

namespace ST_62506028876e4b65a061b3af2dd116ff
{
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {
        public void Main()
        {
            string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
            try
            {
                //Declare Variables
                string EnrollmentExcelName = Dts.Variables["User::EnrollmentExcelName"].Value.ToString();
                string EnrollmentExcelFolderPath = Dts.Variables["User::EnrollmentExcelFolderPath"].Value.ToString();
                string EnrollmentTable = Dts.Variables["User::EnrollmentTable"].Value.ToString();
                string EnrollmentExcelDataSheet = Dts.Variables["User::EnrollmentExcelDataSheet"].Value.ToString();
                string FileName = Dts.Variables["User::TRANSAM_Elig_var"].Value.ToString();

                int startIndex = 3;
                int length = 6;
                String substring = FileName.Substring(startIndex, length);

                EnrollmentExcelName = EnrollmentExcelName + "_" + substring + "_" + datetime;
                string sql1 = @"SELECT BLAH BLAH BLAH FROM ";
                string sql2 = @" ORDER BY SSN,SORTORDER";

                OleDbConnection Excel_OLE_Con = new OleDbConnection();
                OleDbCommand Excel_OLE_Cmd = new OleDbCommand();

                //Construct ConnectionString for Excel
                string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + EnrollmentExcelFolderPath + EnrollmentExcelName
                    + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"";

                //drop Excel file if exists
                File.Delete(EnrollmentExcelFolderPath + "\\" + EnrollmentExcelName + ".xlsx");

                //USE ADO.NET Connection from SSIS Package to get data from table
                SqlConnection myADONETConnection = new SqlConnection();
                myADONETConnection = (SqlConnection)(Dts.Connections["ADO_DataFeed_DB"].AcquireConnection(Dts.Transaction) as SqlConnection);

                //Load Data into DataTable from SQL ServerTable
                // Assumes that connection is a valid SqlConnection object.
                // ... doing data stuff and things...
               }
                Excel_OLE_Con.Close();
                Dts.TaskResult = (int)ScriptResults.Success;
            
               // Formatting the file once closed...
               Microsoft.Office.Interop.Excel.Application excelApplicaiton = new Microsoft.Office.Interop.Excel.Application();

                excelApplicaiton.Visible = false;
                excelApplicaiton.DisplayAlerts = false;

                Microsoft.Office.Interop.Excel.Workbook excelWorkbook =
                excelApplicaiton.Workbooks.Add(Type.Missing);

                excelWorkbook = excelApplicaiton.Workbooks.Open(Filename: EnrollmentExcelFolderPath + "\\" + EnrollmentExcelName + ".xlsx");

                
                // Format columns to numeric B,L,M,S,T,AA,AB,AH,AJ,AK and AM
                Range cells = excelWorkbook.Worksheets[1].Cells;
                cells[1, 2].EntireColumn.NumberFormat = "#";
                cells[1, 12].EntireColumn.NumberFormat = "#";
                cells[1, 13].EntireColumn.NumberFormat = "#";
                cells[1, 19].EntireColumn.NumberFormat = "#";
                cells[1, 20].EntireColumn.NumberFormat = "#";
                cells[1, 27].EntireColumn.NumberFormat = "#";
                cells[1, 28].EntireColumn.NumberFormat = "#";
                cells[1, 34].EntireColumn.NumberFormat = "#";
                cells[1, 36].EntireColumn.NumberFormat = "#";
                cells[1, 37].EntireColumn.NumberFormat = "#";
                cells[1, 39].EntireColumn.NumberFormat = "#";

                excelWorkbook.SaveAs(EnrollmentExcelFolderPath + "\\" + EnrollmentExcelName + ".xlsx",
                    Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
                    false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

                excelWorkbook.Close();
                excelApplicaiton.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApplicaiton);



               }
            catch (Exception exception)
            {

                // Create Log File for Errors
                using (StreamWriter sw = File.CreateText(Dts.Variables["User::EnrollmentExcelFolderPath"].Value.ToString() + "\\" +
                    Dts.Variables["User::EnrollmentExcelName"].Value.ToString() + datetime + ".log"))
                {
                    sw.WriteLine(exception.ToString());
                    Dts.TaskResult = (int)ScriptResults.Failure;

                }
            }
        }

        #region ScriptResults declaration
        /// <summary>
        /// This enum provides a convenient shorthand within the scope of this class for setting the
        /// result of the script.
        /// 
        /// This code was generated automatically.
        /// </summary>
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

    }
}

最佳答案

根据您提供的 C# 代码,脚本任务使用 System.Data.Oledb命名空间类(OledbCommand、OledbConnection)连接到 Excel 文件。 OLE DB 将 Excel 文件作为关系数据库处理。例如,它强制每列使用一种数据类型,而 Excel 允许每列使用多种数据类型。
也许使用 System.Data.Oledb 命名空间类是从 Excel 读取数据的最简单方法,但它有很多限制,并且仅用于执行 CRUD 操作。要更改单元格的格式,您应该使用 Microsoft.Office.Interop.Excel或第三方库。
Interop.Excel 入门

  • How to access Office interop objects (C# Programming Guide)
  • C# Excel Interop Example
  • C# Excel Tutorial

  • 使用 Interop.Excel 格式化 Excel 单元格
  • How to format an Excel file using C#
  • 关于c# - 在 SSIS .net 脚本任务中格式化 Excel 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67390857/

    相关文章:

    c# - StructureMap ObjectFactory.Reset 内存泄漏?

    c# - 检查 File.Exists() 是否提高写入速度

    excel - VBA中如何使用不等于条件与通配符?

    ssis - 向动态收件人发送电子邮件 SSIS 发送邮件任务

    SSIS:插入/更新

    c# - 条形码到产品名称转换器

    c# - Richtextbox - 撤消时?

    从系统日期开始的 VBA 周数

    正则表达式确保范围内的每个数字都匹配一次

    excel - 如何在 SSIS 表达式中获取 Excel 文件名的一部分