为了减少对其它商业软件的依赖,对于像导入导出Office文档这样的功能,可以不使用PIA程序集,而像下面这样:
1 2 3 4 5 6 7 | string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + path.Trim() + "';Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'" ; OleDbConnection OleConn = new OleDbConnection(strConn); OleConn.Open(); string strExcel = "Select * From [Sheet1$]" ; OleDbDataAdapter OleDA = new OleDbDataAdapter(strExcel, strConn); DataTable table = new DataTable(); OleDA.Fill(table); |
这样客户端不需要安装Office就可以读取Excel里的数据,其中连接字符串里的IMEX=1是指定混合类型的数据列均按文本来读取,据说可以解决数据列里有多个类型的数据时某些数据读取不出的问题。可惜的是,尝试后发现不起作用。
后来在某处看到一个新的解决方法:
1 2 | 修改HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\Excel的TypeGuessRows值为0,预设是8 其原理是Office会先读取每一列的前8行来决定每一个数据列的类型,所以如果前8行的资料都是数字,到了第9行以后出现的文字资料都会变成 null ,设为0即表示事先决定数据列的类型。 |
问题虽然解决了,但显示这不是一个好办法,这要求每个客户端都必须修改注册表,比起Office的装机量,使用PIA来读取Office文件或许是个更明智的选择:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | excel = new Excel.Application(); excel.Application.Workbooks.Open(path, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing); Excel.Workbook wb = excel.Workbooks[1]; Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[ "Sheet1" ]; DataTable table = new DataTable(); for ( int i = 0; i < ws.UsedRange.Columns.Count; i++) { DataColumn dc = new DataColumn(); dc.ColumnName = ((Excel.Range)ws.Cells[1, i + 1]).Value; table.Columns.Add(dc); } DataRow dr; for ( int n = 1; n < ws.UsedRange.Rows.Count; n++) { dr = table.NewRow(); for ( int m = 0; m < ws.UsedRange.Columns.Count; m++) { dr[m] = ((Excel.Range)ws.Cells[n + 1, m + 1]).Value; } table.Rows.Add(dr); } |