微软提示的连接字符串是:
ConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & strFileNM & ";" & "Extended Properties='Excel 8.0;HDR=YES;IMEX=1'

问题一:如何读取excel数据?

//如下给出的是c#读取excel
//查询excel,得到worksheet,即类似数据库中的table
public static DataTable GetAllTableInfo(string connstring)
{   
OleDbConnection conn = new OleDbConnection(connstring);  
try
{
conn.Open();
DataTable schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,new object[] {null, null, null, "TABLE"});   
return schemaTable;
}
catch(Exception ex)
{
 return null;
}
}
///查询excel,返回DataSet
public static DataSet getExcelInfoDs(string strConn,string sqlstring)
{   
OleDbConnection conn = new OleDbConnection(strConn); 
conn.Open();
OleDbDataAdapter adp = new OleDbDataAdapter(sqlstring,conn);   
DataSet ds = new DataSet();  
try
{
 adp.Fill(ds);
 conn.Close();
}
catch(Exception ex)
{ 
 return null;
}
return ds;
}

//调用方法如下:
DataTable excelDt = GetAllTableInfo(strConn);
if(excelDt != null && excelDt.Rows.Count > 0)
{ 
     for(int j = 0;j < excelDt.Rows.Count;j++)
    {       
        string sql = "select * from ["+excelDt.Rows[j][2].ToString()+"]";
        try
        {
            DataSet infods = getExcelInfoDs(strConn,sql);
            for(int m = 0;m < infods.Tables.Count;m++)
            {  
                if(infods.Tables[m] != null)
                {
                    //infods.Tables[m]为某个sheet内的全部数据  
                }
            }
        }
        catch(Exception ex)
        {
        }
   }
}

 

使用的是Jet.OLEDB.4.0的连接驱动,HDR=Yes表示worksheet中第一行表示字段.

问题二:为什么读取到了excel数据记录,但取出的数据为空?

在用OLE DB,ISAM会尝试读取前8行的数据类型,如果一列中的前8行既有文本类型又有数字类型,那么就取多数的数据类型,其余的返回为空。如果两者一样的数目一样多,那么就取数字类型,文本类型的行返回空值。

举例说明:某一列前8行中

如果5行文本类型,3行数字类型  则返回结果为5行文本类型的数据,3行空值
如果5行数字类型,3行文本类型  则返回结果为5行数字类型的数据,3行空值
如果4行文本类型,4行数字类型 则返回结果为4行数字类型的数据,4行空值

当然8行以后的值按照前面探测的结果,如果跟结果一样的类型返回原来的值,如果相反则返回空值。

      
如果想在混合类型中返回真实的值,那么就要在连接字符串的扩展属性中加上IMEX=1;这个属性的对应值如下:
0 is Export mode
1 is Import mode
2 is Linked mode (full update capabilities)

微软提醒说,谨慎使用IMEX=1,因为这是导入模式,在这种模式下做数据的添加或者更新结果不可预料,所以在对Excel做Insert 或者Update动作时,不要给这个属性赋值。

那么为什么在ImPort Mode的情况下就是用文本方式读取的那?
请看注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel 下面有个键ImportMixedTypes,它的值是Text,也就是说在导入模式下,混合数据类型统一处理为文本。

这样看似一切OK了,不过当你的数据前八行都是数字,后面的N(N>>8)为文本类型时,即使你把IMEX设为1,后面的文本还是不会显示的。

为什么?因为ISAM会一直在检索前八行数据,即使你跟他交待了在导入模式下使用文本类型,它还是比较关注前八行的情况,如果前八行都为数字,他还是要按数字来处理,

那么如果非得全部取出数据该怎么办呢?

还是得靠注册表,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel,下面有个键TypeGuessRows,其默认键值为8,这就是前八行的来源,你可以把它设为1-16行,当然也可以把它设为0,设置为0时,那么ISAM将不再看前几行,而是遍历所有行。如果所有行都是数字,那就是数字了,有一个不是数字那就按文本处理。