Excel转化成DataTable实现:NPOI和OLEDb
使用两种方式实现的excel数据转化成DataSet,再结合前一篇的DataTable转化为实体,就可以解决excel到实体之间的转化。
代码如下:
首先定义一个接口:
public interface IExcelAccess
{
DataSet Load(ExcelConfig config);
}
public class ExcelConfig
{
/// <summary>
/// 文件存储路径
/// </summary>
public string Path { get; set; } /// <summary>
/// 文件表头所在行索引
/// </summary>
public int HeaderIndex { get; set; }
}
再来看一下使用NPOI的实现:
public class NpoiExcelAccess : IExcelAccess
{
/// <summary>
/// 根据文件扩展名,获取workbook实例
/// </summary>
/// <param name="ext"></param>
/// <returns></returns>
private IWorkbook GetWorkBook(string ext, Stream stream)
{
IWorkbook workbook = null; switch (ext)
{
case ".xlsx":
workbook = new XSSFWorkbook(stream);
break;
case ".xls":
workbook = new HSSFWorkbook(stream);
break;
default:
break;
} return workbook;
} /// <summary>
/// 加载数据,可设置跳过前几行
/// </summary>
/// <param name="path"></param>
/// <param name="skipRows"></param>
/// <returns></returns>
public DataSet Load(ExcelConfig config)
{
using (var fileStream = new FileStream(config.Path, FileMode.Open, FileAccess.Read))
{
var ds = new DataSet();
var ext = Path.GetExtension(config.Path); // 新建IWorkbook对象
var workbook = this.GetWorkBook(ext, fileStream); for (int i = ; i < workbook.NumberOfSheets; i++)
{
ISheet sheet = workbook.GetSheetAt(i);
DataTable dt = GetDataTable(sheet, config.HeaderIndex);
ds.Tables.Add(dt);
} return ds;
}
} private DataTable GetDataTable(ISheet sheet, int headerIndex)
{
var dt = new DataTable();
// 获取表头行
var headerRow = sheet.GetRow(headerIndex);
var cellCount = GetCellCount(sheet, headerIndex); // 设置表头
for (int i = ; i < cellCount; i++)
{
if (headerRow.GetCell(i) != null)
{
dt.Columns.Add(headerRow.GetCell(i).StringCellValue, typeof(string));
}
} for (int i = headerIndex + ; i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
DataRow dr = dt.NewRow();
FillDataRow(row, ref dr);
dt.Rows.Add(dr);
} dt.TableName = sheet.SheetName;
return dt; } private void FillDataRow(IRow row, ref DataRow dr)
{
if (row != null)
{
for (int j = ; j < dr.Table.Columns.Count; j++)
{
ICell cell = row.GetCell(j); if (cell != null)
{
switch (cell.CellType)
{
case CellType.Blank:
dr[j] = DBNull.Value;
break;
case CellType.Boolean:
dr[j] = cell.BooleanCellValue;
break;
case CellType.Numeric:
if (DateUtil.IsCellDateFormatted(cell))
{
dr[j] = cell.DateCellValue;
}
else
{
dr[j] = cell.NumericCellValue;
}
break;
case CellType.String:
dr[j] = cell.StringCellValue;
break;
case CellType.Error:
dr[j] = cell.ErrorCellValue;
break;
case CellType.Formula:
// cell = evaluator.EvaluateInCell(cell) as HSSFCell;
dr[j] = cell.ToString();
break;
default:
throw new NotSupportedException(string.Format("Catched unhandle CellType[{0}]", cell.CellType));
}
}
}
}
} /// <summary>
/// 获取表头列数
/// </summary>
/// <param name="sheet"></param>
/// <param name="skipRows"></param>
/// <returns></returns>
private int GetCellCount(ISheet sheet, int headerIndex)
{
var headerRow = sheet.GetRow(headerIndex); return headerRow.LastCellNum;
}
}
最后看一下使用OLEDB的实现,这里,我只实现了excel2003的版本,07版本的总是失败,查了原因,是需要在本机安装一个组件才能支持导入.xlsx文件。
public class OleDbExcelAccess : IExcelAccess
{
private string strConn; public OleDbExcelAccess()
{
//TODO 需要根据扩展名,来决定 使用哪一种连接字符串
strConn = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = {0};Extended Properties='Excel 8.0;IMEX=1;HDR=NO'";
} public DataSet Load(ExcelConfig config)
{
var ds = new DataSet();
var sheets = GetSheetNames(config.Path);
var strConnTmp = string.Format(strConn, config.Path); foreach (string sheet in sheets)
{
using (var oleConn = new OleDbConnection(strConnTmp))
{
var strsql = "SELECT * FROM [" + sheet + "]";
var oleDaExcel = new OleDbDataAdapter(strsql, oleConn);
oleConn.Open();
oleDaExcel.Fill(ds, sheet);
}
} return ds;
} /// <summary>
/// 获取Excel的所有的sheet
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private string[] GetSheetNames(string path)
{
DataTable dt = new DataTable();
if (File.Exists(path))
{
string strConnTmp = string.Format(strConn, path);
using (var conn = new OleDbConnection(strConnTmp))
{
conn.Open();
//返回Excel的架构,包括各个sheet表的名称,类型,创建时间和修改时间等
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
}
//包含excel中表名的字符串数组
var sheetNames = new List<string>();
for (int k = ; k < dt.Rows.Count; k++)
{
string tableName = dt.Rows[k]["TABLE_NAME"].ToString();
//修正出现兼容性视图名称时过滤表名
if (!tableName.Substring(tableName.Length - ).Equals("_"))
{
sheetNames.Add(tableName);
}
}
return sheetNames.ToArray(); }
return null; }
}
最后看一下客户端的调用 :
private void TestExcelImport()
{
var excelFile = Path.Combine("C:\\Users\\hankk\\Desktop\\ICON", "2003版本.xls"); ExcelConfig config = new ExcelConfig()
{
Path = excelFile,
HeaderIndex =
}; IExcelAccess npoiAccess = new NpoiExcelAccess();
var npoiDs = npoiAccess.Load(config); IExcelAccess oleDbAccess = new OleDbExcelAccess();
var oleDs = oleDbAccess.Load(config);
}
代码已上传到github: https://github.com/hankuikuide/ExcelAccessor
Excel转化成DataTable实现:NPOI和OLEDb的更多相关文章
- 使用NPOI读取Excel数据到DataTable
如今XML文件的存储格式大行其道,可是也不是适用于全部情况,非常多单位的数据交换还是使用Excel的形式.这就使得我们须要读取Excel内的数据.载入到程序中进行处理.可是如何有效率的读取,如何使程序 ...
- .NET小笔记-NPOI读取excel内容到DataTable
下载比较新的NPOI组件支持excel2007以上的,把.dll添加引用 引入命名空间 using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using ...
- C#-导入Excel 内容到 DataTable中
C#-导入Excel 内容到 DataTable中 直接传入文件路径,支持所有Excel格式. 缺点:如果数据量庞大会很占内存. public static DataTable ImportExcel ...
- 把Excel转换成DataTable,Excel2003+
在数据处理的时候,我们会Excel(包含2003.2007.2010等)转换成DataTable,以便进一步操作 1.怎么访问Excel文件呢?我们可以通过OLEDB接口访问,如下: private ...
- 读取Excel数据到DataTable
读取Excel数据到DataTable 代码 /// <summary> /// 获取指定路径.指定工作簿名称的Excel数据:取第一个sheet的数据 /// </summary& ...
- 怎么使用Aspose.Cells读取excel 转化为Datatable
说明:vs2012 asp.net mvc4 c# 使用Aspose.Cells 读取Excel 转化为Datatable 1.HTML前端代码 <%@ Page Language=" ...
- 【210】通过OleDb读写Excel数据到DataTable
参考:C#通过OLEDB读写Excel2013显示到datagrid控件,修改数据集并更新excel2013 解决:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序.( ...
- 【C#】采用OleDB读取Excel文件转DataTable
using System; using System.Data; using System.Data.OleDb; using System.IO; using System.Linq; using ...
- NPOI导入excel文件为DataTable,使用SqlBulkCopy添加到数据库表
public DataTable ExcelToDataTable(Stream stream, string fileName) { DataTable data = new DataTable() ...
随机推荐
- 数据库 - MySQL - 总结
总结: MySQL 表操作 - 练习题 多表查询 - 练习题 建表查询 - 作业
- Zookeeper简介及使用
一.Zookeeper简介 1.zookeeper简介 动物管理员 Apache ZooKeeper致力于开发和维护开源服务器,实现高度可靠的分布式协调. 2.什么是ZooKeeper? ZooKee ...
- LeetCode—Longest Consecutive Sequence
题目描述: Given an unsorted array of integers, find the length of the longest consecutive elements seque ...
- PHP error_log 新认知
//error_log 简介及使用方法 // error_log("消息","类型","路径"); //message //type ...
- Spring整合JUnit4进行AOP单元测试的时候,报:"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.3\lib\idea_rt.jar=64
错误代码 "C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" -ea -Didea.test.cyclic.buffer.size= ...
- 『HTML5挑战经典』是英雄就下100层-开源讲座(二)危险!英雄
本篇为<『HTML5挑战经典』是英雄就下100层-开源讲座>第二篇,需要用到开源引擎lufylegend,可以到这里下载: 下载地址:http://lufylegend.googlecod ...
- Spring第一弹—-全面阐述Spring及轻重量级容器的划分
Spring是什么? Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架,它的主要目得是简化企业开发. IOC 控制反转 : 1 ...
- koa2链接mongodb
数据库使用的mongodbmongodb下载:https://www.mongodb.com/mongodb GUI:https://robomongo.org/ 使用中间件koa来搭建框架使用中间件 ...
- 2017浙江省赛 D - Let's Chat ZOJ - 3961
地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3961 题目: ACM (ACMers' Chatting Messe ...
- yarn nodes label (yarn 划分子集群)
yarn node labels 特性给节点打标签可以把特性类似的节点分成一组,这样可以指定特定的应用执行在特定的机器群上.现在我们只支持节点划分,1.一个节点仅能有一个节点划分,即一个节点只能打一个 ...