在 SSIS .net 脚本任务中格式化 Excel 列
Format Excel Columns in SSIS .net Script Task
我有一个构建 Excel 文件的脚本任务。业务需要以特定方式格式化的特定列。代码在下面,我很好奇是否有一种方法可以使用现有的过程来格式化列,或者如果创建并加载后,然后格式化列?
更新:我决定让 OLE 进程做它的事情并创建文件,然后编写一些互操作代码来格式化文件,但似乎 OLE 进程正在锁定文件,可能是 Excel 只是在后台保持打开状态。我找不到任何不同的方法来确保 OLE 连接完全关闭。我还尝试将 Interop 部分放在不同的任务中,但在尝试打开文件时出现某种版本错误。
错误:
System.Runtime.InteropServices.COMException (0x800A03EC):无法访问 'TA_Enrollment__106648_20210518.xlsx'。
在 Microsoft.Office.Interop.Excel._Workbook.SaveAs(对象文件名、对象文件格式、
对象密码、对象 WriteResPassword、对象 ReadOnlyRecommended、对象 CreateBackup、XlSaveAsAccessMode AccessMode、
对象冲突解决、对象 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 个单元格
我有一个构建 Excel 文件的脚本任务。业务需要以特定方式格式化的特定列。代码在下面,我很好奇是否有一种方法可以使用现有的过程来格式化列,或者如果创建并加载后,然后格式化列?
更新:我决定让 OLE 进程做它的事情并创建文件,然后编写一些互操作代码来格式化文件,但似乎 OLE 进程正在锁定文件,可能是 Excel 只是在后台保持打开状态。我找不到任何不同的方法来确保 OLE 连接完全关闭。我还尝试将 Interop 部分放在不同的任务中,但在尝试打开文件时出现某种版本错误。
错误: System.Runtime.InteropServices.COMException (0x800A03EC):无法访问 'TA_Enrollment__106648_20210518.xlsx'。 在 Microsoft.Office.Interop.Excel._Workbook.SaveAs(对象文件名、对象文件格式、 对象密码、对象 WriteResPassword、对象 ReadOnlyRecommended、对象 CreateBackup、XlSaveAsAccessMode AccessMode、 对象冲突解决、对象 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