使用两种方式实现的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的更多相关文章

  1. 使用NPOI读取Excel数据到DataTable

    如今XML文件的存储格式大行其道,可是也不是适用于全部情况,非常多单位的数据交换还是使用Excel的形式.这就使得我们须要读取Excel内的数据.载入到程序中进行处理.可是如何有效率的读取,如何使程序 ...

  2. .NET小笔记-NPOI读取excel内容到DataTable

    下载比较新的NPOI组件支持excel2007以上的,把.dll添加引用 引入命名空间 using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using ...

  3. C#-导入Excel 内容到 DataTable中

    C#-导入Excel 内容到 DataTable中 直接传入文件路径,支持所有Excel格式. 缺点:如果数据量庞大会很占内存. public static DataTable ImportExcel ...

  4. 把Excel转换成DataTable,Excel2003+

    在数据处理的时候,我们会Excel(包含2003.2007.2010等)转换成DataTable,以便进一步操作 1.怎么访问Excel文件呢?我们可以通过OLEDB接口访问,如下: private ...

  5. 读取Excel数据到DataTable

    读取Excel数据到DataTable 代码 /// <summary> /// 获取指定路径.指定工作簿名称的Excel数据:取第一个sheet的数据 /// </summary& ...

  6. 怎么使用Aspose.Cells读取excel 转化为Datatable

    说明:vs2012 asp.net mvc4 c# 使用Aspose.Cells 读取Excel 转化为Datatable 1.HTML前端代码 <%@ Page Language=" ...

  7. 【210】通过OleDb读写Excel数据到DataTable

    参考:C#通过OLEDB读写Excel2013显示到datagrid控件,修改数据集并更新excel2013 解决:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序.( ...

  8. 【C#】采用OleDB读取Excel文件转DataTable

    using System; using System.Data; using System.Data.OleDb; using System.IO; using System.Linq; using ...

  9. NPOI导入excel文件为DataTable,使用SqlBulkCopy添加到数据库表

    public DataTable ExcelToDataTable(Stream stream, string fileName) { DataTable data = new DataTable() ...

随机推荐

  1. 剑指Offer——链表中环的入口结点

    题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...

  2. MapReduce自定义InputFormat和OutputFormat

    一.自定义InputFormat 需求:将多个小文件合并为SequenceFile(存储了多个小文件) 存储格式:文件路径+文件的内容 c:/a.txt I love Beijing c:/b.txt ...

  3. replace未全局替换的坑

    今天是名副其实的周六.悠闲了一早上(太阳). 真是人在家中坐,BUG自天上来.哈哈其实也不是自天上来,还是自己之前埋下的雷. 所以修复完线上的bug,我脑中立刻浮现出两件还需要做的事情: 一,就是我现 ...

  4. python在处理CSV文件时,字符串和列表写入的区别

    概述 Python在处理CSV文件时,如果writerow的对象是<type 'unicode'>字符串时,写入到CSV文件时将会出现一个字符占一个单元格的情况: 但是将字符串转换为列表类 ...

  5. 搭建高性能Jboss负载均衡集群

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/a1314517love/article/details/26836357 负载均衡集群是由两台或者两 ...

  6. MySQL协议分析(2)

    MySQL协议分析(2) 此阶段是在压缩传输无加密条件下进行的协议分析 思路 结合Oracle官网的说明和自己用wireshark加python进行数据包分析 步骤 客户端与服务器端是否压缩的协商阶段 ...

  7. C语言中的extern

    extern: 这个关键字真的比较恶心,在定义变量的时候,extern居然可以被省略(定义时,默认均省略): 在声明变量的时候,extern必须加在变量前. 所以有时候你搞不清楚是声明还是定义.:变量 ...

  8. Oracle 常见问题汇总

    1.Listener refused the connection with the following error 安装之后如果遇到如下问题状态: 失败 -测试失败: Listener refuse ...

  9. JDBC—DAO

    一.JDBC 什么是JDBC?JAVA DataBase Connectivity (Java 数据库连接技术)由Java编写的一组类和接口组成,为各种类型的数据库提供统一的访问.JDBC的作用?一种 ...

  10. CDH5离线安装简记

    需要的介质如下:CM: cloudera-manager-el6-cm5.4.3_x86_64.tar.gzCDH parcel: CDH-5.4.0-1.cdh5.4.0.p0.27-el6.par ...