欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET(C#) 读取EXCEL另加解决日期问题的方法分享

程序员文章站 2024-02-29 14:11:34
使用oledb可以对excel文件进行读取,我们只要把该excel文件作为数据源即可。 一 在d盘创建excel文件test.xls: 二 将工作表sheet1的内...

使用oledb可以对excel文件进行读取,我们只要把该excel文件作为数据源即可。

一 在d盘创建excel文件test.xls:

ASP.NET(C#) 读取EXCEL另加解决日期问题的方法分享

二 将工作表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);

读取的dataset为:
ASP.NET(C#) 读取EXCEL另加解决日期问题的方法分享

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

三 如果想把第一行也作为数据行,那我们可以给连接字符串添加一个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);

  结果也许会让你有点想不到:

ASP.NET(C#) 读取EXCEL另加解决日期问题的方法分享

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

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

四 我们还可以把所有列都做为字符串来读取,只要添加属性imex=1即可

复制代码 代码如下:

  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);

  结果又会如何呢?

ASP.NET(C#) 读取EXCEL另加解决日期问题的方法分享

是不是再次出乎你的意料,第三行的日期怎么变成数字了,其实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/typeguessrows,如果此值为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有一个typeguessrows值,预设是8,表示会先读取前8列来决定每一个栏位的型态,所以如果前8列的资料都是数字,到了第9列以后出现的文字资料都会变成null,所以如果要解决这个问题,只要把typeguessrows机码值改成0,就可以解这个问题了。