ASP.NET(C#) 读取EXCEL问题汇总

使用OLEDB能够对excel文件进行读取,咱们只要把该excel文件做为数据源便可。数据库

一 在D盘建立excel文件test.xls:数组

  

二 将工做表Sheet1的内容读取到DataSet
  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties='Excel 8.0'";
  DataSet ds = new DataSet();
  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
  oada.Fill(ds);asp.net

 

读取的DataSet为:ide

  

从图中能够看出excel文件中的第一行变成了DataSet中的列名,这正是系统的默认设置。ui

若是想把第一行也做为数据行,那咱们能够给链接字符串添加一个HDR=No属性如:
  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties='Excel 8.0;HDR=No'";
  DataSet ds = new DataSet();
  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
  oada.Fill(ds);
  结果也许会让你有点想不到:spa

  

第一行的第一列和第三列都变成空的了,这是由于系统把第一列识别成了数字,把第三列识别成了日期,.net

而第一行的数据不符合格式的要求,因此就变成空的了。excel

四 咱们还能够把全部列都作为字符串来读取,只要添加属性IMEX=1便可orm

  string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties='Excel 8.0;HDR=No;IMEX=1'";
  DataSet ds = new DataSet();
  OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
  oada.Fill(ds);
  结果又会如何呢?blog

  

是否是再次出乎你的意料,第三行的日期怎么变成数字了,其实excel在转换格式的时候就自动把日期变成数字了,

那这个数字是怎么来的呢 ? 若是你把日期改为1900年1月1日,那么你能够看到他的转换结果是1,以此类推,39902是哪一天就明白了吧。

这里解决办法:

方法一:
  public static string getDateStr(string strValue)
      {
          int i = Convert.ToInt32(strValue);
          DateTime d1 = Convert.ToDateTime("1900-1-1");
          DateTime d2 = d1.AddDays(i - 2);
          string strTemp = d2.ToString("d");

          return strTemp;
      }
  方法二:
  DateTime.FromOADate(Convert.ToInt32(strValue)).ToString("d");

五 也许你并不想读取整个excel的内容

若是只想读取前两列能够用:select * from [Sheet1$A:B]

若是只想读取A1到B2的内容,就用:select * from [Sheet1$A1:B2]

六 若是不知道工做表的名字或名字被人为修改了该怎么办呢?

咱们能够经过索引来获取指定工做表的名字,如下方法能够用来获取工做表名称的数组:


  ArrayList al = new ArrayList();
  string strConn;
  strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
      "Extended Properties=Excel 8.0;";
  OleDbConnection conn = new OleDbConnection(strConn);
  conn.Open();
  DataTable sheetNames = conn.GetOleDbSchemaTable
      (OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
  conn.Close();
  foreach (DataRow dr in sheetNames.Rows)
  {
      al.Add(dr[2]);
  }
  return al;

 

IMEX=1的时候并非全都会做为字符串来处理,根据系统的默认设置,一般若是前8行有字符串,则该列会做为字符串来处理,若是全都为数字,则该列为数字列,日期也是同样。

若是你以为8行不够或者太多了,则只能修改注册表HKEY_LOCAL_MACHINE/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGue***ows,若是此值为0,则会根据全部行来判断使用什么类型,一般不建议这麽作,除非你的数据量确实比较少。 

 

没法读取EXCEL中的数据单元格。有数据,可是读出来全是空值。

解决方法:

1.在导入数据链接字符串中,将IMEX=1加入,“Provider=Microsoft.Jet.OLEDB.4.0;Data Source="C:\Data.xls";Extended Properties="Excel 8.0;HDR=Yes;IMEX=1; ”,这样就能够。

注:

“HDR=Yes;”指示第一行中包含列名,而不是数据;

“IMEX=1;”通知驱动程

序始终将“互混”数据列做为文本读取。

二者必须一块儿使用。

本觉得这样就OK了。但在实际使用过程当中,这样设置仍是不行,查阅了很多资料才发现,原来还有一个注册表里的信息须要修改,这样带能让excel再也不使用前8行的内容来肯定该列的类型。

注册表修改内容以下:

在HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\Excel有一个TypeGue***ows值,预设是8,表示会先读取前8列来决定每个栏位的型态,因此若是前8列的资料都是数字,到了第9列之后出现的文字资料都会变成null,因此若是要解决这个问题,只要把TypeGue***ows机码值改为0,就能够解这个问题了。

 

asp.net 解决使用OLEDB导入excel数据时同时包含文本和数字的列没法正常读取状况


1.链接语句中必须包含IMEX=1

         EXCEL2003:Provider=Microsoft.Jet.OLEDB.4.0;Data Source='文件路径';Extended Properties=Excel 8.0;HDR=Yes;IMEX=1

         EXCEL2007:Provider=Microsoft.ACE.OLEDB.12.0;Data Source='文件路径';Extended Properties=Excel 12.0;HDR=Yes;IMEX=1

 2.设置注册表信息:【HKEY_LOCAL_MACHINE/Software/Microsoft/Jet/4.0/Engines/Excel/】

        ImportMixedType :Text (注:值为Text,则该列为文本;值为Majority Type,则取数据多的类型)

        TypeGue***ows :0  (注:0表示要读取全部数据再来判断是不是混合类型)

OLEDB 链接 Excel 中的 HDR 与 IMEX 解释

 Microsoft.Jet.OleDb 链接 Excel,就像数据库同样操做 Excel,如下是一个示例的链接字符串:

string connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + filePath +";Extended Properties='Excel    8.0;HDR=NO;IMEX=1;'";

HDR

HDR 表示第一行是不是标题行。

  • 若为 YES,则第一行是标题行(即列名称),不是数据;

  • 若为 NO,则第一行不是标题行,跟后面的行同样,是数据。

IMEX

即 intermixed,表示混合数据类型时如何处理。Excel 不像 Access 样,Access 每一字段(列)具备数据类型,Excel 不具备,因此 Excel 第一行第一列能够存储字符串,第二行第一列又能够存储数字……一样的列,存储不一样的数据类型,这就造成了混合数据类型。

若是咱们的 Excel 不存在混合数据类型,则能够省略 IMEX;若是咱们的 Excel 存在混合数据类型,则须要正确指定 IMEX,不然 OLEDB 极可能错误地判断数据类型,致使读取出来的数据是空白,甚至读取不到行等错误。

  • 若为 0,则为输出模式,此状况下只能用做写入 Excel;

  • 若为 1,则为输入模式,此状况下只能用做读取 Excel,而且始终将 Excel 数据做为文本类型读取;

  • 若为 2,则为链接模式,此状况下既可用做写入、也可用做读取。

因此若要读取混合数据类型,应该将 IMEX 设置为 1;若误设置为 0,则读取不到任何行;若误设置为 2 或省略,则有些数据读取出来是空白。

注意:输出模式对应写入、输入模式对应读取。

 Microsoft.Jet.OleDb 链接 Excel,就像数据库同样操做 Excel,如下是一个示例的链接字符串:

string connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + filePath +";Extended Properties='Excel 8.0;HDR=NO;IMEX=1;'";

HDR

HDR 表示第一行是不是标题行。

  • 若为 YES,则第一行是标题行(即列名称),不是数据;

  • 若为 NO,则第一行不是标题行,跟后面的行同样,是数据。

IMEX

即 intermixed,表示混合数据类型时如何处理。Excel 不像 Access 样,Access 每一字段(列)具备数据类型,Excel 不具备,因此 Excel 第一行第一列能够存储字符串,第二行第一列又能够存储数字……一样的列,存储不一样的数据类型,这就造成了混合数据类型。

若是咱们的 Excel 不存在混合数据类型,则能够省略 IMEX;若是咱们的 Excel 存在混合数据类型,则须要正确指定 IMEX,不然 OLEDB 极可能错误地判断数据类型,致使读取出来的数据是空白,甚至读取不到行等错误。

  • 若为 0,则为输出模式,此状况下只能用做写入 Excel;

  • 若为 1,则为输入模式,此状况下只能用做读取 Excel,而且始终将 Excel 数据做为文本类型读取;

  • 若为 2,则为链接模式,此状况下既可用做写入、也可用做读取。

因此若要读取混合数据类型,应该将 IMEX 设置为 1;若误设置为 0,则读取不到任何行;若误设置为 2 或省略,则有些数据读取出来是空白。

注意:输出模式对应写入、输入模式对应读取。

 Microsoft.Jet.OleDb 链接 Excel,就像数据库同样操做 Excel,如下是一个示例的链接字符串:

string connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + filePath +";Extended Properties='Excel 8.0;HDR=NO;IMEX=1;'";

HDR

HDR 表示第一行是不是标题行。

  • 若为 YES,则第一行是标题行(即列名称),不是数据;

  • 若为 NO,则第一行不是标题行,跟后面的行同样,是数据。

IMEX

即 intermixed,表示混合数据类型时如何处理。Excel 不像 Access 样,Access 每一字段(列)具备数据类型,Excel 不具备,因此 Excel 第一行第一列能够存储字符串,第二行第一列又能够存储数字……一样的列,存储不一样的数据类型,这就造成了混合数据类型。

若是咱们的 Excel 不存在混合数据类型,则能够省略 IMEX;若是咱们的 Excel 存在混合数据类型,则须要正确指定 IMEX,不然 OLEDB 极可能错误地判断数据类型,致使读取出来的数据是空白,甚至读取不到行等错误。

  • 若为 0,则为输出模式,此状况下只能用做写入 Excel;

  • 若为 1,则为输入模式,此状况下只能用做读取 Excel,而且始终将 Excel 数据做为文本类型读取;

  • 若为 2,则为链接模式,此状况下既可用做写入、也可用做读取。

因此若要读取混合数据类型,应该将 IMEX 设置为 1;若误设置为 0,则读取不到任何行;若误设置为 2 或省略,则有些数据读取出来是空白。

注意:输出模式对应写入、输入模式对应读取。

相关文章
相关标签/搜索