为什么OleDbDataAdapter在填充DataTable时会留下瑕疵?

时间:2014-11-05 09:34:57

标签: c# .net excel datatable oledb

我写了一些方法,它们应该为Excel文件中的每个工作表获取一个DataTable:

第1步是获取.xlsx文件中包含的所有工作表的名称:

private static List<string> GetSheetNames(string filePath) 
        {
            List<string> sheetNames = new List<string>();
            DataTable dt = null;

            try 
            {
                OleDbConnection connection = new OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + filePath + "';Extended Properties='Excel 12.0 Xml;HDR=YES;'");
                connection.Open();
                dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if (dt == null)
                {
                    return null;
                }

                // Add the sheet name to the string array.
                foreach (DataRow row in dt.Rows)
                {
                    sheetNames.Add(row["TABLE_NAME"].ToString());

                }

            }catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            return sheetNames;
        }

第2步是阅读每张工作表并返回相应的DataTable

private static DataTable ReadExcelSheet(string filePath,string sheetName)
{
    DataTable table = new DataTable();
    ValidateSheetName(ref sheetName);
    try
    {                
        OleDbConnection connection;
        DataSet DtSet;
        OleDbDataAdapter cmd;
        connection = new OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + filePath + "';Extended Properties='Excel 12.0 Xml;HDR=YES;'");
        cmd = new OleDbDataAdapter("select * from ["+sheetName+"]", connection);
        cmd.TableMappings.Add("Table", sheetName.Replace("$",string.Empty));
        DtSet = new DataSet();
        cmd.Fill(DtSet);
        table = DtSet.Tables[0];
        connection.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }

    return table;
}

从最后一个返回List<DataTable>

的方法调用这两个方法
private static List<DataTable> ConvertExcelToTables(string filePath) 
{
    List<string> sheetNames = GetSheetNames(filePath);
    List<DataTable> tableList = new List<DataTable>();

    foreach(string sheetName in sheetNames)
    {
        tableList.Add(ReadExcelSheet(filePath,sheetName));
    }

    return tableList;
}

还有一个小助手方法与问题无关:

private static void ValidateSheetName(ref string sheetName)
{
   sheetName = sheetName.EndsWith("$") ? sheetName : sheetName + "$";
}

如果我从示例文件中获取一张表,它看起来像这样:

enter image description here

现在无论我是在调试时调查DataTable还是将其绑定为DataSource的{​​{1}},结果看起来有点奇怪:

enter image description here

我的猜测是,这可能与Excel工作表开始计数1而不是0.但即使是这种情况,我也无法真正想到解决方案。或者我错过了什么。实际上这很可惜,因为这似乎是一个干净的解决方案。

1 个答案:

答案 0 :(得分:1)

不,问题是由

引起的
HDR=YES;

在你的连接字符串中。 将其更改为

HDR=NO;

HDR=YES表示Excel工作表的第一行被假定为包含表的字段名称。但是,作为示例显示的表不是这种情况。实际上,OleDb提供程序无法确定第二列的名称(它是空白的),因此它会分配默认值(字母F后跟列的渐进编号)

您可以在connectionstrings.com找到有关excel连接字符串的大量示例和解释