博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ADO.NET(OleDb)读取Excel表格时的一个BUG
阅读量:6660 次
发布时间:2019-06-25

本文共 1761 字,大约阅读时间需要 5 分钟。

如果我们有例如以下一个Excel表格: 

 

如今要使用C#程序读取其内容: 

using
 System; 
using
 System.Data.OleDb; 
 
namespace
 Skyiv.Ben.Test 
  
sealed class ExcelTest 
  
    
static void Main() 
    
      
try 
      
        
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"Excel 8.0;HDR=yes\";Data Source=Std")) 
        
          conn.Open(); 
          OleDbCommand comm 
= new OleDbCommand("SELECT [ID],[NAME] FROM [Sheet1$]", conn); 
          
using (OleDbDataReader r = comm.ExecuteReader()) 
          
            
while (r.Read()) 
            
               
int id = Convert.ToInt32(r.GetValue(0)); 
               
string name = Convert.ToString(r.GetValue(1)); 
               Console.WriteLine(
"{0}:\t{1}", id, name); 
            }
 
          }
 
        }
 
      }
 
      
catch (Exception ex) 
      
        Console.WriteLine(
"错误: " + ex.Message); 
      }
 
    }
 
  }
 
}
 

该程序的执行结果例如以下: 

 
看来在读取单元格“B3”时返回了“DBNull”,而不是正确的“1768”。

使用我的博客园发表的一篇随笔“”中给出的 OleDb.exe 查看了一下: 

 
 确实,该 Execl 表格中有 2 个“DBNull”值,再用该工具查看一下其结构: 
  
发现其第一列“ID”的数据类型是“double”,第二列“NAME”的数据类型是“string”。

经分析。“DBNull”都出如今其数据类型与列的数据类型不相符的单元格中。

看来。问题的症结就在这里了。我们知道,Excel 表格并是不真正的数据库,不像真正的数据库一样每一个字段(列)都有一个特定的数据类型。而是由ADO.NET通过扫描该表格的开头几行来猜測其每一列的数据类型,这样。当某列中有些单元格的数据类型与该列数据类型不一致时。就出问题了。该单元格的值就变成的“DBNull”。

 

这个问题来源于我的实际工作。在工作中,须要分析一张业务部门提供的 Excel 表格中的数据,该表格有好几千个数据行。当中有些列绝大部分的值是数字型。但当中有一些数字存储为文本格式。而有些列绝大部分的值是字符型,但有少数单元格的值是数字。这样,我的分析程序就不能工作了。我眼下的解决方式是将该 Excel 表格另存为文本文件(制表符分隔),然后在 C# 程序中读取该文本文件。 
另一种方法就是在 Excel 表格中选中整列。然后“将存为文本的数字转换为数字”。例如以下所看到的: 
  
可是,我并没有找到一个简便的方法来“将数字转换为文本”。 
不知在 ADO.NET 中有没有办法在不改变原始 Excel 表格的情况下。正确读取其列中有单元格的数据类型不一致的 Excel 表格中的数据?假设谁知道的话,恳请告诉我。谢谢。 
不知道要通过什么途径向 Microsoft 报告这个 BUG ?
我觉得这个 BUG 的解决方式有两个:
1.  假设某一列被猜測为数字型的话,假设在该列中出现字符型的数据,假设该数据是存储为文本的数字,就直接转换为数字返回给调用者好了。

假设该数据不能转换为数字,能够返回“DBNull”,或者抛出异常。

    假设某一列被猜測为字符型的话,仅仅要该列中的单元格不为空。就转换为字符型返回给调用者。
2. 在 ADO.NET 的 OleDb 连接串中提供一个属性强制指定 Excel 表格中的全部列的数据类型都为“string”,仅仅要单元格的内容不为空,就不返回“DBNull”,而返回“string”。然后由调用者自己使用 Convert.ToXXX() 方法转换到合适的数字类型。
不知大家以为然否?

你可能感兴趣的文章
格雷码的实现
查看>>
js高级程序设计(四)变量、作用域和内存问题
查看>>
8进制与16进制
查看>>
JS-DOM Element方法和属性
查看>>
我的Android进阶之旅------>Android DatePicker和TimePicker案例
查看>>
作用域和闭包
查看>>
leangoo大讲堂:scrum敏捷开发实战——深圳站
查看>>
表格table嵌套,边框合并问题
查看>>
[转载].NET开发常用的10条实用代码
查看>>
gzip
查看>>
Algs4-1.4.27两个栈实现队列
查看>>
matlab图片压缩
查看>>
设计模式漫谈之责任链
查看>>
[转][荐]优化tableView性能—针对滑动时出现卡的现象
查看>>
javascript小练手
查看>>
基于双下划线的跨表查询 (join查询)
查看>>
ZendFramework2 源码分析 init_autoloader.php
查看>>
javac - Java programming language compiler
查看>>
3 爬虫cookie的处理办法
查看>>
改进UCHOME的记录发布,增强可访问性用户体验
查看>>