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);
读取的dataset为:
从图中可以看出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);
结果也许会让你有点想不到:
第一行的第一列和第三列都变成空的了,这是因为系统把第一列识别成了数字,把第三列识别成了日期,
而第一行的数据不符合格式的要求,所以就变成空的了。
四 我们还可以把所有列都做为字符串来读取,只要添加属性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);
结果又会如何呢?
是不是再次出乎你的意料,第三行的日期怎么变成数字了,其实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,就可以解这个问题了。