关于c#:OleDb没有读取excel文件中的所有行,尽管使用IMEX = 1

OleDb not reading all rows from excel file, in spite of using IMEX=1

我使用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就是这样工作的吗?也就是说,将数据库视为被它锁定,而不重视外部插入。或者我如何创建和保存文件会有问题吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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();

    }

为了关闭文件,我只做了一个EDOCX1[0]

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

另外,我也看到过类似的问题,但问题似乎是数据和IMEX标志没有设置为1。让我提前告诉你,这不是一个重复的问题。

谢谢


我使用了下面的代码,这实际上是对代码的简化,但有一些小的改动。它每次都有效,我甚至可以让Excel打开并在执行代码时观察插入的行。然后,我可以对文件进行编辑,然后在文件仍然打开且从未保存更改的情况下将其加载到数据报中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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();
    }
}

创建文件时使用

1
Initialize("C:\\path\\to\\file\\Test File.xls","ListingDetails");

插入测试行

2

我清理了有关创建和处理OLEDB对象的代码。我不确定,这可能给你带来了麻烦,但这样至少你知道一切都已经顺利完成了。

希望这有帮助。