c#如何使用OleDbCommand在指定列名下的Excel工作表的下一个可用行中添加指定值

Posted

技术标签:

【中文标题】c#如何使用OleDbCommand在指定列名下的Excel工作表的下一个可用行中添加指定值【英文标题】:c# How do I add specified values to the next available row of an Excel worksheet under specified column names using OleDbCommand 【发布时间】:2017-08-01 16:02:49 【问题描述】:

对不起,如果这个问题已经得到解答,我搜索了几个小时,而且我对编程也很陌生。

目前我的 excel 电子表格中有 15 行数据,下面的代码会将值插入到第 40 行,再次按下导出按钮将在第 41 行中插入一个包含值的新行等...

我的问题是如何让它在我现有数据(第 16 行)正下方插入一个新行,以此类推,每次单击导出按钮。我希望保留命令过程。

 private void exportBtn_Click(object sender, EventArgs e)

    OleDbCommand newRow = new OleDbCommand();
    newRow.CommandType = CommandType.Text;
    newRow.CommandText = "INSERT INTO [Sheet1$] ([Company:], [County:], [State:], [Notes:], [User:], [Email:], [Username:], [Password:], [SMMM PWD:], [CAD:]) VALUES (1,2,3,4,5,6,7,8,9,10)";
    newRow.Connection = connectionExl;

    connectionExl.Open();
    newRow.ExecuteNonQuery();
    connectionExl.Close();

更新

到目前为止,我可以获得下一个可用行的 int,现在我想将指定列下的值添加到该可用行。

为方便起见,假设我有 2 个名为 (column1, column2) 的列,我想分别设置的值是 (1,2)

我该怎么做?

到目前为止我的代码:

private void exportBtn_Click(object sender, EventArgs e)
    
        Excel.Application xlApp = StartExcel();
//Excel.Application xlApp = new Excel.Application();  // instead of above line you can open new instance of Excel application and at the end of procedure xlApp.Application.Quit();
        Excel.Workbook myBook = xlApp.Workbooks.Open(@"C:\Users\path\path\excel.xlsx");

        Excel.Worksheet mySheet = myBook.Sheets[1];
        xlApp.Visible = true; // by default excel is invisible leave it invisible if you just like to add data and save it (also use new instance of Excel in this case) 
        int lastRow = mySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
        int openRow = lastRow + 1;
        mySheet.Cells[openRow, 1].Value = "your value for column A";
        mySheet.Cells[openRow, 2].Value = "your value for column B";

        myBook.Save();
        myBook.Close();

    

    private static Excel.Application StartExcel() // would be better to make it public somewhere in your module
    
        Excel.Application instance = null;
        try  instance = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); 
        catch (System.Runtime.InteropServices.COMException ex)  instance = new Excel.Application(); 
        return instance;
    

【问题讨论】:

您正在寻找 excel interop 熟悉 MSDN 文档,因为它将是您最大的资源。 【参考方案1】:

您可能需要 Microsoft.Office.Interop.Excel 或其他 Excel 库。 下面我整理了一些带有 Interop 的示例,您可以根据需要进行调整:

public int getLastRow(Excel.Worksheet ws)

    object[,] arData = ws.UsedRange.FormulaR1C1; // FormulaR1C1 returns only string in 2 dimensional array
    for (int iRow = arData.GetUpperBound(0); iRow > 0; iRow--) 
        for (int iCol = 1; iCol <= arData.GetUpperBound(1); iCol++) 
            if (arData[iRow, iCol].ToString() != "")  return iRow; 
        
    
    return 0;

如果您的工作表的格式未超出数据范围,则下面将为您提供最后一行。

int lastRow = ws.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;

您可以启动 Excel 并根据需要进行调整以设置为您的工作簿/工作表:

using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;

void test()

    Excel.Application xlApp = csXL.StartExcel();
    Excel.Worksheet ws = xlApp.ActiveSheet;
    int irow = getLastRow(ws);


public static Excel.Application StartExcel()

    Excel.Application instance = null;
    try  instance = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); 
    catch (System.Runtime.InteropServices.COMException ex)  instance = new Excel.Application(); 
    return instance;

在这种情况下,您不需要OleDbCommand,您只需将数据插入二维数组即可:

object[,] arLoad = new object[0, 9]; arLoad[0, 0] = 1; arLoad[0, 1] = 2;
ws.Range["A" + irow + ":J" + irow].FormulaR1C1 = arLoad; // or use Value instead of FormulaR1C1

请记住,当您将数据从二维数组加载到 Excel 时,您的数组是基于 0 的,但是当您从 Excel 读取数据时,您的下限数组是 1。 我会等一天,也许有人会发布更好的答案。

这里有几种在特定列/单元格下添加数据的方法,但是当您使用二维数组添加数据时,它会快得多,就像我在上面展示的那样。对于小条目,速度不是问题。

Excel.Worksheet ws;
Excel.Range rngXL = ws.Cells[3, 2]; // Set range to cell B3
rngXL.Value = "Sample Test"; 
rngXL.FormulaR1C1 = "= 3 + 2";
ws.Cells[4,2].FormulaR1C1 = "5";
ws.Cells[5, 3].Value = "2"; // Cell E3
ws.Range["B5:D5"].Value = "Same text for cells B5,C5,D5";
ws.Range["E5"].Value = "This cell is";

另请阅读此处Unable to open another excel file (when one excel is opened by .net) 以及如何使用 Excel 进行干净退出的简单解决方案。我编辑您的代码的地方将使用 Excel 应用程序的打开实例。如果您只需要更新 excel 并退出它,请使用新的 Excel 实例,并且当您完成了 excel 应用程序时。

【讨论】:

是的,我想这可以关闭,因为似乎没有人知道如何使用 OleDbCommand 执行此操作,并且正如您和 Bender Binding 提到的那样,我只需要熟悉 Excel 互操作 正如 Bender Bending 所指出的那样,您将有更多选择来调整输出,无论您喜欢什么。 OleDbCommand 不像 Excel 库那样控制 Excel。要执行此特定任务,您只需要在上面添加几行代码。如果您需要任何帮助,请告诉我。 如果你能看看我下面的问题,请更新我的原始帖子 我已经编辑了你的代码(并且经过实际测试——它可以工作)。我唯一要更改的部分是使用二维数组插入数据,就像我在答案中显示的那样。 如果出现问题,请务必检查您的任务管理器是否有任何 Excel 实例正在运行,然后结束这些实例。

以上是关于c#如何使用OleDbCommand在指定列名下的Excel工作表的下一个可用行中添加指定值的主要内容,如果未能解决你的问题,请参考以下文章

OLEDBCommand Builder 和跨表移动数据

查询数据的库名 查询指定数据库下的表名 查询指定数据库下的指定表的列名

将 DateTime 值作为参数传递给 OleDbCommand

OleDbCommand 不会更新 MS Access 数据库,不会引发错误

如何在 MS Access 中使用 C# 获取所有表名和列名?

在 C# 中检索列名