基于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 ...
 
随机推荐
- C#代码审查工具 StyleCop
			
SourceAnalysis (StyleCop)的终极目标是让所有人都能写出优雅和一致的代码,因此这些代码具有很高的可读性. SourceAnalysis (StyleCop)不是代码格式化(代码美 ...
 - input框设置onInput事件只能输入数字,能兼容火狐IE9
			
使用onInput()事件 onInput()是 HTML5 的标准事件,对于检测 textarea, input:text, input:password 和 input:search 这几个元素通 ...
 - 变量声明置顶规则、函数声明及函数表达式和函数的arguments属性初始化
			
一.变量声明和变量赋值: if (!("a" in window)) { ; } alert(a);//a为? 你可能认为alert出来的结果是1,然后实际结果是“undefine ...
 - Discuz常见大问题-如何自定义单个页面
			
比如我们先做一个最简单的网站的最后一页关于我们(插入了一幅图片,同时加入了几行文字) 先做好两个页面的文件(php页面是负责解析htm页面的,目前这两个页面都是空的) mypage_about.php ...
 - ZH奶酪:Linux新建用户+远程登录
			
7.想在VBUbuntu中新建一个账户,但是用useradd命令发现没有权限,原来Ubuntu默认不是root权限登录,需要按照下边的教程才能新建用户. http://www.linuxidc.com ...
 - Hibernate(五)基本数据类型
			
一.Hibernate的基本数据类型 3种数据类型之间的对应关系 Hibernate映射类型 Java类型 标准SQL类型 integer java.lang.Integer INTEGER long ...
 - TP框架中APP_SUB_DOMAIN_DEPLOY什么意思?
			
'APP_SUB_DOMAIN_DEPLOY' => false, // 是否开启子域名部署 thinkphp开启域名部署/子域名部署/泛域名部署/IP访问部署 Think ...
 - 各种样式的table 及 代码
			
1.模板一 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...
 - TopCoder  SRM624 BuildingHeightEasy 题解
			
本题题意就是求有一组建筑物,问把这些建筑物的M个都统一到同一高度.须要的最小改动高度是多少? 题意隐含的意思就是由于是建筑物,所以不能降低,仅仅能添加了. 本题能够使用暴力搜索,由于数据量少. 可是事 ...
 - jquery 清除style样式
			
$("#show").removeAttr("style"); //ie,ff均支持 $("#show").attr("style ...