在做通用导入导出的时候,最关键的应该就是实体导出导入的顺序了,但是编译器在编译的时候又无法自定义属性编译的顺序,所以需要一个自定义的特性标签来指定实体类导出的顺序,然后通过自定义的比较器将属性排序

因为wcf中无法对实体类的自定义特性进行描述,所以获取不到我们自定义的OrderAttribute,虽然DataMemberAttribute中的Order属性是描述属性序列化的顺序,但是因为没有对序列化排序没有特殊的要求,于是就用它代替了,起初发射之后总是倒数两个Order属性的值是正常的,其他的都为-1,后来发现生成的顺序也是按Order生成的,于是就没有深究了(如果有深入研究的朋友 希望指点一下)。

class Program
{
static void Main(string[] args)
{
//过滤掉没有打排序标签的属性
List<PropertyInfo> pis = typeof(People).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
//自定义比较器排序
pis.Sort(new OrderComparator());
Console.ReadKey();
}
}
//自定义排序特性
public class OrderAttribute : Attribute
{
public OrderAttribute(int order)
{
this.PropertyOrder = order;
}
public int PropertyOrder { get; set; }
}
//实体类
public class People
{
public int ID { get; set; }
[Order(1)]
public string Name { get; set; }
[Order(3)]
public int Age { get; set; }
[Order(2)]
public bool Gender { get; set; }
[Order(5)]
public double Height { get; set; }
[Order(4)]
public double Weight { get; set; }
}
//自定义属性比较器
public class OrderComparator : IComparer<PropertyInfo>
{
public int Compare(PropertyInfo x, PropertyInfo y)
{
OrderAttribute xOrderAttribute = x.GetCustomAttributes(typeof(OrderAttribute), false).FirstOrDefault() as OrderAttribute;
OrderAttribute yOrderAttribute = y.GetCustomAttributes(typeof(OrderAttribute), false).FirstOrDefault() as OrderAttribute;
return xOrderAttribute.PropertyOrder - yOrderAttribute.PropertyOrder;
}
}

目前使用过操作excel的方式有NPOI和,微软提供的Microsoft.Office.Interop.Excel性能太牛X了,所以就不敢贴出来了

一、使用NPOI

NPOI导出:

/// <summary>
/// 保存到硬盘
/// </summary>
/// <param name="path">保存路径@"c:\book1.xls"</param>
/// <param name="data">数据源</param>
/// <param name="columnsName">excel列名</param>
public void SaveToFile<T>(List<T> data, string path, List<string> excelColumnsTitle)
{
if (Path.GetExtension(path).Equals(".xls"))
{
//excel2003
SaveToFile2003<T>(data, path, excelColumnsTitle);
}
else if (Path.GetExtension(path).Equals(".xlsx"))
{
//excel2007
SaveToFile2007<T>(data, path, excelColumnsTitle);
}
else
{
throw new Exception("请传入正确的excel路径");
} }

  SaveToFile2003

 /// <summary>
/// excel2003导出
/// </summary>
private void SaveToFile2003<T>(List<T> data, string path, List<string> excelColumnsTitle)
{
NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet"); //添加一个sheet //给sheet1添加第一行的头部标题
NPOI.SS.UserModel.IRow row1 = sheet.CreateRow(0);
for (int i = 0; i < excelColumnsTitle.Count; i++)
{
row1.CreateCell(i).SetCellValue(excelColumnsTitle[i]);
} //过滤属性
List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
pis.Sort(new OrderComparator());
//金额格式
NPOI.SS.UserModel.ICellStyle cellStyleDecimal = book.CreateCellStyle();
NPOI.SS.UserModel.IDataFormat formatDecimal = book.CreateDataFormat();
cellStyleDecimal.DataFormat = NPOI.HSSF.UserModel.HSSFDataFormat.GetBuiltinFormat("0.00"); //单元格格式为“0.00”来表示,"¥#,##0"美元显示,"0.00%"百分比显示
//日期格式
NPOI.SS.UserModel.ICellStyle cellStyleDateTime = book.CreateCellStyle();
NPOI.SS.UserModel.IDataFormat formatDateTime = book.CreateDataFormat();
cellStyleDateTime.DataFormat = formatDateTime.GetFormat("yyyy-m");
//将数据逐步写入sheet1各个行
for (int i = 0; i < data.Count; i++)
{
NPOI.SS.UserModel.IRow rowtemp = sheet.CreateRow(i + 1);
for (int j = 0; j < pis.Count; j++)
{
NPOI.SS.UserModel.ICell cell = rowtemp.CreateCell(j);
if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
{
cell.SetCellValue(pis[j].GetValue(data[i], null).ToString());
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
{
cell.SetCellValue(Convert.ToInt32(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
{
cell.CellStyle = cellStyleDecimal;
cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
{
cell.CellStyle = cellStyleDateTime;
cell.SetCellValue(Convert.ToDateTime(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
{
cell.CellStyle = cellStyleDecimal;
cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
{
cell.SetCellValue(Convert.ToBoolean(pis[j].GetValue(data[i], null)));
}
}
}
// 写入到客户端
using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
book.Write(fs);
}
}

  SaveToFile2007

 /// <summary>
/// excel2007导出
/// </summary>
private void SaveToFile2007<T>(List<T> data, string path, List<string> excelColumnsTitle)
{
NPOI.XSSF.UserModel.XSSFWorkbook book = new NPOI.XSSF.UserModel.XSSFWorkbook();
NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet"); //添加一个sheet //给sheet1添加第一行的头部标题
NPOI.SS.UserModel.IRow row1 = sheet.CreateRow(0);
for (int i = 0; i < excelColumnsTitle.Count; i++)
{
row1.CreateCell(i).SetCellValue(excelColumnsTitle[i]);
} //过滤属性
List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
pis.Sort(new OrderComparator()); //金额格式
NPOI.SS.UserModel.ICellStyle cellStyleDecimal = book.CreateCellStyle();
NPOI.SS.UserModel.IDataFormat formatDecimal = book.CreateDataFormat();
cellStyleDecimal.DataFormat = NPOI.HSSF.UserModel.HSSFDataFormat.GetBuiltinFormat("0.00"); //单元格格式为“0.00”来表示,"¥#,##0"美元显示,"0.00%"百分比显示
//日期格式
NPOI.SS.UserModel.ICellStyle cellStyleDateTime = book.CreateCellStyle();
NPOI.SS.UserModel.IDataFormat formatDateTime = book.CreateDataFormat();
cellStyleDateTime.DataFormat = formatDateTime.GetFormat("yyyy-m");
//将数据逐步写入sheet1各个行
for (int i = 0; i < data.Count; i++)
{
NPOI.SS.UserModel.IRow rowtemp = sheet.CreateRow(i + 1);
for (int j = 0; j < pis.Count; j++)
{
NPOI.SS.UserModel.ICell cell = rowtemp.CreateCell(j);
if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
{
cell.SetCellValue(pis[j].GetValue(data[i], null).ToString());
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
{
cell.SetCellValue(Convert.ToInt32(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
{
cell.CellStyle = cellStyleDecimal;
cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
{
cell.CellStyle = cellStyleDateTime;
cell.SetCellValue(Convert.ToDateTime(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
{
cell.CellStyle = cellStyleDecimal;
cell.SetCellValue(Convert.ToDouble(pis[j].GetValue(data[i], null)));
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
{
cell.SetCellValue(Convert.ToBoolean(pis[j].GetValue(data[i], null)));
}
}
}
// 写入到客户端
using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
book.Write(fs);
}
}

NPOI导入:

 /// <summary>
/// 返回List数据
/// </summary>
/// <typeparam name="T">实体类</typeparam>
/// <param name="path">excel文件路径</param>
/// <returns></returns>
public List<T> ImportExcelToList<T>(string path)
{
if (Path.GetExtension(path).Equals(".xls"))
{
//excel2003
return ImportExcelToList2003<T>(path);
}
else if (Path.GetExtension(path).Equals(".xlsx"))
{
//excel2007
return ImportExcelToList2007<T>(path);
}
else
{
throw new Exception("请传入正确的excel路径");
}
}

  ImportExcelToList2003

/// <summary>
/// excel2003导入
/// </summary>
private List<T> ImportExcelToList2003<T>(string path)
{
List<T> list = new List<T>();
NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook(new FileStream(path, FileMode.Open, FileAccess.Read));
NPOI.HSSF.UserModel.HSSFSheet sheet = book.GetSheet("Sheet") as NPOI.HSSF.UserModel.HSSFSheet;
if (sheet != null)
{
List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
pis.Sort(new OrderComparator());
//导入数据
for (int i = 1; i <= sheet.LastRowNum; i++) //获得所有行数
{
T model = Activator.CreateInstance<T>();
NPOI.SS.UserModel.IRow row = sheet.GetRow(i); //读取当前行数据
if (row != null)
{
try
{
for (int j = 0; j < row.Cells.Count; j++)
{
if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
{
pis[j].SetValue(model, row.GetCell(j).StringCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
{
pis[j].SetValue(model, (int)row.GetCell(j).NumericCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
{
pis[j].SetValue(model, (decimal)row.GetCell(j).NumericCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
{
pis[j].SetValue(model, row.GetCell(j).DateCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
{
pis[j].SetValue(model, row.GetCell(j).NumericCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
{
pis[j].SetValue(model, row.GetCell(j).BooleanCellValue, null);
}
}
list.Add(model);
}
catch { }
}
}
} return list;
}

  ImportExcelToList2007

 /// <summary>
/// excel2007导入
/// </summary>
private List<T> ImportExcelToList2007<T>(string path)
{
List<T> list = new List<T>();
NPOI.XSSF.UserModel.XSSFWorkbook book = new NPOI.XSSF.UserModel.XSSFWorkbook(new FileStream(path, FileMode.Open, FileAccess.Read));
NPOI.SS.UserModel.ISheet sheet = book.GetSheetAt(0);
if (sheet != null)
{
List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
pis.Sort(new OrderComparator());
//导入数据
for (int i = 1; i <= sheet.LastRowNum; i++) //获得所有行数
{
T model = Activator.CreateInstance<T>();
NPOI.SS.UserModel.IRow row = sheet.GetRow(i); //读取当前行数据
if (row != null)
{
try
{
for (int j = 0; j < row.Cells.Count; j++)
{
if (pis[j].PropertyType.IsAssignableFrom(typeof(string)))
{
pis[j].SetValue(model, row.GetCell(j).StringCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(int)))
{
pis[j].SetValue(model, (int)row.GetCell(j).NumericCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(decimal)))
{
pis[j].SetValue(model, (decimal)row.GetCell(j).NumericCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(DateTime)))
{
pis[j].SetValue(model, row.GetCell(j).DateCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(double)))
{
pis[j].SetValue(model, row.GetCell(j).NumericCellValue, null);
}
else if (pis[j].PropertyType.IsAssignableFrom(typeof(bool)))
{
pis[j].SetValue(model, row.GetCell(j).BooleanCellValue, null);
}
}
list.Add(model);
}
catch { }
}
}
} return list;
}

  

二、使用Acey.ExcelX,以前的时候性能是忧于NPOI的,而且支持excel03和07,相较NPOI有时候还能省去cell类型的判断,只是是第三方收费的,所以导出后会有广告

Acey.ExcelX导出

 /// <summary>
/// 保存到硬盘
/// </summary>
/// <param name="path">保存路径@"c:\book1.xls"</param>
/// <param name="data">数据源</param>
/// <param name="columnsName">excel列名</param>
public void SaveToFile<T>(List<T> data, string path, List<string> excelColumnsTitle)
{
IWorkbook workbook = ExcelxApplication.CreateWorkbook();
IWorksheet worksheet = workbook.Worksheets[0];
for (int i = 0; i < excelColumnsTitle.Count; i++)
{
worksheet.Cells[0, i].Value = excelColumnsTitle[i];
}
List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
pis.Sort(new OrderComparator());
for (int i = 0; i < data.Count; i++)
{
for (int j = 0; j < pis.Count; j++)
{
worksheet.Cells[i + 1, j].Value = pis[j].GetValue(data[i], null);
}
}
workbook.SaveAs(path);//保存到硬盘
}

Acey.ExcelX导入

/// <summary>
/// 返回List数据
/// </summary>
/// <typeparam name="T">实体类</typeparam>
/// <param name="path">excel文件路径</param>
/// <returns></returns>
public List<T> ImportExcelToList<T>(string path)
{
List<T> list = new List<T>();
Type type = typeof(T);
//创建Workbook对象通过打开指定的Excel文档。
IWorkbook workbook = ExcelxApplication.Open(path);
//获取以0为基数的Worksheet对象。
IWorksheet worksheet = workbook.Worksheets[0];
//获取工作表中最大数据行。
int maxRow = worksheet.MaxDataRow;
//获取工作表中最大数据列。
int maxCol = worksheet.MaxDataColumn;
//创建指定区域的对象。
IRange range = worksheet.Cells.CreateRange(0, 0, maxRow, maxCol);
//将该区域对象的数据导出到DataTable对象中。
DataTable table = range.ExportDataTable();
//返回该DataTable对象。
for (int row = 1; row <= maxRow; row++)
{
T model = Activator.CreateInstance<T>();
List<PropertyInfo> pis = typeof(T).GetProperties().Where(p => p.GetCustomAttributes(typeof(OrderAttribute), false).Any()).ToList();
pis.Sort(new OrderComparator());
for (int col = 0; col <= maxCol; col++)
{
ICell cell = worksheet.Cells[row, col];
if (pis[col].PropertyType.IsAssignableFrom(typeof(string)))
{
pis[col].SetValue(model, Convert.ToString(cell.Value), null);
}
else if (pis[col].PropertyType.IsAssignableFrom(typeof(int)))
{
pis[col].SetValue(model, Convert.ToInt32(cell.Value), null);
}
else if (pis[col].PropertyType.IsAssignableFrom(typeof(decimal)))
{
pis[col].SetValue(model, Convert.ToDecimal(cell.Value), null);
}
else if (pis[col].PropertyType.IsAssignableFrom(typeof(DateTime)))
{
pis[col].SetValue(model, Convert.ToDateTime(cell.Value), null);
}
else if (pis[col].PropertyType.IsAssignableFrom(typeof(double)))
{
pis[col].SetValue(model, Convert.ToDouble(cell.Value), null);
}
else if (pis[col].PropertyType.IsAssignableFrom(typeof(bool)))
{
pis[col].SetValue(model, Convert.ToBoolean(cell.Value), null);
}
}
list.Add(model);
}
return list;
}

Acey.ExcelX输出到web

 /// <summary>
///输出到网页
///</summary>
///<param name="context">HttpContext</param>
///<param name="fileName">"book1.xls"</param>
///<param name="data">数据源</param>
public static void RenderToBrowser(DataTable data, HttpContext context, string fileName)
{
IWorkbook workbook = ProcessWorkBook(data);
workbook.SaveToHttpResponse(context.Response, fileName, false);//输出到网页
}

  

反射+属性标签 通用Excel导入导的更多相关文章

  1. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  2. 利用反射实现通用的excel导入导出

    如果一个项目中存在多种信息的导入导出,为了简化代码,就需要用反射实现通用的excel导入导出 实例代码如下: 1.创建一个 Book类,并编写set和get方法 package com.bean; p ...

  3. 解析大型.NET ERP系统 设计通用Microsoft Excel导入功能

    做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能.导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到 ...

  4. 反射+自定义注解---实现Excel数据列属性和JavaBean属性的自动映射

    简单粗暴,直奔主题.   需求:通过自定义注解和反射技术,将Excel文件中的数据自动映射到pojo类中,最终返回一个List<pojo>集合? 今天我只是通过一位使用者的身份来给各位分享 ...

  5. Delphi Excel导入 的通用程序转载

    Delphi Excel导入 的通用程序 (-- ::)转载▼ 标签: it 分类: Delphi相关 步骤: 连excel(自己知道其格式,最好是没个字段在数据一一对应) 读excel数据,填入到数 ...

  6. 通用的高度可扩展的Excel导入实现(附Demo)

    Demo源码 背景 通过程序将excel导入到数据库中是一项非常常见的功能.通常的做法是:先将excel转成DataTable,然后将DataTable转换成List<T>,最终通过Lis ...

  7. NPOI实现Excel导入导出

    NPOI实现Excel的导入导出,踩坑若干. Cyan是博主[Soar360]自2014年以来开始编写整理的工具组件,用于解决现实工作中常用且与业务逻辑无关的问题. 什么是NPOI? NPOI 是 P ...

  8. POI操作Excel导入和导出

    Apache的POI组件是Java操作Microsoft Office办公套件的强大API,当中对Word,Excel和PowperPoint都有支持,当然使用较多的还是Excel.由于Word和Po ...

  9. C# Excel导入、导出【源码下载】

    本篇主要介绍C#的Excel导入.导出. 目录 1. 介绍:描述第三方类库NPOI以及Excel结构 2. Excel导入:介绍C#如何调用NPOI进行Excel导入,包含:流程图.NOPI以及C#代 ...

随机推荐

  1. sql server parameter validation of stored procedure

    https://stackoverflow.com/questions/41908156/validating-missing-parameter-from-procedure-calls I don ...

  2. 報錯:One or more validation errors were detected during model generation:System.Data.Edm.EdmEntityType: : EntityType 'Movie' has no key

    報錯:One or more validation errors were detected during model generation:System.Data.Edm.EdmEntityType ...

  3. this和super用法

    1. this能分清混淆,形参名与当前对象的某个成员有相同的名字,需要明确使用this关键字来指明你要使用某个成员,使用方法是“this.成员名”. 一般以this.形参数名=形参名,代表送进来赋值的 ...

  4. django学习笔记整理(1)django的MTV模式

    django作为一个python的网络编程的框架,自然有着其规律可循.通过对django的了解,也明白了一些网络编程的知识.最近这近一个月,在网上查了许多文字资料,也看了别人的视频之类的资料,也算是对 ...

  5. (python)循环中动态产生变量

    >>> for i in xrange(5): exec 'a'+str(i)+' = '+str(i)+'' >>> a0 0 >>> a1 1 ...

  6. C++的转换函数

    听侯捷老师的讲课笔记: 所谓转换函数指的是类型之间的转换,比如把自定义的类类型转换成内建类型(比如double),后者向相反的方向转. 直接上代码: 头文件conversion_function.h: ...

  7. hdu5692 dfs序线段树

    这是补的知识点,按先序遍历的顺序建立dfs序,用左右两个值代表整个区间,因为dfs序最重要的特点就是子树的区间是连续的 建立线段树时,需要用重新标过的 下标来建立 #pragma comment(li ...

  8. 如何学习Android系统源码(转)

    一. Android系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心.我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与Android系统相关 ...

  9. vue项目打包注意的地方

    打包有两种方式: 第一种方式:1.更改config文件夹下prod.env.js下的地址: 2.将config文件夹下index.js中build下改为 assetsPublicPath: '', 第 ...

  10. Django 基础 视图系统

    Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误, ...