方式一 OLEDB讀取 數據庫引擎
優點:讀取速度快,依據sheet排序讀取
缺點:對於Excel版本依賴強,無法讀取指定sheet
錯誤提示:本地計算機未指定 Microsoft.ACE.OLEDB.12.0
解決方法:win7(64位)+office 2010(64位) 更改目標平台為X86
win10(64位)+office 2010(64位) 更改目標平台無效,下載安裝AccessDatabaseEngine.exe,重啟無效,項目需求采用方式二
注:2019年7月20日之前和平台無關,均可使用(可能office服務被禁,公司特殊),情況緊急,采用方式二。
代碼如下:
public static List<DataTable> excelToDataTable(string filePath)
{
List<DataTable> dtList = new List<DataTable>();
string connStr = "";
string fileType = System.IO.Path.GetExtension(filePath);
if (string.IsNullOrEmpty(fileType)) return null;
if (fileType == ".xls")
connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath + ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";
else
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath + ";" + ";Extended Properties=\"Excel 12.0;HDR=N0;IMEX=1\"";
string sql_F = "Select * FROM [{0}]";
OleDbConnection conn = null;
OleDbDataAdapter da = null;
DataTable dtSheetName = null;
DataSet ds = new DataSet();
DataTable dtNew = new DataTable();
try
{
// 初始化連接,並打開
conn = new OleDbConnection(connStr);
conn.Open();
// 獲取數據源的表定義元數據
string SheetName = "";
dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
// 初始化適配器
da = new OleDbDataAdapter();
for (int i = 0; i < dtSheetName.Rows.Count; i++)
{
DataTable dt = new DataTable();
SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];
if (SheetName.Contains("$") && !SheetName.Replace("'", "").EndsWith("$"))
{
continue;
}
da.SelectCommand = new OleDbCommand(String.Format(sql_F, SheetName), conn);
dt.TableName = i.ToString();
da.Fill(dt);
dtList.Add(dt);
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.ToString());
}
finally
{
// 關閉連接
if (conn.State == ConnectionState.Open)
{
conn.Close();
da.Dispose();
conn.Dispose();
}
}
return dtList;
}
方式二 Excel引擎讀取 Microsoft.Office.Interop.Excel
使用方式:引用 Microsoft.Office.Interop.Excel 調用Excel讀取
優點:不受Excel版本限制,可指定sheet讀取
缺點:讀取速度慢,幾千數據10分鍾
代碼如下:
public static List<DataTable> excelToDataTable(string filePath,bool hasTitle = false)
{
List<DataTable> dtList = new List<DataTable>();
int iRowCount;
int iColCount;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Sheets sheets;
object oMissiong = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Workbook workbook = null;
DataTable dt = new DataTable();
try
{
if (app == null) return null;
workbook = app.Workbooks.Open(filePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong,
oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
sheets = workbook.Worksheets;
//將數據讀入到DataTable中
Microsoft.Office.Interop.Excel.Worksheet worksheet = sheets.get_Item(1);
if (worksheet == null) return null;
iRowCount = worksheet.UsedRange.Rows.Count;
iColCount = worksheet.UsedRange.Columns.Count;
//生成列頭
for (int i = 0; i < iColCount; i++)
{
var name = "column" + i;
if (hasTitle)
{
var txt = ((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, i + 1]).Text.ToString();
if (!string.IsNullOrWhiteSpace(txt)) name = txt;
}
while (dt.Columns.Contains(name)) name = name + "_1";//重復行名稱會報錯。
dt.Columns.Add(new DataColumn(name, typeof(string)));
}
//生成行數據
Microsoft.Office.Interop.Excel.Range range;
int rowIdx = hasTitle ? 2 : 1;
for (int iRow = rowIdx; iRow <= iRowCount; iRow++)
{
DataRow dr = dt.NewRow();
for (int iCol = 1; iCol <= iColCount; iCol++)
{
range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[iRow, iCol];
dr[iCol - 1] = (range.Value2 == null) ? "" : range.Text.ToString();
}
dt.Rows.Add(dr);
}
dtList.Add(dt);
for (int i = 2; i <= sheets.Count; i++)
{
worksheet=sheets.get_Item(i);//讀取第一張表
iRowCount = worksheet.UsedRange.Rows.Count;
iColCount = worksheet.UsedRange.Columns.Count;
//生成列頭
for (int j = 0; j < iColCount; j++)
{
var name = "column" + i;
if (hasTitle)
{
var txt = ((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, j + 1]).Text.ToString();
if (!string.IsNullOrWhiteSpace(txt)) name = txt;
}
while (dt.Columns.Contains(name)) name = name + "_1";//重復行名稱會報錯。
dt.Columns.Add(new DataColumn(name, typeof(string)));
}
//生成行數據
Microsoft.Office.Interop.Excel.Range range1;
int rowIdx1 = hasTitle ? 2 : 1;
for (int iRow = rowIdx1; iRow <= iRowCount; iRow++)
{
DataRow dr = dt.NewRow();
for (int iCol = 1; iCol <= iColCount; iCol++)
{
range1 = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[iRow, iCol];
dr[iCol - 1] = (range1.Value2 == null) ? "" : range1.Text.ToString();
}
dt.Rows.Add(dr);
}
dtList.Add(dt);
}
return dtList;
}
catch { return null; }
finally
{
workbook.Close(false, oMissiong, oMissiong);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
workbook = null;
app.Workbooks.Close();
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
app = null;
}
}
