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 增加 RowFilterCellFilter 来更灵活的配置自己想要读取的数据范围,借助于此我们可以轻松实现隔行读取或多个范围读取等。

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 之外,还有几个小更新,重构了 ExcelSettingSheetSetting ,提供了基于委托来配置的方法,原来的方法作为扩展方法来使用,另外就是优化了文件读取,原来如果别的进程已经打开了文件,这时候再导入就会抛出异常,优化之后即使文件被别的进程占用,依然可以读取文件内容进行导入操作,操作体验可能会更好一些。

更多细节可以参考 Github 仓库里的示例和单元测试

Reference

WeihanLi.Npoi 1.11.0/1.12.0 Release Notes的更多相关文章

  1. 所生成项目的处理器架构“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): ...

  2. Navicat Premium 12.0.18 / 12.0.24安装与激活

    若使用Navicat Premium 12.1.8.0请转至Navicat Premium 12.1.8.0安装与激活,其实每个小版本更迭变化不大.另外最重要的是,请仔细阅读本文激活部分,总有一些人遇 ...

  3. GitLab升级(yum安装版v11.11.8~12.0.12)

    参考官方升级建议(注意升级路线:Example upgrade paths) 升级前请自行备份(测试可忽略此步骤) 生成备份文件,在/var/opt/gitlab/backups/目录下生成备份文件 ...

  4. Microsoft.Office.Interop.Excel, Version=12.0.0.0版本高于引用的程序集(已解决)

    Microsoft.Office.Interop.Excel, Version=12.0.0.0版本高于引用的程序集(已解决) 论坛里的帮助:http://bbs.csdn.net/topics/39 ...

  5. zend studio 12.0 怎么汉化?

    网上搜索到的答案在:http://zhidao.baidu.com/link?url=OUGXDr0H28ad0UYSCUQ27BziJnymTcfWCmNAmzSRorOe3ZDSRhRXY0QoE ...

  6. Navicat Premium 12.0.24安装与激活(亲测已成功激活)

    另请参见:Navicat Premium 12.0.18 / 12.0.24安装与激活 另请参见:Navicat Premium 12安装与激活(亲测已成功激活) 说明: 本主亲自验证过,可以激活! ...

  7. Microsoft.ACE.OLEDB.12.0 及其在 MSSQL中的使用

    1.Microsoft.ACE.OLEDB.12.0 简介 就是一个数据访问接口,用于在office文件和非office应用程序间传输数据.例如 Microsoft Office Access 201 ...

  8. SQL SERVER导入EXCEL文件:无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.Ace.OLEDB.12.0" 的实例。

    [方法一] --开启导入功能    exec sp_configure 'show advanced options',1    reconfigure    exec sp_configure 'A ...

  9. WeihanLi.Npoi

    WeihanLi.Npoi Intro Npoi 扩展,适用于.netframework4.5及以上和netstandard2.0, .netframework基于NPOI, .netstandard ...

随机推荐

  1. Mbedtls和Opesnssl 解码x509Certificate

    最近项目需要添加解码x509Certificate功能,可以使用openssl或者mbedtls库.对这两个库的使用总结一下. 一 Openssl解码x509 Certificate 1. 初始化   ...

  2. Asp.Net Core 企业微信静默授权

    企业微信接口文档 1.构造授权网页链接 2.回调获取到 Code 通过code+access_token去请求用户信息 3.获取access_token 调试准备工作 -->内网穿透+域名 推荐 ...

  3. 超级简单的照片画廊MVC

    下载Gallery.zip - 23.5 MB 介绍 我想在我的个人网站上添加一个简单的图片库,但找不到任何合适的方法来从文件夹而不是数据库中挑选图片.也许我应该看得更仔细些!尽管如此,下面是我实现的 ...

  4. [Docker] redis 全配置

    启动容器,加载配置文件并持久化数据 docker run -d --privileged=true -p 6379:6379 --restart always -v /usr/redis/conf:/ ...

  5. day37 Pyhton 网络编程04

    # tcp协议和udp协议的选择问题 # tcp # 大量的连续的数据 传递文件\发送邮件 # 文件的传递 # 下载电影 # udp # 短消息类 社交软件 # qq 微信 # 在线播放视频 快会丢帧 ...

  6. 程序员的“三十而已”,你都30岁了,不会还在XXX吧?

    一部<三十而已>火了 太太们的包包鄙视链出圈了 有人的地方就有江湖 是的,程序员入圈是容易的 不需要4万的LV,更不需要限量版的爱马仕 只需要一件耐躁的格子衫 然而,程序员的30岁, 却说 ...

  7. hugo主题文档-manpassant

    +++ date="2020-10-17T10:32:00+08:00" title="hugo主题文档manpassant" tags=["hugo ...

  8. swoft 使用协程 初试

    控制器访问 /hi /** * @Swoft\Bean\Annotation\Mapping\Inject("UserService") * @var UserService */ ...

  9. centos8上安装mysql8

    一,下载并解压mysql8 1,mysql官网 https://www.mysql.com/ 2,下载到source目录 [root@yjweb source]# wget https://cdn.m ...

  10. selenium 设置代理ip

    from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--prox ...