由于使用的习惯以及需求,对NOPI 中操作Excel 做了个简单的封装,简单快速的进行数据的导入导出。
话不多说,直接上源码。
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace NPOIExcelExtend
{
public static class ExcelExtend
{
/// <summary>
/// 读取Excel数据
/// 读取的第一行会识别为 "头部"
/// 模型 T 属性要跟第一行"头部"对的上
/// </summary>
/// <typeparam name="T">模型 T 属性要跟第一行"头部"对的上</typeparam>
/// <param name="workBook">工作簿</param>
/// <param name="fileName">文件名(绝对路径)</param>
/// <param name="selectSheet">簿名</param>
/// <param name="startRow">开始读取的行数(读的第一行为头部)</param>
/// <returns></returns>
public static IList<T> ReadData<T>(this IWorkbook workBook, string fileName, int selectSheet = 0, int startRow = 0)
{
var extension = Path.GetExtension(fileName);
using (FileStream fs = File.OpenRead(fileName))
{
if (extension.Equals(".xls"))
{
//把xls文件中的数据写入wk中
workBook = new HSSFWorkbook(fs);
}
else
{
//把xlsx文件中的数据写入wk中
workBook = new XSSFWorkbook(fs);
}
}
var sheet = workBook.GetSheetAt(selectSheet);
var row = sheet.GetRow(startRow);
//列号和头部名称映射,之后可以根据列号获取对应的属性
var dicCellNumberMapHeadName = new Dictionary<int, string>();
//头部字段跟属性有效性映射,后面判断属性是否可用再进行赋值
var dicPropertyMapAvailable = new Dictionary<string, bool>();
var type = typeof(T);
for (int i = 0; i < row.LastCellNum; i++)
{
var value = row.GetCell(i).ToString();
dicCellNumberMapHeadName.Add(i, value);
if (type.GetProperty(value) != null)
{
dicPropertyMapAvailable.Add(value, true);
}
else
{
dicPropertyMapAvailable.Add(value, false);
}
}
var result = new List<T>();
//遍历所有行
while ((row = sheet.GetRow(++startRow)) != null)
{
var t = Activator.CreateInstance<T>();
for (int i = 0; i < row.LastCellNum; i++)
{
var colName = dicCellNumberMapHeadName[i];
var isPropertyAvailable = dicPropertyMapAvailable[colName];
//判断属性是否可用,可用再进行赋值
if (isPropertyAvailable)
{
var property = type.GetProperty(colName);
var cell = row.GetCell(i);
dynamic value;
switch (cell.CellType)
{
case CellType.Blank:
value = null;
break;
case CellType.Boolean:
value = cell.BooleanCellValue;
break;
case CellType.Error:
value = cell.ErrorCellValue;
break;
case CellType.Formula:
value = cell.CellFormula;
break;
case CellType.Numeric:
value = cell.NumericCellValue;
break;
case CellType.String:
value = cell.StringCellValue;
break;
case CellType.Unknown:
value = cell.ToString();
break;
default: value = null;
break;
}
if (value != null)
{
property.SetValue(t, Convert.ChangeType(value, property.PropertyType), null);
}
}
else
{
continue;
}
}
result.Add(t);
}
return result;
}
/// <summary>
/// 写入数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="workBook">工作簿</param>
/// <param name="dataList">数据源</param>
/// <param name="sheetName">表名称</param>
/// <returns></returns>
public static MemoryStream WriteData<T>(this IWorkbook workBook ,IList<T> dataList,string sheetName="sheet1")
{
workBook = new HSSFWorkbook();
var sheet = workBook.CreateSheet(sheetName);
var properties = typeof(T).GetProperties();
var stream = new MemoryStream();
for (int i = 0; i < dataList.Count; i++)
{
var row = sheet.CreateRow(i);
for (int j = 0; j < properties.Count(); j++)
{
var cell = row.CreateCell(j);
var value = properties[j].GetValue(dataList[i], null);
cell.SetCellValue(value == null ? "" : value.ToString());
}
}
workBook.Write(stream);
stream.Flush();
stream.Position = 0;
return stream;
}
}
}
码云源码