Epplus下的一个将Excel转换成List的范型帮助类
因为前一段时间公司做项目的时候,用到了Excel导入和导出,然后自己找了个插件Epplus进行操作,自己将当时的一些代码抽离出来写了一个帮助类。
因为帮助类是在Epplus基础之上写的,项目需要引用Epplus.dll。自己基础不是很扎实,有问题的地方欢迎指导。
1.用法,默认excel第一列是头部信息。
public class UserInfo : XlsRow
{
public int id { get; set; }
public string username { get; set; }
public string address { get; set; }
public int userage { get; set; }
public DateTime birthday { get; set; }
public decimal total { get; set; }
public string grade { get; set; }
} static void Main(string[] args)
{
string filePath = "E:\\ExcelConvertEntity\\datatest.xlsx"; //转换address列的时候在所有地址钱添加“上海市”三个字
ECEntityCOM<UserInfo>.ForMember(e => e.address, e => "上海市:" + e); //excel列name对应实体username进行映射
ECEntityCOM<UserInfo>.ForMember("name", e => e.username); //列名age映射到实体userage属性,映射过程中给所有age加5
ECEntityCOM<UserInfo>.ForMember("age", e => e.userage, e => Convert.ToInt32(e) + ); //读取excel转换成List<UserInfo>
List<UserInfo> list = ECEntityCOM<UserInfo>.LoadFromExcel(filePath); Console.WriteLine("ok");
Console.ReadLine();
}
a.实体需要继承我的自定义实体XlsRow,这个实体会记录转换过程出错信息,转换这一行的时候,是否出现过错误,具体是那一列出错的。转换出错单元格内内容是什么,还有错误信息。
public class XlsRow
{
/// <summary>
/// 错误信息
/// </summary>
public List<string> ErrMessage { get; set; } /// <summary>
/// 错误列名
/// </summary>
public List<string> ErrColumn { get; set; } /// <summary>
/// 错误内容
/// </summary>
public List<string> ErrValue { get; set; } /// <summary>
/// 是否转换出错(false:未出错,true:出错)
/// </summary>
public bool IsErr { get; set; }
}
然后转换过程中提供了几个方法,用来更好的自定义转换形式。
b.转换过程中,某一列统一进行某些处理操作,最后把处理后的信息存进实体列名里。
//转换address列的时候在所有地址钱添加“上海市”三个字
ECEntityCOM<UserInfo>.ForMember(e => e.address, e => "上海市:" + e);
c.实体名跟excel列头部名称不一致,可以自定义映射。
//excel列name对应实体username进行映射
ECEntityCOM<UserInfo>.ForMember("name", e => e.username);
d.自定义映射对excel单元格信息进行处理。
//列名age映射到实体userage属性,映射过程中给所有age加5
ECEntityCOM<UserInfo>.ForMember("age", e => e.userage, e => Convert.ToInt32(e) + );
帮助类:
#region 需要用到的实体
public class XlsEntity
{
/// <summary>
/// 实体名称
/// </summary>
public string EntityName { get; set; }
/// <summary>
/// 列名称
/// </summary>
public string ColumnName { get; set; }
/// <summary>
/// 列下标
/// </summary>
public int ColumnIndex { get; set; }
/// <summary>
/// 转换方法
/// </summary>
public Func<string, object> ConvertFunc { get; set; }
}
public class XlsRow
{
/// <summary>
/// 错误信息
/// </summary>
public List<string> ErrMessage { get; set; }
/// <summary>
/// 错误列名
/// </summary>
public List<string> ErrColumn { get; set; }
/// <summary>
/// 错误内容
/// </summary>
public List<string> ErrValue { get; set; }
/// <summary>
/// 是否转换出错(false:未出错,true:出错)
/// </summary>
public bool IsErr { get; set; }
}
#endregion
public class ECEntityCOM<T> where T : XlsRow, new()
{
private static List<XlsEntity> xlsHeader = new List<XlsEntity>();
#region 初始化转换形式
public static void ForMember(Expression<Func<T, object>> entityExpression, Func<string, object> func)
{
XlsEntity xlsEntity = new XlsEntity();
xlsEntity.EntityName = GetPropertyName(entityExpression);
xlsEntity.ColumnName = xlsEntity.EntityName;
xlsEntity.ConvertFunc = func;
xlsHeader.Add(xlsEntity);
}
public static void ForMember(string columnName, Expression<Func<T, object>> entityExpression)
{
XlsEntity xlsEntity = new XlsEntity();
xlsEntity.ColumnName = columnName;
xlsEntity.EntityName = GetPropertyName(entityExpression);
xlsHeader.Add(xlsEntity);
}
public static void ForMember(string columnName, string entityName)
{
XlsEntity xlsEntity = new XlsEntity();
xlsEntity.ColumnName = columnName;
xlsEntity.EntityName = entityName;
xlsHeader.Add(xlsEntity);
}
public static void ForMember(string columnName, string entityName, Func<string, object> func)
{
XlsEntity xlsEntity = new XlsEntity();
xlsEntity.ColumnName = columnName;
xlsEntity.EntityName = entityName;
xlsEntity.ConvertFunc = func;
xlsHeader.Add(xlsEntity);
}
public static void ForMember(string columnName, Expression<Func<T, object>> entityExpression, Func<string, object> func)
{
XlsEntity xlsEntity = new XlsEntity();
xlsEntity.ColumnName = columnName;
xlsEntity.EntityName = GetPropertyName(entityExpression);
xlsEntity.ConvertFunc = func;
xlsHeader.Add(xlsEntity);
}
#endregion
#region 从Excel中加载数据(泛型)
public static List<T> LoadFromExcel(string filePath)
{
FileInfo existingFile = new FileInfo(filePath);
List<T> resultList = new List<T>();
using (ExcelPackage package = new ExcelPackage(existingFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[];
int colStart = worksheet.Dimension.Start.Column;
int colEnd = worksheet.Dimension.End.Column;
int rowStart = worksheet.Dimension.Start.Row;
int rowEnd = worksheet.Dimension.End.Row;
PropertyInfo[] propertyInfoList = typeof(T).GetProperties();
XlsEntity xlsEntity;
#region 将实体和excel列标题进行对应绑定,添加到集合中
for (int i = colStart; i <= colEnd; i++)
{
string columnName = worksheet.Cells[rowStart, i].Value.ToString();
xlsEntity = xlsHeader.FirstOrDefault(e => e.ColumnName == columnName);
for (int j = ; j < propertyInfoList.Length; j++)
{
if (xlsEntity != null && xlsEntity.ColumnName == columnName)
{
xlsEntity.ColumnIndex = i;
xlsHeader.Add(xlsEntity);
}
else if (propertyInfoList[j].Name == columnName)
{
xlsEntity = new XlsEntity();
xlsEntity.ColumnName = columnName;
xlsEntity.EntityName = propertyInfoList[j].Name;
xlsEntity.ColumnIndex = i;
xlsHeader.Add(xlsEntity);
break;
}
}
}
#endregion
#region 根据对应的实体名列名的对应绑定就行值的绑定
for (int row = rowStart + ; row < rowEnd; row++)
{
T result = new T();
foreach (PropertyInfo p in propertyInfoList)
{
var xlsRow = xlsHeader.FirstOrDefault(e=> e.EntityName == p.Name);
if (xlsRow == null) continue;
ExcelRange cell = worksheet.Cells[row, xlsRow.ColumnIndex];
if (cell.Value == null) continue;
try
{
if (xlsRow.ConvertFunc != null)
{
object entityValue = xlsRow.ConvertFunc(cell.Value.ToString());
p.SetValue(result, entityValue);
}
else
{
cellBindValue(result, p, cell);
}
}
catch (Exception ex)
{
if (result.ErrColumn == null) result.ErrColumn = new List<string>();
if (result.ErrMessage == null) result.ErrMessage = new List<string>();
if (result.ErrValue == null) result.ErrValue = new List<string>();
result.ErrColumn.Add(p.Name);
result.ErrMessage.Add(ex.Message);
result.ErrValue.Add(cell.Value.ToString());
result.IsErr = true;
}
}
resultList.Add(result);
}
#endregion
}
return resultList;
}
#endregion
#region 给实体绑定值
private static void cellBindValue(T result, PropertyInfo p, ExcelRange cell)
{
switch (p.PropertyType.Name.ToLower())
{
case "string":
p.SetValue(result, cell.GetValue<String>());
break;
case "int16":
p.SetValue(result, cell.GetValue<Int16>());
break;
case "int32":
p.SetValue(result, cell.GetValue<Int32>());
break;
case "int64":
p.SetValue(result, cell.GetValue<Int64>());
break;
case "decimal":
p.SetValue(result, cell.GetValue<Decimal>());
break;
case "double":
p.SetValue(result, cell.GetValue<Double>());
break;
case "datetime":
p.SetValue(result, cell.GetValue<DateTime>());
break;
case "boolean":
p.SetValue(result, cell.GetValue<Boolean>());
break;
case "byte":
p.SetValue(result, cell.GetValue<Byte>());
break;
case "char":
p.SetValue(result, cell.GetValue<Char>());
break;
case "single":
p.SetValue(result, cell.GetValue<Single>());
break;
default:
p.SetValue(result, cell.Value);
break;
}
}
#endregion
#region 获取Lambda的属性名称
private static string GetPropertyName(Expression<Func<T, object>> expression)
{
Expression expressionToCheck = expression;
bool done = false;
while (!done)
{
switch (expressionToCheck.NodeType)
{
case ExpressionType.Convert:
expressionToCheck = ((UnaryExpression)expressionToCheck).Operand;
break;
case ExpressionType.Lambda:
expressionToCheck = ((LambdaExpression)expressionToCheck).Body;
break;
case ExpressionType.MemberAccess:
var memberExpression = ((MemberExpression)expressionToCheck);
string propertyName = memberExpression.Member.Name;
return propertyName;
default:
done = true;
break;
}
}
return "";
}
#endregion
}
补充一个例子
http://files.cnblogs.com/ariklee/ExcelConvertEntity.rar
Epplus下的一个将Excel转换成List的范型帮助类的更多相关文章
- Linux下将UTF8编码批量转换成GB2312编码的方法
Linux下将UTF8编码批量转换成GB2312编码的方法 在sqlplus中导入UTF8编码的sql脚本就会出现乱码错误,这时就需要将UTF8编码转换成GB2312编码,下面为大家介绍下在Linux ...
- 字符串A转换到字符串B,只能一次一次转换,每次转换只能把字符串A中的一个字符全部转换成另一个字符,是否能够转换成功
public class DemoTest { public static void main(String[] args) { System.)); } /** * 有一个字符串A 有一个字符串B ...
- 使用 js 实现一个中文自动转换成拼音的工具库
使用 js 实现一个中文自动转换成拼音的工具库 中文 => zhong-wen 应用场景 SEO 友好, URL 自动转换 blogs 发布文章,自动化部署,自动生成 url 的 path (时 ...
- Mac地址转换成long长整型
Mac地址转换成long长整型 using System;using System.Collections.Generic;using System.IO;using System.Text;usin ...
- Mac地址转换成long长整型 2
数据之间的转换可以使用 System.Convert Mac地址转换成long长整型 /// <summary> /// 解析长整形的数据使其转换为macID /// </sum ...
- 利用NPOI将EXCEL转换成HTML的C#实现
领导说想做一个网页打印功能,而且模板可以自定义,我考虑了三个方案,一是打印插件,二是在线 html 编辑器,三是 excel 模板,领导建议用的是打印插件的形式,我研究了一下,一个是需要下载安装,二个 ...
- C# Excel转换成Json工具(含源码)
可执行版本下载:https://github.com/neil3d/excel2json/releases 完整项目源代码下载:https://github.com/neil3d/excel2json ...
- Java中Office(word/ppt/excel)转换成HTML实现
运行条件:JDK + jacob.jar + jacob.dll 1) 把jacob.dll在 JAVA_HOME\bin\ 和 JAVA_HOME\jre\bin\ 以及C:\WINDOWS\sys ...
- 多页Excel转换成PDF时如何保存为单独文件
通过ABBYY PDF Transformer+图文识别软件,使用PDF-XChange打印机将多页Excel工作簿转换成PDF文档(相关文章请参考ABBYY PDF Transformer+从MS ...
随机推荐
- 【[AHOI2012]树屋阶梯】
卡特兰数! 至于为什么是卡特兰数,就稍微说那么一两句吧 对于一个高度为\(i\)的阶梯,我们可以在左上角填一个高度为\(k\)的阶梯,右下角填一个高度为\(i-1-k\)的阶梯剩下的我们用一个大的长方 ...
- PHP设计模式——桥接模式
<?php /* * 桥接模式 * 使用发送器,将一个类对象传入另一个类作为属性,耦合M+N个类 * */ abstract class Info { protected $_send = NU ...
- caffe卷积层实现
下图是jiayangqing在知乎上的回答,其实过程就是把image转换成矩阵,然后进行矩阵运算 卷积的实现在conv_layer层,conv_layer层继承了base_conv_layer层,ba ...
- SpringMVC学习记录五——功能开发及参数处理
15 包装类型pojo参数绑定 15.1 需求 商品查询controller方法中实现商品查询条件传入. 15.2 实现方法 第一种方法:在形参中 添加HttpServ ...
- idea原生ajax数据处理(增删改查)
项目名称:Bookstore UI界面 项目文件 操作: jsp代码 <%@ page import="dao.BookDAO" %> <%@ page impo ...
- asp.net 在repeater控件中加按钮
在repeater中加入方法有两种方法: 第一种:是对repeater控件的行添加OnItemCommand事件,添加方法也是有两种 1.在设计页面中,选中repeater控件右击==>属性== ...
- AngularJS 控制器函数
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Python基础—14-邮件与短信
邮件与短信 邮件发送 简介: 邮件服务器.账户.密码 相关协议:SMTP.POP3.IMAP 默认TCP协议端口:25 用途:经常用在一个网站的注册激活.通知.找回密码等场景 库:smtplib 示例 ...
- eclipse 突然debug模式不能正常运行了
eclipse 突然debug模式不能正常运行了,但非debug模式却能正常运行.debug模式不能正常启动的现象描述如下: 点击eclipse debug按钮,console窗口显示tomca ...
- c/c++面试总结---c语言基础算法总结2
c/c++面试总结---c语言基础算法总结2 算法是程序设计的灵魂,好的程序一定是根据合适的算法编程完成的.所有面试过程中重点在考察应聘者基础算法的掌握程度. 上一篇讲解了5中基础的算法,需要在面试之 ...