尽管使用IMEX = 1,OleDb仍无法从Excel文件中读取所有行

San*_*rnm 5 .net c# oledb excel

我在C#中使用Microsoft.ACE.OLEDB.12.0驱动程序来读取和写入Excel文件(XLS)。我的阅读器的扩展属性如下:Excel 8.0; HDR = NO; IMEX = 1; 对于作者来说,格式如下:Excel 8.0; HDR = NO; IMEX = 0;

这是场景:我从excel文件中读取了input.xls,并创建了一个新的output.xls文件,并使用我的编写器将其写入。现在,我在MS Excel中打开文件output.xls,并向其中添加几行。

接下来,我将output.xls作为输入输入到程序中,并且在调试时,我看到它仅读取最初使用OleDb编写的行。它不会读取我添加的任何新行,并且编写程序会吐出已读取的行。

这是OleDb的工作方式吗?即将数据库视为被其锁定,并且不重视外部插入。还是我创建和保存文件的方式可能有问题?

private void Initialize(string fileName, FileType fileType)
    {
        string connectionString = GetConnectionString(fileName, fileType);

        string sheet;
        using (OleDbConnection connection = OpenConnection(connectionString))
        {
            DataTable sheets = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

        }

        tableName = "[ListingDetails]";

        conn = new OleDbConnection();
        conn.ConnectionString = connectionString;
        conn.Open();
        cmd1 = new OleDbCommand();
        cmd1.Connection = conn;
        cmd1.CommandText = string.Format(CultureInfo.InvariantCulture, @"CREATE TABLE {0} {1}", tableName, fieldstring);
        int x = cmd1.ExecuteNonQuery();

    }


public void InsertRow(string[] data)
    {
        StringBuilder fieldString = new StringBuilder();
        fieldString.Append("(");
        foreach (var h in headers)
        {
             fieldString.Append(" ["+h+"], ");
        }
        fieldString.Remove(fieldString.Length - 2, 2);
        fieldString.Append(")");
        StringBuilder dataString = new StringBuilder();
        dataString.Append("('");
        foreach (var d in data)
        {
            if(d!=null)
                dataString.Append(d.Replace("'", "''") + "', '");
            else
                dataString.Append("', '");
        }
        dataString.Remove(dataString.Length - 4, 4);
        dataString.Append("')");
        cmd1.CommandText = string.Format(CultureInfo.InvariantCulture, @"INSERT INTO {0} {1} values {2}", tableName, fieldString, dataString);
        int x = cmd1.ExecuteNonQuery();

    }
Run Code Online (Sandbox Code Playgroud)

对于关闭文件,我只是做一个 conn.Close();

我在某种程度上怀疑我在Initialize()方法中创建/使用工作表的方式。

PS我见过类似的问题,但问题似乎在于Data和IMEX标志未设置为1。让我事先告诉您这不是重复的问题。

谢谢

Sid*_*and 2

我使用了下面的代码,这实际上是您的代码的简化,但有一些细微的更改。它每次都有效,我什至可以打开 Excel 并在执行代码时观察插入的行。然后,我可以对文件进行编辑,然后在文件仍处于打开状态且无需保存更改的情况下将其加载到数据网格中。

private void Initialize(string fileName, string tableName)
{
    string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=NO\"";
    string fieldstring = "(ID int, Field1 char(255), Field2 char(255))";

    using (OleDbConnection conn = new OleDbConnection(connectionString))
    {
        conn.Open();

        using (OleDbCommand cmd = new OleDbCommand())
        {
            cmd.Connection = conn;
            cmd.CommandText = string.Format(CultureInfo.InvariantCulture, @"CREATE TABLE [{0}] {1}", tableName, fieldstring);
            cmd.ExecuteNonQuery();
        }

        conn.Close();
    }
}

public void InsertRow(string fileName, string tableName, string data)
{
    string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=YES\"";
    string headers = "ID,Field1,Field2";

    using (OleDbConnection conn = new OleDbConnection(connectionString))
    {
        conn.Open();

        using (OleDbCommand cmd = new OleDbCommand())
        {
            cmd.Connection = conn;
            cmd.CommandText = string.Format(CultureInfo.InvariantCulture, @"INSERT INTO [{0}$] ({1}) values({2})", tableName, headers, data);
            txtQuery.Text = cmd.CommandText;
            cmd.ExecuteNonQuery();
        }

        conn.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

创建文件

Initialize("C:\\path\\to\\file\\Test File.xls", "ListingDetails");
Run Code Online (Sandbox Code Playgroud)

插入测试行

for (int i = 0; i < 10; i++)
{
    InsertRow("C:\\path\\to\\file\\Test File.xls", "ListingDetails",
        "'" + i.ToString() + "','test" + (i + 2).ToString() + "','test" + (i + 5).ToString() + "'");
}
Run Code Online (Sandbox Code Playgroud)

我清理了围绕 OleDb 对象的创建和处理的代码。我不确定这可能给你带来了问题,但这样至少你知道一切都正常完成了。

希望这可以帮助。