public class ExportAttribute : Attribute
{
public ExportAttribute(bool needExport = true)
{
_NeedExport = needExport;
}
private bool _NeedExport { set; get; }
///
/// 是否需要导出的字段
///
public bool NeedExport
{
get { return _NeedExport; }
set { _NeedExport = value; }
}
}
///
/// 导出excel帮助类
///
///
public class ExcelHelper
{
///
/// 属性描述与类集合缓存
///
private static Dictionary<Type, List> _propertyNameDic;
///
/// 属性与类集合缓存
///
private static Dictionary<Type, PropertyInfo[]> _propertyDic;
///
/// 属性与描述对应关系集合缓存
///
public static Dictionary<Type, List> _displayMappProperty;
private string fileName = null; //文件名
private HSSFWorkbook workbook = null;
private XSSFWorkbook xworkbook = null;
private FileStream fs = null;
private bool disposed;
public ExcelHelper()
{
}
///
/// 有参构造函数 导入EXCEL 时使用
///
///
public ExcelHelper(string fileName)
{
this.fileName = fileName;
disposed = false;
}
///
/// 将excel中的数据导入到实体集合中
/// 使用说明:1.传入的实体属性中displayName描述对应excel中的列名
///
///文件
///sheet名称
///起始第一行(excel列名开始行)
///返回的指定的实体集合
public List ExcelToModel(HttpPostedFileBase file, string sheetName = null, int firstRow = 0) where T : new()
{
var models = new List();
DataTable data = new DataTable();
try
{
using (Stream fs = file.InputStream)
{
fileName = file.FileName;
var fileNameArray = fileName.Split('.');
if (fileNameArray.Length == 2)
{
ISheet sheet = null;
if (fileNameArray[1].ToLower().Trim() == "xls")
{
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = xworkbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = xworkbook.GetSheetAt(0);
}
}
else
{
sheet = xworkbook.GetSheetAt(0);
}
}
else
{
xworkbook = new XSSFWorkbook(fs);
if (sheetName != null)
{
sheet = xworkbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = xworkbook.GetSheetAt(0);
}
}
else
{
sheet = xworkbook.GetSheetAt(0);
}
}
models = GetModel(sheet, models, firstRow);
}
else
{
return null;
}
}
return models;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
///
/// 保存文件到本地,并且数据转化为实体
///
///文件
///文件保存路径
///sheet名称
///起始第一行(excel列名开始行)
///
public List ExcelToModelAndSave(HttpPostedFileBase file, string savePath, string sheetName = null, int firstRow = 0) where T : new()
{
var models = new List();
DataTable data = new DataTable();
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
try
{
using (Stream fs = file.InputStream)
{
fileName = file.FileName;
var fileNameArray = fileName.Split('.');
if (fileNameArray.Length == 2)
{
ISheet sheet = null;
if (fileNameArray[1].ToLower().Trim() == "xls")
{
savePath = $"{savePath}\\{DateTime.Now.ToString("dd-HH-mm-ss")}.xls";
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = xworkbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = xworkbook.GetSheetAt(0);
}
}
else
{
sheet = xworkbook.GetSheetAt(0);
}
}
else
{
savePath = $"{savePath}\\{DateTime.Now.ToString("dd-HH-mm-ss")}.xlsx";
xworkbook = new XSSFWorkbook(fs);
if (sheetName != null)
{
sheet = xworkbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = xworkbook.GetSheetAt(0);
}
}
else
{
sheet = xworkbook.GetSheetAt(0);
}
}
models = GetModel(sheet, models, firstRow);
}
else
{
return null;
}
}
file.SaveAs(savePath);
return models;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
///
/// 导出Excel
/// 使用说明:1.实体中属性的displayName为导出excel中对应的列名,如果没有则按照属性名称
/// 2.实体的属性最好都是字符串或者数字类型的,在展示过程中,不会进行数据转化
///
///需要导出的实体模型(实体的属性最好都是字符串或者数字类型的,在展示过程中,不会进行数据转化)
///请求上下文
///导出的文件名(默认时间)
///文件头备注
///文件底部备注(eg:统计数据的添加)
public void Export(List models, HttpResponseBase Response, string fileName, string remark, string addUp)
{
//首先获取excel中的列名
Type type = typeof(T);
List propertyNames = GetDisplayNames(type);
//Create a new workbook
var workbook = new XSSFWorkbook();
//create a new sheet
var sheet = workbook.CreateSheet("User Accounts");
// Add header labels
var rowIndex = 0;
var rowLength = 0;
//存储文件头备注
if (!string.IsNullOrEmpty(remark))
{
var rowRemark = sheet.CreateRow(rowIndex);
rowRemark.CreateCell(rowIndex).SetCellValue(remark);
//合并单元格
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, propertyNames.Count - 1));
rowIndex++;
}
var row = sheet.CreateRow(rowIndex);
//存储列名
foreach (var propertyName in propertyNames)
{
row.CreateCell(rowLength).SetCellValue(propertyName);
rowLength++;
}
//存储值
var propertieValues = _propertyDic[type];
foreach (var model in models)
{
rowIndex++;
row = sheet.CreateRow(rowIndex);
for (var m = 0; m < rowLength; m++)
{
var value = propertieValues[m].GetValue(model, null);
row.CreateCell(m).SetCellValue(value?.ToString());
}
}
//存储文件尾备注(EG:统计数据)
if (!string.IsNullOrEmpty(addUp))
{
row = sheet.CreateRow(rowIndex + 1);
row.CreateCell(0).SetCellValue(addUp);
//合并单元格
sheet.AddMergedRegion(new CellRangeAddress(rowIndex + 1, rowIndex + 2, 0, propertyNames.Count - 1));
}
fileName = $"{fileName}{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}";
ExportExcel(workbook, Response, fileName);
}
///
/// 导出文件到浏览器
///
///
///
///文件名称
private void ExportExcel(XSSFWorkbook workbook, HttpResponseBase Response, string fileName)
{
using (var exportData = new MemoryStream())
{
workbook.Write(exportData);
Response.Buffer = true;
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
//response.ContentType = "application/ms-excel";
Response.ContentType = "application/vnd.openxmlformats - officedocument.spreadsheetml.sheet";
Response.AppendHeader("Content-Type", "text/html; charset=GB2312");
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xlsx", fileName));
Response.Charset = "GB2312";
Response.ContentEncoding = Encoding.GetEncoding("GB2312");
Response.BinaryWrite(exportData.GetBuffer());
Response.Flush();
}
}
///
/// 根据类型获取实体的描述集合
///
///类型
private List GetDisplayNames(Type type)
{
List propertyNames = new List();
if (_propertyNameDic != null && _propertyNameDic.ContainsKey(type))
{
propertyNames = _propertyNameDic[type];
}
else
{
var properties = type.GetProperties();
var propertyResult = new List();
propertyNames = GetDisplayNames(properties, out propertyResult);
//添加到缓存
if (_propertyNameDic == null)
{
_propertyNameDic = new Dictionary<Type, List>();
}
if (_propertyDic == null)
{
_propertyDic = new Dictionary<Type, PropertyInfo[]>();
}
_propertyNameDic.Add(type, propertyNames);
_propertyDic.Add(type, propertyResult.ToArray());
}
return propertyNames;
}
///
/// 获取属性描述对应关系
///
///类型
public List GetMapping(Type type)
{
List mapping = new List();
if (_displayMappProperty != null && _displayMappProperty.ContainsKey(type))
{
mapping = _displayMappProperty[type];
}
else
{
var properties = type.GetProperties();
mapping = GetMapping(properties);
//添加到缓存
if (_displayMappProperty == null)
{
_displayMappProperty = new Dictionary<Type, List>();
}
if (_propertyDic == null)
{
_propertyDic = new Dictionary<Type, PropertyInfo[]>();
}
_displayMappProperty.Add(type, mapping);
_propertyDic.Add(type, properties);
}
return mapping;
}
///
/// 获取实体的描述集合
///
///实体属性组
private List GetDisplayNames(PropertyInfo[] propertyInfos, out List propertyInfoList)
{
List propertyNames = new List();
propertyInfoList = new List();
if (propertyInfos != null)
{
for (var i = 0; i < propertyInfos.Length; i++)
{
//判断是否是不需要导出的字段
var expoertAttribute = propertyInfos[i].GetCustomAttribute();
if (expoertAttribute == null || expoertAttribute.NeedExport)
{
var propertyName = propertyInfos[i].GetCustomAttribute();
if (propertyName != null && !string.IsNullOrEmpty(propertyName.DisplayName))
{
propertyNames.Add(propertyName.DisplayName);
}
else
{
propertyNames.Add(propertyInfos[i].Name);
}
propertyInfoList.Add(propertyInfos[i]);
}
}
}
return propertyNames;
}
///
/// 获取实体中的属性和描述对应关系数据
///
///属性集合
private List GetMapping(PropertyInfo[] propertyInfos)
{
List mapping = new List();
if (propertyInfos != null)
{
for (var i = 0; i < propertyInfos.Length; i++)
{
var propertyName = propertyInfos[i].GetCustomAttribute();
if (propertyName != null && !string.IsNullOrEmpty(propertyName.DisplayName))
{
mapping.Add(new DisplayMappProperty { Property = propertyInfos[i], DisplayName = propertyName.DisplayName });
}
}
}
return mapping;
}
///
/// 获取excel中映射的实体数据
///
///
///
///
///
///
private List GetModel(ISheet sheet, List models, int firstRowNum = 0) where T : new()
{
//首先获取excel中的列名
Type type = typeof(T);
List mappings = GetMapping(type);
int startRow = 0;
if (sheet != null)
{
IRow firstRow = sheet.GetRow(firstRowNum);
//一行最后一个cell的编号 即总的列数
int cellCount = firstRow.LastCellNum;
var cellValues = new string[cellCount];
//获取excel中的列名
for (int i = firstRow.FirstCellNum; i < cellCount; i++)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
cellValues[i] = cellValue;
}
}
}
//数据开始行
startRow = firstRowNum + 1;
//最后一行的标号
int rowCount = sheet.LastRowNum;
//读取数据
for (int i = startRow; i <= rowCount; i++)
{
var singT = new T();
IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null
for (int j = row.FirstCellNum; j < cellCount; j++)
{
//获取Excel中列名
var cellValue = "";
if (j < cellValues.Length)
{
cellValue = cellValues[j];
}
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
//给实体赋值
{
//根据列名找到对应关系的属性值
var property = mappings.FirstOrDefault(n => n.DisplayName == cellValue)?.Property;
if (property != null)
{
property.SetValue(singT, row.GetCell(j)?.ToString());
}
}
}
models.Add(singT);
}
}
return models;
}
}
///
/// 将excel转化为DataTable
///
public class ExcelHelper : IDisposable
{
private string fileName = null; //文件名
private IWorkbook workbook = null;
private FileStream fs = null;
private bool disposed;
public ExcelHelper(string fileName)
{
this.fileName = fileName;
disposed = false;
}
///
/// 将excel中的数据导入到实体中
///
///excel工作薄sheet的名称
///第一行是否是DataTable的列名
/// 返回的DataTable
public DataTable ExcelToDataTable(string sheetName = null, bool isFirstRowColumn = true)
{
ISheet sheet = null;
DataTable data = new DataTable();
int startRow = 0;
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = workbook.GetSheetAt(0);
}
}
else
{
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
if (isFirstRowColumn)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
}
startRow = sheet.FirstRowNum + 1;
}
else
{
startRow = sheet.FirstRowNum;
}
//最后一列的标号
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null
DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
dataRow[j] = row.GetCell(j).ToString();
}
data.Rows.Add(dataRow);
}
}
return data;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (fs != null)
fs.Close();
}
fs = null;
disposed = true;
}
}
}
///
/// 属性描述对应关系
///
public class DisplayMappProperty
{
///
/// 属性
///
public PropertyInfo Property { set; get; }
///
/// 属性描述 描述对应excel中的列名
///
public string DisplayName { set; get; }
}
调用方法实例,首先是导入,其中ImportModel是excel对应的实体类型:
public ActionResult Import(HttpPostedFileBase importFile)
{
ExcelHelper important = new ExcelHelper();
var agentInfos = important.ExcelToModel(importFile, null, 1);
}
导出实例,其中exportModels是需要导出的数据集合:
new ExcelHelper.Export(exportModels, Response, "活动分润", null,null);