.net core 项目

可以向excel写入任何类型(T)的数据,只要T中的field的[Display(Name = "1233", Description = "#,##0.00")]:name==excel column header's name   ,dicription==excel cell's formate

引用的nuget包:

1.EPPlus.Core

2. System.ComponentModel.Annotations

操作类:

    public class ExcelWriteReadAccordingDisplayService<T> : IExcelWriteService<T> where T : class
{
ILogBase _logger;
Dictionary<int, PropertyInfo> _columnIndexDicForProperInfo;
Dictionary<int, DisplayAttribute> _columnIndexDicForDisplayAttr;
public ExcelWriteReadAccordingDisplayService(ILogBase logBase)
{
_logger = logBase;
}
}

class ExcelWriteReadAccordingDisplayService 中的方法:

  main method:

        public bool WriteData(List<T> data, string excelPath, string sheetName)
{ try
{
if (!WriteRequestCheck(excelPath))
{
_logger.Warn($"WriteData Request not valid.excelPath :{excelPath},sheetName:{sheetName}");
return false;
}
if (string.IsNullOrWhiteSpace(sheetName))
{
sheetName = DateTime.Now.ToString("yyyyMM");
} //set sheet style
Func<ExcelWorksheet, Color, bool> SetHeadStyle = (targetSheet, backgroundColor) =>
{
using (ExcelRange rng = targetSheet.Cells[, , , targetSheet.Dimension.Columns])
{
rng.Style.Font.Bold = true;
rng.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
rng.Style.Fill.PatternType = ExcelFillStyle.Solid;
rng.Style.Fill.BackgroundColor.SetColor(backgroundColor);
}
targetSheet.Row().Height = targetSheet.Row().Height * 1.4f;
return true;
}; Func<ExcelWorksheet, bool> SetAllCellsStyle = (targetSheet) =>
{
using (ExcelRange rng = targetSheet.Cells)
{
rng.AutoFitColumns();
}
return true;
}; using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet sheet = AddSheet(package, sheetName); //write data to excel
GetColumnIndexDic(sheet);
WriteContent(data, sheet); //set style for excel
SetHeadStyle(sheet, Color.FromArgb(, , ));
SetAllCellsStyle(sheet); //save
package.SaveAs(new FileInfo(excelPath));
} return true;
}catch(Exception ex)
{
_logger.Error($"ExcelWrite data exception :{ex.ToString()},excel:{excelPath},data:{JsonConvert.SerializeObject(data)}");
throw ex;
}
}
        public byte[] WriteData(List<T> data, string sheetName)
{
try
{
if (string.IsNullOrWhiteSpace(sheetName))
{
sheetName = DateTime.Now.ToString("yyyyMM");
}
if (data == null || data.Count() == 0)
{
_logger.Warn($"WriteData Request not valid. request.data:{JsonConvert.SerializeObject(data)}");
return null;
}
return SaveData(data, sheetName);
}
catch (Exception ex)
{
_logger.Error($"ExcelWrite data exception :{ex.ToString()},sheetName:{sheetName},data:{JsonConvert.SerializeObject(data)}");
throw ex;
}
} private bool WriteRequestCheck(string excelPath)
{
Func<string, bool> pathValidCheck = (path) =>
{
if (string.IsNullOrWhiteSpace(path) || !Path.IsPathRooted(path)) return false;
return true;
}; if (!pathValidCheck(excelPath))
{
_logger.Warn($"excelPath not valid,path :{excelPath}");
return false;
}
return true;
} private ExcelWorksheet AddSheet(ExcelPackage package, string sheetName)
{
if (package.Workbook.Worksheets[sheetName] != null)
{
package.Workbook.Worksheets.Delete(sheetName);
}
var sheet = package.Workbook.Worksheets.Add(sheetName);
return sheet;
} private byte[] SaveData(List<T> data, string sheetName)
{
byte[] excelContent = new byte[] { }; using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet sheet = AddSheet(package, sheetName); //write data to excel
GetColumnIndexDic(sheet);
WriteContent(data, sheet); //set style for excel
SetHeadStyle(sheet, Color.FromArgb(255, 242, 204));
SetAllCellsStyle(sheet); //save
using (System.IO.MemoryStream outStream = new System.IO.MemoryStream())
{
package.SaveAs(outStream);
excelContent = outStream.ToArray();
}
}
return excelContent;
}

  

       // type T => init excel's header && get some setting info to write excel cell
private void GetColumnIndexDic(ExcelWorksheet sheet,bool writeHeader=true)
{
try
{
var typeOfObject = typeof(T);
var pds = typeOfObject.GetProperties();
if (pds == null)
{
_logger.Warn($"no PropertyInfos can get from class Type:{typeOfObject.FullName} ");
return;
} //Dictionary<excel column index,T's PropertyInfo>
_columnIndexDicForProperInfo = new Dictionary<int, PropertyInfo>();
//Dictionary<excel column index,T's PropertyInfo's DisplayAttribute(its name=excle header name,its discription =excel cell style formate)>
_columnIndexDicForDisplayAttr = new Dictionary<int, DisplayAttribute>();
int column = 1;
int row = 1;
foreach (var p in pds)
{
var attr = p.GetCustomAttribute(typeof(DisplayAttribute)) as DisplayAttribute;
if (attr != null)
{
_columnIndexDicForDisplayAttr.Add(column, attr);
}
else
{
_logger.Warn($"no DisplayAttribute can get from PropertyInfo:(class:{typeOfObject.FullName},property:{p.Name})");
} if (writeHeader)
{
sheet.Cells[row, column].Value = attr == null ? p.Name : attr.Name;
}
_columnIndexDicForProperInfo.Add(column, p);
column++;
} if (_columnIndexDicForProperInfo.Count == 0)
{
_logger.Warn($"no _columnIndexDicForProperInfo can get from type:{typeOfObject.FullName}");
}
if (_columnIndexDicForDisplayAttr.Count == 0)
{
_logger.Warn($"no _columnIndexDicForDisplayAttr can get from type:{typeOfObject.FullName}");
}
}
catch (Exception ex)
{
_logger.Error($"ExcelWrite-GetColumnIndexDic exception :{ex.ToString()}");
throw ex;
}
}

  

       //fill sheet content according list data
private void WriteContent(List<T> data,ExcelWorksheet sheet,int startRow=2)
{
try
{
PropertyInfo propertyTemp = null;
DisplayAttribute displayAttrTemp = null;
int column = 1;
int row = startRow;
Dictionary<string, Dictionary<string, DisplayAttribute>> enumDic = new Dictionary<string, Dictionary<string, DisplayAttribute>>();
foreach (var eachData in data)
{
column = 1;
foreach (var eachColumn in _columnIndexDicForProperInfo)
{
if (!_columnIndexDicForProperInfo.ContainsKey(column))
{
_logger.Warn($"no PropertyInfos can get from _columnIndexDic. current column:{column},_columnIndexDic:{JsonConvert.SerializeObject(_columnIndexDicForProperInfo)} ");
continue;
}
propertyTemp = _columnIndexDicForProperInfo[column];
var cellValue = propertyTemp.GetValue(eachData); if (cellValue != null)
{
FormatCellValue(ref enumDic, ref cellValue, propertyTemp.PropertyType);
}
sheet.Cells[row, column].Value = cellValue == null ? "" : cellValue;
if (_columnIndexDicForDisplayAttr.ContainsKey(column))
{
displayAttrTemp = _columnIndexDicForDisplayAttr[column];
var styleFormate = displayAttrTemp.Description;
if (!string.IsNullOrWhiteSpace(styleFormate))
{
sheet.Cells[row, column].Style.Numberformat.Format = styleFormate;
}
}
column++;
}
row++;
}
}
catch (Exception ex)
{
_logger.Error($"ExcelWrite-WriteContent exception :{ex.ToString()},data:{JsonConvert.SerializeObject(data)}");
throw ex;
}
} // formate cell value according type T‘s property’s DisplayAttribute
private void FormatCellValue(ref Dictionary<string, Dictionary<string, DisplayAttribute>> enumDic, ref object cellValue, Type propertyTypeOfCell)
{
if (cellValue == null) return;
if (propertyTypeOfCell.IsEnum)
{
Dictionary<string, DisplayAttribute> enumDicTemp;
if (enumDic.ContainsKey(propertyTypeOfCell.FullName))
{
enumDicTemp = enumDic[propertyTypeOfCell.FullName];
}
else
{
enumDicTemp = GetEnumNameDicForDisplayAttr(propertyTypeOfCell);
enumDic.Add(propertyTypeOfCell.FullName, enumDicTemp);
} if (enumDicTemp != null)
{
if (enumDicTemp.ContainsKey(cellValue.ToString()))
{
cellValue = enumDicTemp[cellValue.ToString()].Name;
return;
}
else
{
_logger.Warn($"no enum value can get from enum dictionary:{JsonConvert.SerializeObject(enumDicTemp.Keys)} , enum Type:{propertyTypeOfCell.FullName},cell value:{cellValue}");
}
}
else
{
_logger.Warn($"no enum dictionary can get from enum Type:{propertyTypeOfCell.FullName} ");
}
return;
}
/*if (propertyTypeOfCell == typeof(int))
{
cellValue = Convert.ToInt32(cellValue);
return;
}
if (propertyTypeOfCell == typeof(long))
{
cellValue = Convert.ToInt64(cellValue);
return;
}
if (propertyTypeOfCell == typeof(DateTime))
{
cellValue = Convert.ToDateTime(cellValue);
return;
}
if (propertyTypeOfCell == typeof(string))
{
cellValue = cellValue.ToString();
return;
}*/
return; } // get enum property Dic<enum value,DisplayAttribute> =>show in excel cell
private Dictionary<string, DisplayAttribute> GetEnumNameDicForDisplayAttr(Type enumClassType)
{
try
{
var result = new Dictionary<string, DisplayAttribute>();
if (enumClassType.IsEnum)
{
var enumValues = enumClassType.GetEnumValues();
foreach (var value in enumValues)
{
MemberInfo memberInfo =
enumClassType.GetMember(value.ToString()).First();
var descriptionAttribute =
memberInfo.GetCustomAttribute<DisplayAttribute>();
if (descriptionAttribute != null)
{
var enumString = Enum.GetName(enumClassType, value);
result.Add(value.ToString(), descriptionAttribute);
}
}
if (result == null || result.Count() == 0)
{
_logger.Warn($"no EnumDic can get from enum Type:{enumClassType.FullName} ");
}
}
return result;
}
catch (Exception ex)
{
_logger.Error($"ExcelWrite-GetEnumNameDicForDisplayAttr exception :{ex.ToString()},Type:{enumClassType.FullName}");
throw ex;
}
}

  

        private bool WriteRequestCheck(string excelPath)
{
Func<string, bool> pathValidCheck = (path) =>
{
if (string.IsNullOrWhiteSpace(path) || !Path.IsPathRooted(path)) return false;
return true;
}; if (!pathValidCheck(excelPath))
{
_logger.Warn($"excelPath not valid,path :{excelPath}");
return false;
}
return true;
} private ExcelWorksheet AddSheet(ExcelPackage package, string sheetName)
{
if (package.Workbook.Worksheets[sheetName] != null)
{
package.Workbook.Worksheets.Delete(sheetName);
}
var sheet = package.Workbook.Worksheets.Add(sheetName);
return sheet;
}

  

enum 定义:

public enum AdvertiseType:Int32
{
/// <summary>
/// Search
/// </summary>
[Display(Name = "Search")]//important
Search = 1, /// <summary>
/// Display
/// </summary>
[Display(Name = "Display")]
Display = 2,
}

type T 的定义

    public class FinancialBillEntity
{ [Display(Name = "类型")]
public AdvertiseType AdvertiseType{ get; set; } [Display(Name = "总金额", Description = "#,##0.00")]//name==excel header name;discription=cell style formate
public decimal TotalAdivitisingCost{ get; set; } [Display(Name = "赠送", Description = "#,##0.00")]
public decimal PromotionAmountUSD { get; set; }
}

  

应用:

//register interface
services.RegisterServiceR<IExcelWriteService<FinancialBillEntity>, ExcelWriteReadAccordingDisplayService<FinancialBillEntity>>(lifeStyle); //get interface instance
var excelWriteService= services.GetInstance<IExcelWriteService<FinancialBillEntity>>(); //execute interface method
bool result=_excelWriteService.WriteData(financeBills,cmdOptions.OutputFinanceBillExcelPath,cmdOptions.OutputFinanceBillSheetName);

  

EPPlus实战篇——Excel写入的更多相关文章

  1. EPPlus实战篇——Excel读取

    .net core 项目 可以从excel读取任何类型(T)的数据,只要T中的field的[Display(Name = "1233")]中的name==excel column ...

  2. python基础 实战作业 ---Excel基本读写与数据处理

    代码地址如下:http://www.demodashi.com/demo/11650.html 看完本篇需要: 10min 作业练习需要: 0.5h~3h(依练习者对python熟悉程度而定) 看完本 ...

  3. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...

  4. 2天驾驭DIV+CSS (实战篇)(转)

     这是去年看到的一片文章,感觉在我的学习中,有不少的影响.于是把它分享给想很快了解css的兄弟们.本文是实战篇. 基础篇[知识一] “DIV+CSS” 的叫法是不准确的[知识二] “DIV+CSS” ...

  5. EpPlus读取生成Excel帮助类+读取csv帮助类+Aspose.Cells生成Excel帮助类

    大部分功能逻辑都在,少量自定义异常类和扩展方法 ,可用类似代码自己替换 //EpPlus读取生成Excel帮助类+读取csv帮助类,epplus只支持开放的Excel文件格式:xlsx,不支持 xls ...

  6. 构建NetCore应用框架之实战篇(七):BitAdminCore框架登录功能源码解读

    本篇承接上篇内容,如果你不小心点击进来,建议从第一篇开始完整阅读,文章内容继承性连贯性. 构建NetCore应用框架之实战篇系列 一.简介 1.登录功能完成后,框架的雏形已经形成,有必要进行复习. 2 ...

  7. SQL Server ->> 高可用与灾难恢复(HADR)技术 -- AlwaysOn(实战篇)之AlwaysOn可用性组搭建

    因为篇幅原因,AlwaysOn可用性组被拆成了两部分:理论部分和实战部分.而实战部分又被拆成了准备工作和AlwaysOn可用性组搭建. 三篇文章各自的链接: SQL Server ->> ...

  8. Redis实战篇

    Redis实战篇 1 Redis 客户端 1.1 客户端通信 原理 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 . 客户端和服务器发送的命令或数据一律以 \r\n ...

  9. MySQL 5.7主从复制实战篇

    MySQL 5.7主从复制实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装MySQL数据库并启动 1>.在MySQL官方下载相应的安装包(https://dev ...

随机推荐

  1. 正确把mysql数据库从windows迁移到linux系统上的方法

    (一)用mysqldump命令导出数据库文件: 在windows下cd到Mysql的bin目录: c:/data.txt这个目录和导出的文本名可以自己随便取,-B 后面的是表名,我要导出的表明叫use ...

  2. 谷歌重磅开源强化学习框架Dopamine吊打OpenAI

    谷歌重磅开源强化学习框架Dopamine吊打OpenAI 近日OpenAI在Dota 2上的表现,让强化学习又火了一把,但是 OpenAI 的强化学习训练环境 OpenAI Gym 却屡遭抱怨,比如不 ...

  3. seo网页加速技术,预加载 DNS Prefetching 详解

    seo网页加速技术,预加载 DNS Prefetching 详解 DNS Prefetching 是什么 : DNS 是什么-- Domain Name System,域名系统,作为域名和IP地址相互 ...

  4. Anaconda下载及安装及查看安装的Python库用法

    Anaconda下载及安装及查看安装的Python库用法 Anaconda 是一个用于科学计算的 Python 发行版,提供了包管理与环境管理的功能.Anaconda 利用 conda 来进行 pac ...

  5. 前端框架VUE----babel

    这个是解析我们es6的代码的,为什么要用它呢,因为对于一些ie浏览器,甚至FF浏览器,低版本的还不能识别我们的es6代码,那么vue里面好多还让我们去写es6的代码,这个时候我们就可以用babel这个 ...

  6. python-数据分析与展示(Numpy、matplotlib、pandas)---2

    笔记内容整理自mooc上北京理工大学嵩天老师python系列课程数据分析与展示,本人小白一枚,如有不对,多加指正 1.python自带的图像库PIL 1.1常用API  Image.open()    ...

  7. 搭建ELK日志分析(亲测无毒!)截图没有附上。。凑合看。搭建出来没有问题

    ( 1 )安装 Logstash 依赖包 JDK Logstash 的运行依赖于 Java 运行环境, Logstash 1.5 以上版本不低于 java 7 推荐使用最新版本的 Java .由于我们 ...

  8. springboot打war包需要注意事项

    1. pom文件 1.1 添加servlet-api依赖: <!-- 添加servlet-api的依赖--> <dependency> <groupId>org.a ...

  9. 一个六年Java程序员的从业总结:比起掉发,我更怕掉队

    我一直担惊受怕,过去,可能是因为我年轻,但现在,我已经不是那么年轻了,我仍然发现有很多事情让我害怕. 当年纪越来越大后,我开始变得不能加班.我开始用更多的时间和家人在一起,而不是坐在计算机前(尽管这样 ...

  10. Action的编写方式

    四.Action 的编写方式 : 三种 第一种 创建普通类 不继承任何类,不实现任何接口 Public class HelloAction{  } 第二种 创建类,实现接口action Public ...