【问题标题】:How to work on specific excel that already opened - C#?如何处理已经打开的特定 excel - C#?
【发布时间】:2022-08-18 18:28:47
【问题描述】:

我有引用此代码的按钮:

private void button24_Click(object sender, EventArgs e)
{
    string connectionString = \"Data Source=\" + System.Configuration.ConfigurationManager.AppSettings[\"server\"] + \";\";
    connectionString += \"Initial Catalog=\" + System.Configuration.ConfigurationManager.AppSettings[\"database\"] + \";\";
    connectionString += \"Integrated Security=True\";

    Excel.Application oXL = new Excel.Application();
    oXL.Visible = true;
    //oXL.ActiveSheet.Name = \"Je Anaylsis Tests\";

    object[] Checked = new object[10];
    if(checkBox1.Checked)
    {
        dt = new DataTable();
        conn = new SqlConnection(connectionString);
        conn.Open();
        string _tbName;
        _tbName = \"Test1\";
        string _Client;
        _Client = \"Client_\" + ClientRowId;
        sda = new SqlDataAdapter(@\"SELECT * From \" + _Client + \".DBO.\" + _tbName, conn);
        sda.Fill(dt);
        Checked [0] = \"Test1\";
        Excel._Workbook oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value));
        ExportExcels.InsertIntoExcelWorksheets( oWB, dt, Checked[0].ToString());
    }
    if (checkBox2.Checked)
    {
        dt = new DataTable();
        conn = new SqlConnection(connectionString);
        conn.Open();
        string _tbName;
        _tbName = \"Test2\";
        string _Client;
        _Client = \"Client_\" + ClientRowId;
        sda = new SqlDataAdapter(@\"SELECT * From \" + _Client + \".DBO.\" + _tbName, conn);
        sda.Fill(dt);
        Checked[1] = \"Test2\";
        Excel._Workbook oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value));
        ExportExcels.InsertIntoExcelWorksheets( oWB, dt, Checked[1].ToString());
    }

    oXL.UserControl = true;
}

ExportExcels 代码和 InsertIntoExcelWorksheets:

static string[] stRange = { \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"aa\", \"ab\", \"ac\", \"ad\", \"ae\", \"af\", \"ag\", \"ah\", \"ai\", \"aj\", \"ak\", \"al\", \"am\", \"an\", \"ao\", \"ap\", \"aq\", \"ar\", \"as\", \"at\", \"au\", \"av\", \"ax\", \"ay\", \"az\", \"ba\", \"bb\", \"bc\", \"bd\", \"be\", \"bf\", \"bg\", \"bh\", \"bi\", \"bj\", \"bk\", \"bl\", \"bm\", \"bn\", \"bo\", \"bp\", \"bq\", \"br\", \"bs\", \"bt\", \"bu\", \"bv\", \"bx\", \"by\", \"bz\" };

static string[,] GetMatrixFromDataTable(DataTable dt)
{
    string[,] toBeReturn = new string[dt.Rows.Count, dt.Columns.Count];
    for (int i = 0; i < dt.Rows.Count; i++)
        for (int j = 0; j < dt.Columns.Count; j++)
            toBeReturn[i, j] = dt.Rows[i][j].ToString();
    return toBeReturn;
}

public static void InsertIntoExcelWorksheets( Excel._Workbook oWB, DataTable dt, string sheetName)
{
    Excel._Worksheet oSheet;
    //Excel._Worksheet oSheet2;
    Excel.Range oRng;

    try
    {
         //oXL.Visible = true;
        //Get a new workbook.

        oWB.Sheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
        oSheet = (Excel._Worksheet)oWB.ActiveSheet;
        oSheet.Name = sheetName.Substring(0, Math.Min(31, sheetName.Length));

        int i = 1;
        foreach (DataColumn dc in dt.Columns)
        {
            oSheet.Cells[1, i] = dc.ColumnName;
            i++;
        }

        oSheet.get_Range(\"A1\", stRange[i - 2] + \"1\").Font.Bold = true;
        oSheet.get_Range(\"A1\", stRange[i - 2] + \"1\").VerticalAlignment =
        Excel.XlVAlign.xlVAlignCenter;

        string[,] dtMatrix = GetMatrixFromDataTable(dt);
        oSheet.get_Range(\"A2\", stRange[i - 2] + (dt.Rows.Count + 1).ToString()).Value2 = dtMatrix;

        oSheet.DisplayRightToLeft = true;
        oSheet.get_Range(\"A1\", stRange[i - 2] + (dt.Rows.Count + 1).ToString()).Font.Name = \"David\";
        oSheet.get_Range(\"A1\", stRange[i - 2] + (dt.Rows.Count + 1).ToString()).VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
        oSheet.get_Range(\"A1\", stRange[i - 2] + (dt.Rows.Count + 1).ToString()).HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;

        oSheet.get_Range(\"A1\", stRange[i - 2] + \"1\").Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightSteelBlue);

        oRng = oSheet.get_Range(\"A1\", stRange[i - 2] + (dt.Rows.Count + 1).ToString());
        oRng.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeBottom].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
        oRng.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeLeft].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
        oRng.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeRight].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
        oRng.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeTop].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
        oRng.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideHorizontal].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
        oRng.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideVertical].Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);

        //  oSheet.get_Range(\"A1\", stRange[i - 1] + \"1\").Borders[Excel.XlBordersIndex.xlDiagonalDown].LineStyle =   

        oRng = oSheet.get_Range(\"A1\", stRange[i - 2] + \"1\");
        oRng.EntireColumn.AutoFit();

        //Manipulate a variable number of columns for Quarterly Sales Data.
        //  DisplayQuarterlySales(oSheet);

        //Make sure Excel is visible and give the user control
        //of Microsoft Excel\'s lifetime.
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

我希望在第二个中它可以在第一个中已经打开的同一个 Excel 上工作,但它总是打开新的。 在底线一个带有两张纸的 excel 文件,而不是带有两张纸的两个 excel 文件。 我怎样才能做到这一点?

非常感谢。

    标签: c# excel


    【解决方案1】:

    如果在 little helper 方法中,您可以提取两者的通用代码:

    private void InsertIntoWorkbook(Excel._Workbook oWB, SqlConnection conn, string tableName)
    {
        string _Client = "Client_" + ClientRowId;
        var sda = new SqlDataAdapter($"SELECT * From {_Client}.DBO.{tableName}", conn);
        var dt = new DataTable();
        sda.Fill(dt);
        ExportExcels.InsertIntoExcelWorksheets(oWB, dt, tableName);
    }
    

    现在,您可以在两个 if 中重用相同的 Excel 对象和相同的连接。工作簿在复选框 ifs 之前创建一次(这解决了问题):

    private void button24_Click(object sender, EventArgs e)
    {
        string connectionString = $"Data Source={System.Configuration.ConfigurationManager.AppSettings["server"]};";
        connectionString += $"Initial Catalog={System.Configuration.ConfigurationManager.AppSettings["database"]};";
        connectionString += "Integrated Security=True";
    
        Excel.Application oXL = new Excel.Application();
        oXL.Visible = true;
        //oXL.ActiveSheet.Name = "Je Anaylsis Tests";
    
        object[] Checked = new object[10];
        if (checkBox1.Checked || checkBox2.Checked) {
            var oWB = (Excel._Workbook)oXL.Workbooks.Add(Missing.Value);
            using (var conn = new SqlConnection(connectionString)) {
                conn.Open();
                if (checkBox1.Checked) {
                    string tableName = "Test1";
                    InsertIntoWorkbook(oWB, conn, tableName);
                    Checked[0] = tableName;
                }
                if (checkBox2.Checked) {
                    string tableName = "Test2";
                    InsertIntoWorkbook(oWB, conn, tableName);
                    Checked[1] = tableName;
                }
            }
        }
        oXL.UserControl = true;
    }
    

    将连接对象放入using statement 可确保连接将在块结束时关闭。

    String interpolation 简化了字符串的创建。

    您在某些地方使用全局变量,似乎局部变量是合适的。

    Checked 数组应该是 string[] 类型,因为它包含表名。但是,我看不出它的目的,因为您从未读过它。另外,为什么只插入两个名称时它的长度为 10?

    【讨论】:

    • 感谢您的努力,但它仍然打开两个 Excels 文件,而不是一个带有两张工作表的 excel。
    • 我不知道ExportExcels.InsertIntoExcelWorksheets 做了什么。也许它发生在那里?
    • 我现在编辑帖子,您也可以看到 ExportExcels.InsertIntoExcelWorksheets。
    • 好的,它不会在那里发生,但 var oWB = (Excel._Workbook)oXL.Workbooks.Add(Missing.Value); 添加了一个新工作簿。我更新了我的代码。现在它应该可以工作了。将方法InsertIntoExcel 替换为InsertIntoWorkbook
    • 作品!非常感谢
    猜你喜欢
    • 2018-06-13
    • 2022-01-11
    • 2014-11-22
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    • 2018-06-28
    相关资源
    最近更新 更多