使用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,就可以解这个问题了。
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,则取数据多的类型)
TypeGuessRows :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 或省略,则有些数据读取出来是空白。
注意:输出模式对应写入、输入模式对应读取。