基于NOPI的Execl模板转换类,直接将Execl模板转换对应的Entity
1、创建实体属性标记
public class CellAttribute : Attribute
{
/// <summary>
///
/// </summary>
/// <param name="displayName">显示名称</param>
/// <param name="hander"></param>
public CellAttribute(string displayName, Type hander = null)
{
DisplayName = displayName; Hander = hander;
} /// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; } /// <summary>
/// 类型
/// </summary>
public Type Hander { get; set; }
}
2、创建通用处理方法
public class XlsFileHandler<T> where T : new()
{
private readonly string _path;
private readonly Dictionary<string, CellAttribute> _cellAttributes;
readonly Dictionary<string, string> _propDictionary; public XlsFileHandler(string path)
{
_path = path;
_cellAttributes = new Dictionary<string, CellAttribute>();
_propDictionary = new Dictionary<string, string>();
CreateMappers();
} /// <summary>
/// 创建映射
/// </summary>
private void CreateMappers()
{
foreach (var prop in typeof(T).GetProperties())
{
foreach (CellAttribute cellMapper in prop.GetCustomAttributes(false).OfType<CellAttribute>())
{
_propDictionary.Add(cellMapper.DisplayName, prop.Name);
_cellAttributes.Add(cellMapper.DisplayName, cellMapper);
}
}
} /// <summary>
/// 获取整个xls文件对应行的T对象
/// </summary>
/// <returns></returns>
public List<T> ToData()
{
List<T> dataList = new List<T>();
using (FileStream stream = GetStream())
{
IWorkbook workbook = new HSSFWorkbook(stream);
ISheet sheet = workbook.GetSheetAt();
var rows = sheet.GetRowEnumerator();
int lastCell = ;
int i = ;
IRow headRow = null;
while (rows.MoveNext())
{
var row = sheet.GetRow(i);
if (i == )
{
headRow = sheet.GetRow();
lastCell = row.LastCellNum;
}
else
{
T t = GetData(workbook, headRow, row, lastCell);
dataList.Add(t);
}
i++;
}
stream.Close();
}
return dataList;
} /// <summary>
/// 获取T对象
/// </summary>
/// <param name="workbook"></param>
/// <param name="headRow"></param>
/// <param name="currentRow"></param>
/// <param name="lastCell"></param>
/// <returns></returns>
private T GetData(IWorkbook workbook, IRow headRow, IRow currentRow, int lastCell)
{
T t = new T();
for (int j = ; j < lastCell; j++)
{
var displayName = headRow.Cells[j].StringCellValue;
if (!_cellAttributes.ContainsKey(displayName) || !_propDictionary.ContainsKey(displayName))
{
continue;
}
var currentAttr = _cellAttributes[displayName];
var propName = _propDictionary[displayName]; ICell currentCell = currentRow.GetCell(j);
string value = currentCell != null ? GetCellValue(workbook, currentCell) : "";
if (currentAttr.Hander != null)
{
SetValue(ref t, propName, InvokeHandler(currentAttr.Hander, value));
}
else
{
SetValue(ref t, propName, value);
}
}
return t;
} /// <summary>
/// 动态执行处理方法
/// </summary>
/// <param name="type"></param>
/// <param name="value"></param>
/// <returns></returns>
private static object InvokeHandler(Type type, object value)
{
System.Reflection.ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor == null) throw new ArgumentNullException("type");
object mgConstructor = constructor.Invoke(null);
System.Reflection.MethodInfo method = type.GetMethod("GetResults");
return method.Invoke(mgConstructor, new[] { value });
} /// <summary>
/// 获取文件流
/// </summary>
/// <returns></returns>
private FileStream GetStream()
{
if (!File.Exists(_path)) throw new FileNotFoundException("path");
return new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read);
} /// <summary>
/// 获取xls文件单元格的值
/// </summary>
/// <param name="workbook"></param>
/// <param name="cell"></param>
/// <returns></returns>
private static string GetCellValue(IWorkbook workbook, ICell cell)
{
string value;
switch (cell.CellType)
{
case CellType.FORMULA:
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(workbook);
value = evaluator.Evaluate(cell).FormatAsString();
break;
default:
value = cell.ToString();
break;
}
return value;
} /// <summary>
/// 设置T属性值
/// </summary>
/// <param name="t"></param>
/// <param name="propName"></param>
/// <param name="value"></param>
private static void SetValue(ref T t, string propName, object value)
{
var typeName = t.GetType().GetProperty(propName).PropertyType.Name;
var property = t.GetType().GetProperty(propName);
switch (typeName)
{
case "Int32":
property.SetValue(t, Convert.ToInt32(value), null);
break;
case "DateTime":
property.SetValue(t, Convert.ToDateTime(value), null);
break;
case "Decimal":
property.SetValue(t, Convert.ToDecimal(value), null);
break;
default:
property.SetValue(t, value, null);
break;
}
}
}
3、创建Execl文件映射类
public class ReadMapper
{
[CellAttribute("测试1")]
public decimal Code { get; set; } [CellAttribute("测试2")]
public int Name { get; set; } [CellAttribute("测试3", typeof(ClassCellHander))]
public string Group { get; set; } [CellAttribute("测试4")]
public DateTime AddTime { get; set; }
}
4、指定Execl文件路径,通过通用处理方法导出映射实体

[Test]
public void Read1()
{
const string filePath = @"C:\Users\zk\Desktop\1.xls";
XlsFileHandler<ReadMapper> handler = new XlsFileHandler<ReadMapper>(filePath);
List<ReadMapper> readMappers = handler.ToData();
Assert.AreEqual(readMappers.Count, );
}
基于NOPI的Execl模板转换类,直接将Execl模板转换对应的Entity的更多相关文章
- 基于Webpack, KnockoutJs,esyui,koeasyui实现类vue-cli生成的模板框架
前后端分离的开发机制,基本上是开发现代业务系统的标配.可在国内某些特殊领域还是存在大量的以JQuery走天涯的现象,但其中也不泛有追求技术者,如不才的鄙人.不才的本人曾以JQuery走天涯:后又接受了 ...
- JSON转换类(二)--List转换成Json、对象集合转换Json等
#region List转换成Json /// <summary> /// List转换成Json /// </summary> public static string Li ...
- PHP模板解析类实例
作者:mckee 这篇文章主要介绍了PHP模板解析类,涉及php针对模板文件的解析与字符串处理的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下 <?php class template { ...
- 基于JavaMail开发邮件发送器工具类
基于JavaMail开发邮件发送器工具类 在开发当中肯定会碰到利用Java调用邮件服务器的服务发送邮件的情况,比如账号激活.找回密码等功能.本人之前也碰到多次这样需求,为此特意将功能封装成一个简单易用 ...
- C++ 模板常见特性(函数模板、类模板)
背景 C++ 是很强大,有各种特性来提高代码的可重用性,有助于减少开发的代码量和工作量. C++ 提高代码的可重用性主要有两方面: 继承 模板 继承的特性我已在前面篇章写过了,本篇主要是说明「模板」的 ...
- C++学习笔记:09 函数模板与类模板
课程<C++语言程序设计进阶>清华大学 郑莉老师) 引入 考虑一个求绝对值函数myabs,对于int,double,float等数据类型需要重载多次,编写多个函数体.函数体逻辑代码完全一致 ...
- C++进阶-1-模板基础(函数模板、类模板)
C++进阶 模板 1.1 函数模板 1 #include<iostream> 2 using namespace std; 3 4 // 模板 5 6 // 模板的简单实例 7 // 要求 ...
- DataTable与DTO对象的简易转换类
在web开发过程中,有时候为了数据传输的方便,比如:后台需要更新前端的ViewModel,此时我们定义一个与前端ViewModel结构一样的DTO对象,从数据层获取数据后,将数据封装成DTO然后序列化 ...
- php byte数组与字符串转换类
<?php /** * byte数组与字符串转化类 * @author ZT */ class Bytes { /** * 转换一个string字符串为byte数组 * @param $str ...
随机推荐
- 附 Java对象内存布局
注意:本篇博客,主要参考自<深入理解Java虚拟机(第二版)> 1.对象在内存中存储的布局分为三块 对象头 存储对象自身的运行时数据:Mark Word(在32bit和64bit虚拟机上长 ...
- Python并发编程-Redis
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Remote Dictionary Server(Redis)是一个基于 key-value ...
- 比较windows phone程序启动和android程序启动原理
windows phone 程序是如何启动的了,他和android程序有什么区别,我们重点从native code 层面来分析 在windows phone 程序启动的时候是: 在XAML中使用应用程 ...
- php中120个内置函数
php中实现事件模式 https://yq.aliyun.com/ziliao/162660 <?php class Event{ private $events = []; public fu ...
- Spring Mongo配置多个Mongos
由于数据存储使用MongoDB集群,在对外访问的时候,地址是Mongos的地址,在使用的过程中没有发现任何问题,配置如下: <mongo:mongo host="${mongodb.h ...
- select设置高度的兼容问题
在IE678下,我们给select设置高度的话,里面的option无法居中,折中的兼容方式就是,我们给select的border:0:外面套一层div,这个div给他设置padding,让select ...
- Setsockopt选项
讨论 Setsockopt选项 http://c.chinaitlab.com/cc/ccjq/200806/752042_3.html 总而言之,如果你肯定能一起发送多个数据集合(例如HTTP响应的 ...
- linux 用户管理,用户权限管理,用户组管理
linux 用户管理,用户权限管理,用户组管理 一:ls -l 命令 解释 第个d表示是目录,如果是文件是-,如果是连接是l 第2到4个 rwx 表示创建者的操作权限 r 读,w 写,x 执行 第5到 ...
- 算法笔记_212:第七届蓝桥杯软件类决赛真题(Java语言B组)
目录 1 愤怒小鸟 2 反幻方 3 打靶 4 路径之谜 5 碱基 6 圆圈舞 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 愤怒小鸟 愤怒小鸟 X星球愤怒的小鸟喜欢撞火车! 一根平直的铁轨上两火车 ...
- jquery position方法使用及兼容性
1.position方法 jquery api地址:http://jquery.cuishifeng.cn/position.html position方法获取匹配元素相对父元素的偏移. 2.说明 2 ...