【问题标题】:C# resolving Excel table column names of which some are datesC#解析Excel表格列名,其中一些是日期
【发布时间】:2014-04-16 04:23:48
【问题描述】:

我正在尝试根据我执行的 Excel 查询从 C# 中的数据集中返回列名列表。我可以这样做(我认为),请参见下面的代码。但是,我的三个列标题是日期,列名显示为 F4、F5、F6。我进一步查看,发现 Type (.getType) 报告 System.Double 但我无法转换它们。

示例文件是:

UID |名字 |姓氏 | 2010 年 7 月 31 日 | 2010 年 8 月 31 日

100 |测试 |测试 | 8.8 | 9.9

200 |测试2 |测试2 | 7.7 | 6.6

我的输出是:

UID

名字

系统字符串

系统字符串

F4

System.Double

F5

System.Double

F6

System.Double

你能解释一下吗?

conn = new OleDbConnection(conStr);
conn.Open();

dbCmd = new OleDbCommand("SELECT * FROM [" + worksheetName + "$]", conn);
dbCmd.CommandType = CommandType.Text;

dbAd = new OleDbDataAdapter(dbCmd);

dbAd.Fill(ds);

foreach (DataTable table in ds.Tables)
{
    foreach (DataColumn col in table.Columns)
        {
            Console.WriteLine(col.ColumnName);
                Console.WriteLine(col.ToString());
                Console.WriteLine(col.DataType);
                //object t = col;
                //Double ttd = (Double)t;
                //Console.WriteLine(t);
        }
}

我搜索了高低,但找不到如何做到这一点。我真的不想读取使用 Excel 对象模型的文件,因为这太慢了。

【问题讨论】:

    标签: c# excel


    【解决方案1】:

    我相信正在发生的事情是 Excel OLE 数据提供程序猜测这些单元格的类型并且它猜测错误。默认情况下,JET 引擎查看前 8 行以确定所有列的数据类型。您可以通过在填充数据集之前修改注册表来更改此设置。这是我不久前对similar question 的回复:


    您必须在解析 Excel 电子表格之前更新此注册表项:

    // Excel 2007
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel\
    
    // Excel 2003
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\
    

    在此键下将TypeGuessRows 更改为0ImportMixedTypes 更改为Text。您还需要更新连接字符串以在扩展属性中包含 IMEX=1

    string connString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileLocation + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";");
    

    参考文献

    http://blogs.vertigo.com/personal/aanttila/Blog/archive/2008/03/28/excel-and-csv-reference.aspx

    http://msdn.microsoft.com/en-us/library/ms141683.aspx

    【讨论】:

    • 为这么小的事情修改注册表?你不打算告诉它的恐怖吗?!
    • 安德鲁,谢谢你的回答。更新注册表有效,尤其是在我将连接字符串排成正确版本的 Excel 12 而不是 8 之后。谢谢您的指点。请不要在您的回复中的第一个链接给出 404。
    【解决方案2】:

    这不适合你吗?

    double dblValue = 39456; // <--- your input double value
    
    DateTime dt = DateTime.FromOADate(dblValue);
    
    //dt <- Your DateTime value
    

    阅读herehere

    Excel 将日期/时间存储为双格式数字。 DateTime 类已经提供了 FromOADate 函数来解析 (valid :)) 双精度值到正确的日期和时间。

    【讨论】:

    • 嘿 Nayan - 我试过这个,它会导致 C# 抛出异常,因为它试图将“F4”转换为日期时间。
    • 大声笑.. 我清楚地说 - 只转换双精度值.. 不是字符串!为什么您希望“F4”成为有效的 DateTime 对象?
    • 好吧..这太愚蠢了,无法回答,但我会的。检查col.DataType。如果是System.Double,那么只能使用我的方法.. 否则它不是日期/时间值。但不是每个双精度值都是 DateTime,好吗?现在就动动脑筋。
    • 好吧,我真的觉得不需要这种态度。它返回双倍,因为列中保存的数据值是双倍的。但是,标题是日期时间。如果我返回列名,我会得到字符串 F4(或 FX,其中 X 是列号)。请注意,我想获取列名,即日期时间。
    猜你喜欢
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 2011-04-21
    • 2014-03-04
    • 1970-01-01
    相关资源
    最近更新 更多