WeihanLi.Npoi 1.11.0/1.12.0 Release Notes
WeihanLi.Npoi 1.11.0/1.12.0 Release Notes
Intro
最近 NPOI 扩展新更新了两个版本,感谢 shaka chow 的帮忙和支持,这两个 Feature 都是来自于他,并且帮我测试了几个版本,还帮我提供了一个更好用的读文件的方式,十分感谢。
最近更新的两个功能都是 Excel 导入方面的,1.11.0 版本支持公式导入处理,1.12.0 支持通过 Attribute 配置允许读取的列范围, 也可以通过 Fluent API 的方式设置 CellFilter 来更灵活的过滤不想读取的列。
公式导入的支持
在之前的版本中是没有公式支持的,导入一个公式的单元格会是一个字符串去读取,某些场景下可能用 Excel 会很有用,于是尝试添加了公式的支持,仅是导入,导出的时候没有支持公式,一方面是因为根据公式去计算导出的值的时候可能会需要先把所有值先填完整再计算公式的值,这样的场景会导致效率很低,另外一方面我觉得 Fluent API 的方式已经可以满足大多数场景的需要,不是特别需要,所以没有支持公式的导出。
Row/Cell Filter 支持
在 1.10.0 版本中,我们支持了一个 EndRowIndex 来配置一个结束行,用以提前结束读取数据,在 1.12.0 版本中 shaka 提出了可以增加 StartColumnIndex 以及 EndColumnIndex 配置来指定要读取的列范围,在此基础上想出了基于 Fluent API 给 Sheet 增加 RowFilter 和 CellFilter 来更灵活的配置自己想要读取的数据范围,借助于此我们可以轻松实现隔行读取或多个范围读取等。
Show the Code
Excel 公式导入支持的示例:
[Theory]
[InlineData(ExcelFormat.Xls)]
[InlineData(ExcelFormat.Xlsx)]
public void ExcelImportWithFormula(ExcelFormat excelFormat)
{
var setting = FluentSettings.For<ExcelFormulaTestModel>();
setting.HasSheetConfiguration(0, "Test", 0);
setting.Property(x => x.Num1).HasColumnIndex(0);
setting.Property(x => x.Num2).HasColumnIndex(1);
setting.Property(x => x.Sum).HasColumnIndex(2);
var workbook = ExcelHelper.PrepareWorkbook(excelFormat);
var sheet = workbook.CreateSheet();
var row = sheet.CreateRow(0);
row.CreateCell(0, CellType.Numeric).SetCellValue(1);
row.CreateCell(1, CellType.Numeric).SetCellValue(2);
row.CreateCell(2, CellType.Formula).SetCellFormula("$A1+$B1");
var excelBytes = workbook.ToExcelBytes();
var list = ExcelHelper.ToEntityList<ExcelFormulaTestModel>(excelBytes, excelFormat);
Assert.NotNull(list);
Assert.NotEmpty(list);
Assert.Equal(1, list[0].Num1);
Assert.Equal(2, list[0].Num2);
Assert.Equal(3, list[0].Sum);
}
公式的支持不需要修改任何代码,和原来的 API 是完全兼容的,可以看到上面公式的导入的值成功被替换成了计算后的值
Cell Filter 使用 Attribute 方式示例
[Theory]
[InlineData(ExcelFormat.Xls)]
[InlineData(ExcelFormat.Xlsx)]
public void ExcelImportWithCellFilterAttributeTest(ExcelFormat excelFormat)
{
IReadOnlyList<CellFilterAttributeTest> list = Enumerable.Range(0, 10).Select(i => new CellFilterAttributeTest()
{
Id = i + 1,
Description = $"content_{i}",
Name = $"title_{i}",
}).ToArray();
var excelBytes = list.ToExcelBytes(excelFormat);
var importedList = ExcelHelper.ToEntityList<CellFilterAttributeTest>(excelBytes, excelFormat);
Assert.NotNull(importedList);
Assert.Equal(list.Count, importedList.Count);
for (var i = 0; i < importedList.Count; i++)
{
Assert.Equal(list[i].Id, importedList[i].Id);
Assert.Equal(list[i].Name, importedList[i].Name);
Assert.Null(importedList[i].Description);
}
}
[Sheet(SheetName = "test", AutoColumnWidthEnabled = true, StartColumnIndex = 0, EndColumnIndex = 1)]
private class CellFilterAttributeTest
{
[Column(Index = 0)]
public int Id { get; set; }
[Column(Index = 1)]
public string Name { get; set; }
[Column(Index = 2)]
public string Description { get; set; }
}
可以看到最后一列的值其实是被忽略掉的,最后一列对应的 Description 属性永远是 null
Cell Filter 使用 Fluent API 方式示例
[Theory]
[InlineData(ExcelFormat.Xls)]
[InlineData(ExcelFormat.Xlsx)]
public void ExcelImportWithCellFilter(ExcelFormat excelFormat)
{
IReadOnlyList<Notice> list = Enumerable.Range(0, 10).Select(i => new Notice()
{
Id = i + 1,
Content = $"content_{i}",
Title = $"title_{i}",
PublishedAt = DateTime.UtcNow.AddDays(-i),
Publisher = $"publisher_{i}"
}).ToArray();
var excelBytes = list.ToExcelBytes(excelFormat);
var settings = FluentSettings.For<Notice>();
settings.HasSheetSetting(setting =>
{
setting.CellFilter = cell => cell.ColumnIndex == 0;
});
var importedList = ExcelHelper.ToEntityList<Notice>(excelBytes, excelFormat);
Assert.Equal(list.Count, importedList.Count);
for (var i = 0; i < list.Count; i++)
{
if (list[i] == null)
{
Assert.Null(importedList[i]);
}
else
{
Assert.Equal(list[i].Id, importedList[i].Id);
Assert.Null(importedList[i].Title);
Assert.Null(importedList[i].Content);
Assert.Null(importedList[i].Publisher);
Assert.Equal(default(DateTime).ToStandardTimeString(), importedList[i].PublishedAt.ToStandardTimeString());
}
}
settings.HasSheetSetting(setting =>
{
setting.CellFilter = null;
});
}
这个示例比较简单,只导入了第一列的数据 ,其他列数据对应的属性都是默认值
More
除了这两个主要的 Feature 之外,还有几个小更新,重构了 ExcelSetting 和 SheetSetting ,提供了基于委托来配置的方法,原来的方法作为扩展方法来使用,另外就是优化了文件读取,原来如果别的进程已经打开了文件,这时候再导入就会抛出异常,优化之后即使文件被别的进程占用,依然可以读取文件内容进行导入操作,操作体验可能会更好一些。
更多细节可以参考 Github 仓库里的示例和单元测试
Reference
- https://github.com/WeihanLi/WeihanLi.Npoi
- https://www.nuget.org/packages/WeihanLi.Npoi/
- https://github.com/WeihanLi/WeihanLi.Npoi/blob/dev/docs/ReleaseNotes.md
WeihanLi.Npoi 1.11.0/1.12.0 Release Notes的更多相关文章
- 所生成项目的处理器架构“MSIL”与引用“Microsoft.AspNet.Scaffolding.12.0, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=x86”的处理器架构“x86”不匹配。
生成成功后: 3>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): ...
- Navicat Premium 12.0.18 / 12.0.24安装与激活
若使用Navicat Premium 12.1.8.0请转至Navicat Premium 12.1.8.0安装与激活,其实每个小版本更迭变化不大.另外最重要的是,请仔细阅读本文激活部分,总有一些人遇 ...
- GitLab升级(yum安装版v11.11.8~12.0.12)
参考官方升级建议(注意升级路线:Example upgrade paths) 升级前请自行备份(测试可忽略此步骤) 生成备份文件,在/var/opt/gitlab/backups/目录下生成备份文件 ...
- Microsoft.Office.Interop.Excel, Version=12.0.0.0版本高于引用的程序集(已解决)
Microsoft.Office.Interop.Excel, Version=12.0.0.0版本高于引用的程序集(已解决) 论坛里的帮助:http://bbs.csdn.net/topics/39 ...
- zend studio 12.0 怎么汉化?
网上搜索到的答案在:http://zhidao.baidu.com/link?url=OUGXDr0H28ad0UYSCUQ27BziJnymTcfWCmNAmzSRorOe3ZDSRhRXY0QoE ...
- Navicat Premium 12.0.24安装与激活(亲测已成功激活)
另请参见:Navicat Premium 12.0.18 / 12.0.24安装与激活 另请参见:Navicat Premium 12安装与激活(亲测已成功激活) 说明: 本主亲自验证过,可以激活! ...
- Microsoft.ACE.OLEDB.12.0 及其在 MSSQL中的使用
1.Microsoft.ACE.OLEDB.12.0 简介 就是一个数据访问接口,用于在office文件和非office应用程序间传输数据.例如 Microsoft Office Access 201 ...
- SQL SERVER导入EXCEL文件:无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.Ace.OLEDB.12.0" 的实例。
[方法一] --开启导入功能 exec sp_configure 'show advanced options',1 reconfigure exec sp_configure 'A ...
- WeihanLi.Npoi
WeihanLi.Npoi Intro Npoi 扩展,适用于.netframework4.5及以上和netstandard2.0, .netframework基于NPOI, .netstandard ...
随机推荐
- 第二次UML作业
博客班级 https://edu.cnblogs.com/campus/fzzcxy/2018SE1/ 作业要求 https://edu.cnblogs.com/campus/fzzcxy/2018S ...
- (数据科学学习手札96)在geopandas中叠加在线地图
本文示例文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 国庆期间,抽空给大家分享在geopandas中叠 ...
- JavaScript动态生成表格
要求: HTML标签只写一行表头 通过JS来写动态的表格(有多少组数据,就自动创建多少行表格) 为学习和演示,采用固定的数据,不涉及调用后台数据 代码实现: HTML内容: <table cel ...
- maven下载依赖包下载失败
在家办公,遇到项目的maven包下载不了,刚开始以为是vpn的问题,折腾半天反复确认之后没有发现什么问题. 同时试过阿里巴巴的maven仓库,删除过以来,重新导过包发现都不行. 后来在idea的设置里 ...
- Java虚拟机系列——检视阅读
Java虚拟机系列--检视阅读 参考 java虚拟机系列 入门掌握JVM所有知识点 2020重新出发,JAVA高级,JVM JVM基础系列 从 0 开始带你成为JVM实战高手 Java虚拟机-垃圾收集 ...
- cocos creator屏幕适配的一些知识点
一. cocos creator 提供的几种适配策略 EXACT_FIT: 整个应用程序在指定区域可见,无需尝试保留原始纵横比.可能会出现失真,应用程序会被拉伸或压缩.也就是说设计分辨率的长和宽不会等 ...
- MySQL数据库的完全备份与恢复
前言 在生产环境中,数据的安全性是至关重要的,任何数据的丢失都可能产生严重的后果,正确的数据库操作是实际环境下不可缺少的. 一.数据库备份的分类 1.1 从物理与逻辑的角度,备份的分类 物理备份:对数 ...
- 要是想让程序跳转到绝对地址是0x100000去执行
要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做? *((void (* ...
- mysql5.5和5.6的一些区别
timestamp 5.5中 直接写timestamp不加长度 5.6 中 写的timestamp(3) datatime 5.5中 直接写datetime 不加长度 5.6中 可以添加长度(3 ...
- nginx的脚本引擎(二)rewrite
其实rewrite指令和上一篇说的if/set/return/break之类的没多大差别,但是rewrite用起来相对复杂,我就把他单独放到了这里.想要弄懂nginx的脚本引擎需要先明白处理reque ...