基于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 ...
随机推荐
- Keras Data augmentation(数据扩充)
在深度学习中,我们经常需要用到一些技巧(比如将图片进行旋转,翻转等)来进行data augmentation, 来减少过拟合. 在本文中,我们将主要介绍如何用深度学习框架keras来自动的进行data ...
- Android中intent如何传递自定义数据类型
转载自:http://www.cnblogs.com/GoAhead/archive/2012/07/16/2593868.html 大家好,好久不见,今天要给大家讲一下Android中Intent中 ...
- Inside GDALAllRegister之一: 五大部分
基本信息 在GDAL的Tutorial中开篇即提到GDALAllRegister函数,它会注册所有已知的驱动,包括动态库自动加载的驱动.最关键是这句话: If for some application ...
- Angular6
Structural Directives https://angular.io/guide/structural-directives#template-input-variable There a ...
- MFC 小知识总结二
1 UpdateData 不能及时更新控件内容 原因: UpdateData是通过数据交换实现改变控件显示的.改变了之后必需要调用一次OnPaint才干实现刷新. 因此,若是在一个函数里重复多次调用有 ...
- HDU 2544最短路dijkstra模板题
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- 能说明你的Javascript技术很烂的五个原因
Javascript在互联网上名声很臭,但你又很难再找到一个像它这样如此动态.如此被广泛使用.如此根植于我们的生活中的另外一种语言.它的低学习门槛让很多人都称它为学前脚本语言,它另外一个让人嘲笑的东西 ...
- 谷歌浏览器保存网页为pdf和.mhtml文件
注:需要安装chrome谷歌浏览器,尽可能安装最新版的浏览器: 一:保存为pdf 打开要加载的网页 空白处右键-----打印 配置要打印的pdf网页 点击 左边----> 保存按钮 即可: ...
- Hibernate(十四)缓存
一.什么是缓存 缓存是介于应用程序和永久必数据存储源之间,目的是为了降低应用程序直接读写永久必数据存储源的频率,从而提高运行性能 缓存通常是在内存中的如: Office中的Word.excel Hib ...
- Java从零开始学三十一(DATE和Calendar类)
一.Date类 Date类是一个相对较为简单的操作类,在使用中直接使用java.util.Date类的构造方法并进行输出就可以得到一个完整的日期 二.Calendar类 Calendar类可以将取得的 ...