C#可变Excel文件输出循环

时间:2018-12-03 11:48:17

标签: c# excel ssis

我曾用for循环在SSIS软件包上进行此操作的问题,但我一直遇到错误(数据类型转换问题),所以我决定涉猎C#。

我有这个工作代码:

#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
using System.Data.OleDb;
using System.Data.SqlClient;
#endregion

namespace ST_6704c764a25b4ffa92f62385be46f235
{

    [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 ExcelFileName = Dts.Variables["User::ExcelFileName"].Value.ToString();
                string FolderPath = Dts.Variables["User::FolderPath"].Value.ToString();
                string TableName = Dts.Variables["User::TableName"].Value.ToString();
                string SheetName = Dts.Variables["User::SheetName"].Value.ToString();
                ExcelFileName = ExcelFileName + "_" + datetime;

                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=" + FolderPath + ExcelFileName
                    + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"";

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

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




                //Load Data into DataTable from SQL ServerTable
                // Assumes that connection is a valid SqlConnection object.
                string queryString =
                  "SELECT Post_Advice, Purchase_order, Article from " + TableName;
                SqlDataAdapter adapter = new SqlDataAdapter(queryString, myADONETConnection);
                DataSet ds = new DataSet();
                adapter.Fill(ds);


                //Get Header Columns
                string TableColumns = "";

                // Get the Column List from Data Table so can create Excel Sheet with Header
                foreach (DataTable table in ds.Tables)
                {
                    foreach (DataColumn column in table.Columns)
                    {
                        TableColumns += column + "],[";
                    }
                }

                // Replace most right comma from Columnlist
                TableColumns = ("[" + TableColumns.Replace(",", " Text,").TrimEnd(','));
                TableColumns = TableColumns.Remove(TableColumns.Length - 2);
                //MessageBox.Show(TableColumns);


                //Use OLE DB Connection and Create Excel Sheet
                Excel_OLE_Con.ConnectionString = connstring;
                Excel_OLE_Con.Open();
                Excel_OLE_Cmd.Connection = Excel_OLE_Con;
                Excel_OLE_Cmd.CommandText = "Create table " + SheetName + " (" + TableColumns + ")";
                Excel_OLE_Cmd.ExecuteNonQuery();


                //Write Data to Excel Sheet from DataTable dynamically
                foreach (DataTable table in ds.Tables)
                {
                    String sqlCommandInsert = "";
                    String sqlCommandValue = "";
                    foreach (DataColumn dataColumn in table.Columns)
                    {
                        sqlCommandValue += dataColumn + "],[";
                    }

                    sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
                    sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
                    sqlCommandInsert = "INSERT into " + SheetName + "(" + sqlCommandValue.TrimEnd(',') + ") VALUES(";

                    int columnCount = table.Columns.Count;
                    foreach (DataRow row in table.Rows)
                    {
                        string columnvalues = "";
                        for (int i = 0; i < columnCount; i++)
                        {
                            int index = table.Rows.IndexOf(row);
                            columnvalues += "'" + table.Rows[index].ItemArray[i] + "',";

                        }
                        columnvalues = columnvalues.TrimEnd(',');
                        var command = sqlCommandInsert + columnvalues + ")";
                        Excel_OLE_Cmd.CommandText = command;
                        Excel_OLE_Cmd.ExecuteNonQuery();
                    }

                }
                Excel_OLE_Con.Close();
                Dts.TaskResult = (int)ScriptResults.Success;
            }
            catch (Exception exception)
            {

                // Create Log File for Errors
                using (StreamWriter sw = File.CreateText(Dts.Variables["User::FolderPath"].Value.ToString() + "\\" +
                    Dts.Variables["User::ExcelFileName"].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

    }
}

我所缺少的是,这将生成1个文件,其中包含查询的所有结果。

我想运行2个查询,第一个查询创建以下结果:

var post_adv int
    Select distinct Post_advice from TableName;
adapter.fill(post_adv)

然后,我希望上述查询以如下查询循环运行:

select * from TableName where Post_advice=post_adv

还必须将FileName设为Post_advice,而不是当前变量。

在使第二个查询也要执行时,我遇到了一些困难。

这是我第一次尝试使用C#,并且花了一些时间阅读,但是我对此很陌生:)

感谢所有帮助!

编辑:

此问题的解决方案:

public void Main()
        {
            string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");



            //Declare Variables

            string FolderPath = Dts.Variables["User::FolderPath"].Value.ToString();
            string TableName = Dts.Variables["User::TableName"].Value.ToString();
            string SheetName = Dts.Variables["User::SheetName"].Value.ToString();

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



            //USE ADO.NET Connection for the loop initialisation
            SqlConnection myADONETConnection2 = new SqlConnection();
            myADONETConnection2 = (SqlConnection)(Dts.Connections["DBConn"].AcquireConnection(Dts.Transaction) as SqlConnection);
            //Load data into the loop table
            string queryString2 =
       "SELECT distinct PO from " + TableName;
            SqlDataAdapter adapter = new SqlDataAdapter(queryString2, myADONETConnection2);
            var table2 = new DataTable();
            adapter.Fill(table2);
            var numberofrows = table2.Rows.Count;
            for (int i = 0; i < numberofrows; i++)
            {
                try
                {
                    var cell = table2.Rows[i]["PO"];

                    string ExcelFileName = (string)cell;
                    ExcelFileName = ExcelFileName + "_" + datetime;

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

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

                    //USE ADO.NET Connection from SSIS Package to get data from table

                    SqlConnection myADONETConnection = new SqlConnection();
                    myADONETConnection = (SqlConnection)(Dts.Connections["DBConn"].AcquireConnection(Dts.Transaction) as SqlConnection);


                    //Load Data into DataTable from SQL ServerTable
                    // Assumes that connection is a valid SqlConnection object.
                    string queryString =
                      "SELECT * from " + TableName + "where PO=" + cell;
                    SqlDataAdapter adapter2 = new SqlDataAdapter(queryString, myADONETConnection);
                    DataSet ds = new DataSet();
                    adapter2.Fill(ds);


                    //Get Header Columns
                    string TableColumns = "";

                    // Get the Column List from Data Table so can create Excel Sheet with Header
                    foreach (DataTable table in ds.Tables)
                    {
                        foreach (DataColumn column in table.Columns)
                        {
                            TableColumns += column + "],[";
                        }
                    }

                    // Replace most right comma from Columnlist
                    TableColumns = ("[" + TableColumns.Replace(",", " Text,").TrimEnd(','));
                    TableColumns = TableColumns.Remove(TableColumns.Length - 2);
                    //MessageBox.Show(TableColumns);


                    //Use OLE DB Connection and Create Excel Sheet
                    Excel_OLE_Con.ConnectionString = connstring;
                    Excel_OLE_Con.Open();
                    Excel_OLE_Cmd.Connection = Excel_OLE_Con;
                    Excel_OLE_Cmd.CommandText = "Create table " + SheetName + " (" + TableColumns + ")";
                    Excel_OLE_Cmd.ExecuteNonQuery();


                    //Write Data to Excel Sheet from DataTable dynamically
                    foreach (DataTable table in ds.Tables)
                    {
                        String sqlCommandInsert = "";
                        String sqlCommandValue = "";
                        foreach (DataColumn dataColumn in table.Columns)
                        {
                            sqlCommandValue += dataColumn + "],[";
                        }

                        sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
                        sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
                        sqlCommandInsert = "INSERT into " + SheetName + "(" + sqlCommandValue.TrimEnd(',') + ") VALUES(";

                        int columnCount = table.Columns.Count;
                        foreach (DataRow row in table.Rows)
                        {
                            string columnvalues = "";
                            for (int j = 0; j < columnCount; j++)
                            {
                                int index = table.Rows.IndexOf(row);
                                columnvalues += "'" + table.Rows[index].ItemArray[j] + "',";

                            }
                            columnvalues = columnvalues.TrimEnd(',');
                            var command = sqlCommandInsert + columnvalues + ")";
                            Excel_OLE_Cmd.CommandText = command;
                            Excel_OLE_Cmd.ExecuteNonQuery();
                        }

                    }
                    Excel_OLE_Con.Close();
                    Dts.TaskResult = (int)ScriptResults.Success;
                    myADONETConnection.Close();
                }


                catch (Exception exception)
                {

                    // Create Log File for Errors
                    using (StreamWriter sw = File.CreateText(Dts.Variables["User::FolderPath"].Value.ToString() + "\\" +
                        Dts.Variables["User::ExcelFileName"].Value.ToString() + ".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

    }
}

2 个答案:

答案 0 :(得分:1)

public void Main()
        {
            string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");



            //Declare Variables

            string FolderPath = Dts.Variables["User::FolderPath"].Value.ToString();
            string TableName = Dts.Variables["User::TableName"].Value.ToString();
            string SheetName = Dts.Variables["User::SheetName"].Value.ToString();

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



            //USE ADO.NET Connection for the loop initialisation
            SqlConnection myADONETConnection2 = new SqlConnection();
            myADONETConnection2 = (SqlConnection)(Dts.Connections["DBConn"].AcquireConnection(Dts.Transaction) as SqlConnection);
            //Load data into the loop table
            string queryString2 =
       "SELECT distinct PO from " + TableName;
            SqlDataAdapter adapter = new SqlDataAdapter(queryString2, myADONETConnection2);
            var table2 = new DataTable();
            adapter.Fill(table2);
            var numberofrows = table2.Rows.Count;
            for (int i = 0; i < numberofrows; i++)
            {
                try
                {
                    var cell = table2.Rows[i]["PO"];

                    string ExcelFileName = (string)cell;
                    ExcelFileName = ExcelFileName + "_" + datetime;

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

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

                    //USE ADO.NET Connection from SSIS Package to get data from table

                    SqlConnection myADONETConnection = new SqlConnection();
                    myADONETConnection = (SqlConnection)(Dts.Connections["DBConn"].AcquireConnection(Dts.Transaction) as SqlConnection);


                    //Load Data into DataTable from SQL ServerTable
                    // Assumes that connection is a valid SqlConnection object.
                    string queryString =
                      "SELECT * from " + TableName + "where PO=" + cell;
                    SqlDataAdapter adapter2 = new SqlDataAdapter(queryString, myADONETConnection);
                    DataSet ds = new DataSet();
                    adapter2.Fill(ds);


                    //Get Header Columns
                    string TableColumns = "";

                    // Get the Column List from Data Table so can create Excel Sheet with Header
                    foreach (DataTable table in ds.Tables)
                    {
                        foreach (DataColumn column in table.Columns)
                        {
                            TableColumns += column + "],[";
                        }
                    }

                    // Replace most right comma from Columnlist
                    TableColumns = ("[" + TableColumns.Replace(",", " Text,").TrimEnd(','));
                    TableColumns = TableColumns.Remove(TableColumns.Length - 2);
                    //MessageBox.Show(TableColumns);


                    //Use OLE DB Connection and Create Excel Sheet
                    Excel_OLE_Con.ConnectionString = connstring;
                    Excel_OLE_Con.Open();
                    Excel_OLE_Cmd.Connection = Excel_OLE_Con;
                    Excel_OLE_Cmd.CommandText = "Create table " + SheetName + " (" + TableColumns + ")";
                    Excel_OLE_Cmd.ExecuteNonQuery();


                    //Write Data to Excel Sheet from DataTable dynamically
                    foreach (DataTable table in ds.Tables)
                    {
                        String sqlCommandInsert = "";
                        String sqlCommandValue = "";
                        foreach (DataColumn dataColumn in table.Columns)
                        {
                            sqlCommandValue += dataColumn + "],[";
                        }

                        sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
                        sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
                        sqlCommandInsert = "INSERT into " + SheetName + "(" + sqlCommandValue.TrimEnd(',') + ") VALUES(";

                        int columnCount = table.Columns.Count;
                        foreach (DataRow row in table.Rows)
                        {
                            string columnvalues = "";
                            for (int j = 0; j < columnCount; j++)
                            {
                                int index = table.Rows.IndexOf(row);
                                columnvalues += "'" + table.Rows[index].ItemArray[j] + "',";

                            }
                            columnvalues = columnvalues.TrimEnd(',');
                            var command = sqlCommandInsert + columnvalues + ")";
                            Excel_OLE_Cmd.CommandText = command;
                            Excel_OLE_Cmd.ExecuteNonQuery();
                        }

                    }
                    Excel_OLE_Con.Close();
                    Dts.TaskResult = (int)ScriptResults.Success;
                    myADONETConnection.Close();
                }


                catch (Exception exception)
                {

                    // Create Log File for Errors
                    using (StreamWriter sw = File.CreateText(Dts.Variables["User::FolderPath"].Value.ToString() + "\\" +
                        Dts.Variables["User::ExcelFileName"].Value.ToString() + ".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

    }
}

答案 1 :(得分:0)

谢谢您的解决方案。它确实对我有用。 我只需在工作表名称之前和之后添加以下括号[,如下所示,即可创建并插入查询代码:

Excel_OLE_Cmd.CommandText = "Create table [" + SheetName + "]  (" + TableColumns + ")"; //SheetName should be in []

Excel_OLE_Cmd.ExecuteNonQuery();

//Write Data to Excel Sheet from DataTable dynamically
foreach (System.Data.DataTable table in Results.Tables)
{
    String sqlCommandInsert = "";
    String sqlCommandValue = "";
    foreach (DataColumn dataColumn in table.Columns)
    {
        sqlCommandValue += dataColumn + "],[";
    }
    sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
    sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
    sqlCommandInsert = "INSERT into [" + SheetName + "] (" + sqlCommandValue + ") VALUES (";