C# 读取Excel到DataTable两种方式对比
方式一 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;
}
}
C# 读取Excel到DataTable两种方式对比的更多相关文章
- java读取excel文件的两种方式
方式一: 借用 package com.ij34.util; /** * @author Admin * @date 创建时间:2017年8月29日 下午2:07:59 * @version 1.0 ...
- .NET环境下导出Excel表格的两种方式和导入两种类型的Excel表格
一.导出Excel表格的两种方式,其中两种方式指的是导出XML数据类型的Excel(即保存的时候可以只需要修改扩展名为.xls)和真正的Excel这两种. using System; using Sy ...
- C++读取字符串数据的两种方式
C++读取字符串数据的两种方式 对于同样的样例输入: ladder came tape soon leader acme RIDE lone Dreis peat ScAlE orb eye Ride ...
- [Python]xlrd 读取excel 日期类型2种方式
有个excle表格须要做一些过滤然后写入数据库中,可是日期类型的cell取出来是个数字,于是查询了下解决的办法. 主要的代码结构 data = xlrd.open_workbook(EXCEL_PAT ...
- Java值创建线程的两种方式对比
在Java中创建线程的方式有两种,第一种是直接继承Thead类,另一种是实现Runable接口.那么这两种方式孰优孰劣呢? 采用继承Thead类实现多线程: 优势:编写简单,如果需要访问当前线程,只需 ...
- 多线程实现Thread.Start()与ThreadPool.QueueUserWorkItem两种方式对比
Thread.Start(),ThreadPool.QueueUserWorkItem都是在实现多线程并行编程时常用的方法.两种方式有何异同点,而又该如何取舍? 写一个Demo,分别用两种方式实现.观 ...
- java操作excel常用的两种方式
Excel是我们平时工作中比较常用的用于存储二维表数据的,JAVA也可以直接对Excel进行操作,在这篇博客中将为大家介绍两种操作Excel的方式,分别为:jxl和poi. 对于两者的区别网上有测试如 ...
- c# 读取excel数据的两种方法(转)
转载自:http://developer.51cto.com/art/201302/380622.htm, 方法一:OleDb: 用这种方法读取Excel速度还是非常的快的,但这种方式读取数据的时候不 ...
- c# 读取excel数据的两种方法
转载自:http://developer.51cto.com/art/201302/380622.htm, 方法一:OleDb: 用这种方法读取Excel速度还是非常的快的,但这种方式读取数据的时候不 ...
随机推荐
- Mysql 在线新建或重做主从
1. 前言 以前给 Mysql 数据库做主从,都是在主服务器停服的情况下做的.但是最近有一个项目,已经上线几天了,数据库也单服务器跑了几天,才确定要给 Mysql 服务器做一个主从架构,简单的一主一从 ...
- CentOS7时区和时间设置
[root@saltstack-master ~]# timedatectl set-timezone Asia/Shanghai [root@saltstack-master ~]# ln -sf ...
- A water problem 大数取余。
A water problem Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- DotNet源码学习-HASHSET(初探)
命名空间:System.Collections.Generic 先看一下官方说明:类提供了高级的设置操作.集是不包含重复元素的集合,其元素无特定顺序. HashSet <T>对象的容量是对 ...
- MySQL 什么是索引?
该文为< MySQL 实战 45 讲>的学习笔记,感谢查看,如有错误,欢迎指正 一.索引简介 索引就类似书本的目录,作用就是方便我们更加快速的查找到想要的数据. 索引的实现方式比较多,常见 ...
- mysql 查询出现 "this is incompatible with sql_mode=only_full_group_by"错误解决方案,以及个人rpm方式重装所遇到的问题备份
一.错误说明 这个错误发生在mysql 5.7 版本及以上版本会出现的问题: mysql .7版本默认的sql配置是:sql_mode="ONLY_FULL_GR ...
- 探究Redis两种持久化方式下的数据恢复
对长期奋战在一线的后端开发人员来说,都知道redis有两种持久化方式RDB和AOF,虽说大家都知道这两种方式大概运作方式,但想必有实操的人不会太多. 这里是自己实操两种持久化方式的一点点记录. 先看以 ...
- 【56】目标检测之NMS非极大值抑制
非极大值抑制(Non-max suppression) 到目前为止你们学到的对象检测中的一个问题是,你的算法可能对同一个对象做出多次检测,所以算法不是对某个对象检测出一次,而是检测出多次.非极大值抑制 ...
- php根据字段相识度进行排序查询
$data = [ [ 'id'=>1, 'title'=>'test内容管理系统', ], [ 'id'=>2, 'title'=>'开源test', ], [ 'id'=& ...
- 一、threejs————灯光阴影
threejs设置阴影有三个注意点 1.只有支持阴影的灯光才可以 pointLight,spotlight,directionallight 2.添加摄像机辅助器 THREE.CameraHelper ...