C#读取Excel数据的几种方式(包含大量数据读取)
常用的Excel数据读取方式有三种:
OleDB方式
- 这种方式需要安装
AccessDatabaseEngine
,实际上就是一种利用ACCESS数据库的方式读取数据至DataTable。下载链接 - 这种方法使用简单,读取速度快,尤其适合小批量数据读取。
WHC.OrderWater.Commons
中有完成的操作封装,日常使用足矣。下载链接 - 缺点是当数据量非常大时(比如超过2w行),会非常占用内存,甚至可能存在内存溢出的异常,需要使用其他方式。
public static DataSet ExcelToDataSet(string excelPath, bool header, ExcelType eType)
{
string connectstring = GetExcelConnectstring(excelPath, header, eType);
return ExcelToDataSet(connectstring);
}
public static DataSet ExcelToDataSet(string connectstring)
{
using (OleDbConnection conn = new OleDbConnection(connectstring))
{
DataSet ds = new DataSet();
List<string> tableNames = GetExcelTablesName(conn);
foreach (string tableName in tableNames)
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [" + tableName + "]", conn);
adapter.Fill(ds, tableName);
}
return ds;
}
}
COM组件的方式
- 这种方式需要添加
Microsoft.Office.Interp.Excel
引用,可用NuGet安装引用。 - 优点是能够非常灵活的读取Excel中的数据,还可以灵活调用各种函数。如果通过
WorkSheet.Range()
方式读取可以极大地提升读取速度,适用于批量数据读取。 - 缺点是需要后台打开Excel,数据量较小时读取速度优势不明显。
/// <summary>
/// 读取Excel中某一范围的数据
/// </summary>
/// <param name="excelPath">待读取的Excel文件路径</param>
/// <param name="stCell">起始单元格编号</param>
/// <param name="edCell">终止单元格编号</param>
/// <returns>存放连续读取的数据的二维数组</returns>
public static object[,] GetExcelRangeData(string excelPath, string stCell, string edCell)
{
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
Workbook workBook = null;
object oMissiong = Missing.Value;
try
{
workBook = app.Workbooks.Open(excelPath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong,
oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
if (workBook == null)
return null;
Worksheet workSheet = (Worksheet) workBook.Worksheets.Item[1];
//使用下述语句可以从头读取到最后,按需使用
//var maxN = workSheet.Range[startCell].End[XlDirection.xlDown].Row;
return workSheet.Range[stCell + ":" + edCell].Value2;
}
catch (Exception e)
{
return null;
}
finally
{
//COM组件方式调用完记得释放资源
if (workBook != null)
{
workBook.Close(false, oMissiong, oMissiong);
Marshal.ReleaseComObject(workBook);
app.Workbooks.Close();
app.Quit();
Marshal.ReleaseComObject(app);
}
}
}
//随便写的一个调用案例
public static List<Edge> ReadAllEdgesFromFile()
{
List<Edge> lstEdges = new List<Edge>();
object[,] data = ExcelHelper.GetExcelRangeData(FilePath, "A1", "C82412");
int length = data.GetLength(0);
//注意这里是从1开始的,调试的时候才发现
for (int i = 1; i <= length; i++)
{
Edge edge = new Edge();
//注意这里是从1开始的,调试的时候才发现
edge.EdgeID = Convert.ToInt32(data[i, 1]);
edge.EdgeStartIndex = Convert.ToInt32(data[i, 2]);
edge.EdgeEndIndex = Convert.ToInt32(data[i, 3]);
edge.StSelected = false;
edge.EdSelected = false;
lstEdges.Add(edge);
}
return lstEdges;
}
NPOI方式读取(此处未测试,参考其他博文)
- NPOI是POI项目的.NET版本,用于读写Excel/Word等微软OLE2组件文档。
- 优点是读取Excel速度较快,读取方式灵活。
- 缺点是需要下载相关插件。
- 此处代码请参考以下博文链接:C#读取Excel的三种方式以及比较