WeihanLi.Npoi 1.21.0 Released
WeihanLi.Npoi 1.21.0 Released
Intro
WeihanLi.Npoi 是一個基于 netstandard2.0 的一個 NPOI 擴展庫,主要用于導入導出 Excel 以及 CSV,支持通過 Fluent API 的方式來支持非常靈活的導入導出配置,詳細使用可以參考文檔介紹以及項目示例 https://github.com/WeihanLi/WeihanLi.Npoi
New Features
本次引入的新功能是針對 DataTable 的優化,如果導入的 Excel 出現了重復列,原來會直接拋出一個 System.Data.DuplicateNameException,主要是因為原來是直接用 excel 列名稱作為 DataColumn 的 Name,而一個 DataTable 中是不允許有名字重復 Column 的,就像數據庫同一個表中不允許出現重復列名一樣??梢詤⒖?Issue https://github.com/WeihanLi/WeihanLi.Npoi/issues/125
而導入 excel 時,很多時候可能并不根據列名稱去讀取對應的值,有時候會直接使用列索引來讀取列的值,這個場景下,即使 excel 列名沖突了也關系不大,我們只需要按照索引讀取就可以了,所以就考慮了支持沖突的讀取,因為想再導出的時候 excel 還和之前導入的時候保持一致,所以也增加了導出的時候對 DataTable 的處理,實現效果可以參考單元測試:
//?Csv [Fact] public?void?DuplicateColumnTest() {var?csvText?=?$@"A,B,C,A,B,C{Environment.NewLine}1,2,3,4,5,6";var?dataTable?=?CsvHelper.ToDataTable(csvText.GetBytes());Assert.Equal(6,?dataTable.Columns.Count);Assert.Equal(1,?dataTable.Rows.Count);var?newCsvText?=?CsvHelper.GetCsvText(dataTable);Assert.StartsWith("A,B,C,A,B,C",?newCsvText);var?newDataTable?=?CsvHelper.ToDataTable(newCsvText.GetBytes());Assert.Equal(dataTable.Columns.Count,?newDataTable.Columns.Count);Assert.Equal(dataTable.Rows.Count,?newDataTable.Rows.Count); } //?Excel [Theory] [ExcelFormatData] public?void?DuplicateColumnTest(ExcelFormat?excelFormat) {var?workbook?=?ExcelHelper.PrepareWorkbook(excelFormat);var?sheet?=?workbook.CreateSheet();var?headerRow?=?sheet.CreateRow(0);headerRow.CreateCell(0).SetCellValue("A");headerRow.CreateCell(1).SetCellValue("B");headerRow.CreateCell(2).SetCellValue("C");headerRow.CreateCell(3).SetCellValue("A");headerRow.CreateCell(4).SetCellValue("B");headerRow.CreateCell(5).SetCellValue("C");var?dataRow?=?sheet.CreateRow(1);dataRow.CreateCell(0).SetCellValue("1");dataRow.CreateCell(1).SetCellValue("2");dataRow.CreateCell(2).SetCellValue("3");dataRow.CreateCell(3).SetCellValue("4");dataRow.CreateCell(4).SetCellValue("5");dataRow.CreateCell(5).SetCellValue("6");var?dataTable?=?sheet.ToDataTable();Assert.Equal(headerRow.Cells.Count,?dataTable.Columns.Count);Assert.Equal(1,?dataTable.Rows.Count);var?newWorkbook?=?ExcelHelper.LoadExcel(dataTable.ToExcelBytes());var?newSheet?=?newWorkbook.GetSheetAt(0);Assert.Equal(sheet.PhysicalNumberOfRows,?newSheet.PhysicalNumberOfRows);for?(var?i?=?0;?i?<?sheet.PhysicalNumberOfRows;?i++){Assert.Equal(sheet.GetRow(i).Cells.Count,?newSheet.GetRow(i).Cells.Count);for?(var?j?=?0;?j?<?headerRow.Cells.Count;?j++){Assert.Equal(sheet.GetRow(i).GetCell(j).GetCellValue<string>(),newSheet.GetRow(i).GetCell(j).GetCellValue<string>());}} }實現方式上一定程度參考了 issue 給出的建議,導入時重復列會添加一個 duplicate 標識和一個唯一 id 使得名稱不會重復,從而不會引發異常,導出時如果是重復列會把 duplicate 標識和唯一 id 去掉從而還原真實的列名稱,更多細節可以查看 Github 上的 PR https://github.com/WeihanLi/WeihanLi.Npoi/pull/126
Bug Fixes
修復了 sheet name 配置可能會不生效的 BUG
本次更新修復了在導出成文件的時候 sheet name 的配置沒有生效的一個 BUG,詳細可以參考 issue: https://github.com/WeihanLi/WeihanLi.Npoi/issues/127
開始并沒有重現這個 BUG,因為只有在導出為文件的時候才會有問題,如果是 bytes 或者 stream 是不會有這個問題的,現在已經增加了下面的測試用例來覆蓋這個情況
[Theory] [ExcelFormatData] public?void?SheetNameTest_ToExcelFile(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?settings?=?FluentSettings.For<Notice>();lock?(settings){settings.HasSheetSetting(s?=>{s.SheetName?=?"Test";});var?filePath?=?$"{Path.GetTempFileName()}.{excelFormat.ToString().ToLower()}";list.ToExcelFile(filePath);var?excel?=?ExcelHelper.LoadExcel(filePath);Assert.Equal("Test",?excel.GetSheetAt(0).SheetName);settings.HasSheetSetting(s?=>{s.SheetName?=?"NoticeList";});}}[Theory] [ExcelFormatData] public?void?SheetNameTest_ToExcelBytes(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?settings?=?FluentSettings.For<Notice>();lock?(settings){settings.HasSheetSetting(s?=>{s.SheetName?=?"Test";});var?excelBytes?=?list.ToExcelBytes(excelFormat);var?excel?=?ExcelHelper.LoadExcel(excelBytes,?excelFormat);Assert.Equal("Test",?excel.GetSheetAt(0).SheetName);settings.HasSheetSetting(s?=>{s.SheetName?=?"NoticeList";});} }修復導出到文件 excel 文件格式不對的 BUG
根據文件路徑創建 excel workbook 的時候原來是有 BUG 的可能會導致文件格式不對,原來沒有先換取文件擴展名,新版本中修復了這個 bug,會先獲取文件擴展名再判斷文件格式
-?!excelPath.EqualsIgnoreCase(".xls") +?!Path.GetExtension(excelPath).EqualsIgnoreCase(".xls")More
這個新版本中還有個針對 CsvHelper 的小優化,主要是獲取導出的 CSV 字符串時 includeHeader 參數變成了一個可選參數,對于調用方來說可以調用會變得更簡單一些,默認值是 true,默認會包含 header
public?static?string?GetCsvText(this?DataTable??dataTable,?bool?includeHeader?=?true); public?static?string?GetCsvText<TEntity>(this?IEnumerable<TEntity>?entities,?bool?includeHeader?=?true); 更多細節可以參考 PR 變更 https://github.com/WeihanLi/WeihanLi.Npoi/pull/130References
https://github.com/WeihanLi/WeihanLi.Npoi
https://github.com/WeihanLi/WeihanLi.Npoi/pull/130
https://www.nuget.org/packages/WeihanLi.Npoi/1.21.0
https://github.com/WeihanLi/WeihanLi.Npoi/tree/1.21.0
總結
以上是生活随笔為你收集整理的WeihanLi.Npoi 1.21.0 Released的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端开发的盛宴
- 下一篇: 抓包写代码模拟怎么减少重复劳动