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的更多相关文章

  1. 基于Webpack, KnockoutJs,esyui,koeasyui实现类vue-cli生成的模板框架

    前后端分离的开发机制,基本上是开发现代业务系统的标配.可在国内某些特殊领域还是存在大量的以JQuery走天涯的现象,但其中也不泛有追求技术者,如不才的鄙人.不才的本人曾以JQuery走天涯:后又接受了 ...

  2. JSON转换类(二)--List转换成Json、对象集合转换Json等

    #region List转换成Json /// <summary> /// List转换成Json /// </summary> public static string Li ...

  3. PHP模板解析类实例

    作者:mckee 这篇文章主要介绍了PHP模板解析类,涉及php针对模板文件的解析与字符串处理的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下 <?php class template { ...

  4. 基于JavaMail开发邮件发送器工具类

    基于JavaMail开发邮件发送器工具类 在开发当中肯定会碰到利用Java调用邮件服务器的服务发送邮件的情况,比如账号激活.找回密码等功能.本人之前也碰到多次这样需求,为此特意将功能封装成一个简单易用 ...

  5. C++ 模板常见特性(函数模板、类模板)

    背景 C++ 是很强大,有各种特性来提高代码的可重用性,有助于减少开发的代码量和工作量. C++ 提高代码的可重用性主要有两方面: 继承 模板 继承的特性我已在前面篇章写过了,本篇主要是说明「模板」的 ...

  6. C++学习笔记:09 函数模板与类模板

    课程<C++语言程序设计进阶>清华大学 郑莉老师) 引入 考虑一个求绝对值函数myabs,对于int,double,float等数据类型需要重载多次,编写多个函数体.函数体逻辑代码完全一致 ...

  7. C++进阶-1-模板基础(函数模板、类模板)

    C++进阶 模板 1.1 函数模板 1 #include<iostream> 2 using namespace std; 3 4 // 模板 5 6 // 模板的简单实例 7 // 要求 ...

  8. DataTable与DTO对象的简易转换类

    在web开发过程中,有时候为了数据传输的方便,比如:后台需要更新前端的ViewModel,此时我们定义一个与前端ViewModel结构一样的DTO对象,从数据层获取数据后,将数据封装成DTO然后序列化 ...

  9. php byte数组与字符串转换类

    <?php /** * byte数组与字符串转化类 * @author ZT */ class Bytes { /** * 转换一个string字符串为byte数组 * @param $str ...

随机推荐

  1. Vue路由scrollBehavior滚动行为控制锚点

    使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样. vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动. 注意: 这个功能只 ...

  2. 【Hibernate】Hibernate3.x独立执行时的Failed to load class &quot;org.slf4j.impl.StaticLoggerBinder&quot;错误

    按理说,假设Hibernate不依附于SSH执行,像<[Struts2+Hibernate3+Spring3]利用SSH整合,完毕打印用户表,用户登录.注冊.改动password系统>(点 ...

  3. Visio 2013 由于形状保护、容器和/或图层属性的设置,无法完全执行此命令

    形状的保护 解决问题:Visio 2013 由于形状保护.容器和/或图层属性的设置,无法完全执行此命令 重要: 本文是由机器翻译的,请参阅免责声明.请在 此处 中查找本文的英文版本以便参考. 禁止对形 ...

  4. easyui combotree模糊查询

    技术交流QQ群:15129679 让EasyUI的combobox和combotree同时支持自定义模糊查询,在不更改其他代码的情况下,添加以下代码就行了: /** * combobox和combot ...

  5. WebService SOAP、Restful和HTTP(post/get)请求区别

    web service(SOAP) Webservice的一个最基本的目的就是提供在各个不同平台的不同应用系统的协同工作能力. Web service 就是一个应用程序,它向外界暴露出一个能够通过We ...

  6. Step by Step iOS Project In Action - 视图控制器

    1. 什么是视图控制器(View Controller) 简单来说,视图控制器用来管理你所有的视图. 他们是你的视图和模型的粘合剂. 如果你做过MVC的Web项目,我想你应该不会对它感到陌生. 2. ...

  7. C++运行库 Neptune C++ Runtime Library(xbmc)

    一个可以在多个平台C++开发环境下编译运行的C++运行库.其中包括了对多个C++库和平台SDK(HTTP/TCP/UDP/XML, Thread/Message, String, List/Stack ...

  8. android 随手记 读写文件的几种方式

    java中多种方式读文件 一.多种方式读文件内容. 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内容 4.随机读取文件内容 */ import java.io.BufferedRe ...

  9. 如何分析Java虚拟机死锁

    Thread Dump and Concurrency Locks Thread dumps are very useful for diagnosing synchronization relate ...

  10. Android:Dialog中隐藏键盘的注意事项

    场景:弹出一个Dialog.里面有一个EditText.用来输入内容.由于输入时.须要弹出键盘.所以当Dialog消失时.键盘要一起隐藏. 如今我们做一个自己定义的Dialog MyDialog ex ...