如果我们有例如以下一个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”。

使用我的博客园发表的一篇随笔“数据库小工具(C#)”中给出的 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() 方法转换到合适的数字类型。

不知大家以为然否?

ADO.NET(OleDb)读取Excel表格时的一个BUG的更多相关文章

  1. OLEDB读取EXCEL表格时,某些字段为空,怎么办?

    转载:http://blog.sina.com.cn/s/blog_53864cba01011cbn.html   前些日子,写了一个Excel导入数据库的共同Batch,突然有一天发现当我修改Exc ...

  2. Python:读取Excel表格时出现的u'\u51c6’ 无法正确显示汉字

    读取Excel后,想显示其中一行的元素,结果读出来是这样[u'\u51c6\u8003\u8bc1\u53f7', u'\u8003\u751f\u59d3\u540d'],始终不显示正常的汉字 依照 ...

  3. python2读取EXCEL表格内的数据时碰到的问题

    一,今天在剥离自动化的测试数据时,发生了一个错误,错误显示读取不到某个单元格的数据. 因为我使用的是python2,正好那一个单元格出现的是中文汉字,再者通过查看报错日志,让我了解到错误的原因. di ...

  4. .Net读取Excel文件时丢失数据的问题 (转载)

    相信很多人都试过通过OleDB读取Excel文件,这种方法效率十分高,只是有一点会让人十分头痛,就是当一列中既有混合型数据,又有纯数据时,往往容易丢失数据. 百度过后,改连接字符串 “HDR=YES; ...

  5. Java读取excel表格

    Java读取excel表格 一般都是用poi技术去读取excel表格的,但是这个技术又是什么呢 什么是Apache POI? Apache POI是一种流行的API,它允许程序员使用Java程序创建, ...

  6. C#读取Excel表格中数据并返回datatable

    在软件开发的过程中,经常用到从excel表格中读取数据作为数据源,以下整理了一个有效的读取excel表格的方法. DataTable GetDataTable(string tableName,str ...

  7. 读取Excel表格中数据原型

    写下这篇博客来记录自己的工作,这部分功能是读取Excel表格中的数据,并通过c#中的datagridview控件将读取的数据显示出来.为了方便用户,我设计了一个read按钮,用户点击这个按钮,会弹出打 ...

  8. python使用xlrd读取excel数据时,整数变小数的解决办法

    python使用xlrd读取excel数据时,整数变小数: 解决方法: 1.有个比较简单的就是在数字和日期的单元格内容前加上一个英文的逗号即可.如果数据比较多,也可以批量加英文逗号的前缀(网上都有方法 ...

  9. C# 读取Excel表格内容,以及NPOI的使用

    在实际的开发中,我们可能需要读写word或者Excel的内容,在我开发的项目中,需要读取Excel的内容,并将相对应的内容存储到数据库中,这里简单跟大家分享一下,希望能够帮助一些人. 我相信在读写wo ...

随机推荐

  1. jsp公共头信息的抽取(相对路径的修改)

    1,抽取出的公共头信息 <%@ page language="java" contentType="text/html; charset=UTF-8" p ...

  2. ubuntu 18.04 start myproject

    #!/bin/bash now=$(date +%Y%m%d) cmd='/home/hu/go/src/github.com/coredns/coredns/coreserver -conf /ho ...

  3. 单片微机原理P1:80C51指令系统和编程方法

    0. 寻址方式 寻址方式在汇编中是很重要的,汇编所有的操作都是和和内存或者寄存器打交道的,在80C51里面一共7种寻址方式.   1. 立即寻址: 这个没什么好说的,就是往寄存器或者内存里面写立即数, ...

  4. vue2.0中transition组件的用法

    作用:实现元素进入/离开的过渡效果. 首先,让我们举个栗子: <!DOCTYPE html> <html lang="en"> <head> & ...

  5. 区间DP入门

    所为区间DP,主要是把一个大区间拆分成几个小区间,先求小区间的最优值,然后合并起来求大区间的最优值. 区间DP最关键的就是满足最优子结构以及无后效性!! 例如像是石子合并和括号匹配这两类比较经典的模型 ...

  6. SQL 一次插入多条记录

    本文介绍如何快速插入多条数据到数据表中,以满足sql语句学习或项目测试的需要. 本文非原创,是对移步原文的重新整理. 如有以下表格,如图: 1,原始添加记录的方式,sql语句如下: insert in ...

  7. sqlserver建dblink

    --建立连接exec sp_addlinkedserver'ITSV' ,'' , 'SQLOLEDB' ,'IP地址不加端口' exec sp_addlinkedsrvlogin'ITSV' ,'f ...

  8. 74. Spring Data JPA方法定义规范【从零开始学Spring Boot】

    [从零开始学习Spirng Boot-常见异常汇总] 事情的起因:有人问过我们这个这个问题:为什么我利用Spring data jpa写的方法没有按照我想要的情况进行执行呢?我记得当时只是告诉他你你先 ...

  9. oracle导出多CSV文件的靠谱的

    oracle导出多CSV文件的问题 ---------------------------------------------------------------------- 用ksh脚本从orac ...

  10. 《TCP/IP详解卷1:协议》——第3章 IP:网际协议(转载)

    1.引言 IP是TCP/IP协议族中最核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输.IP提供不可靠. 无连接的数据报传送服务. (1)不可靠 它不能保证IP数据报能成 ...