使用NPOI/Apache POI编辑.xlsx文件时如何保留原有单元格背景色
问题描述
我使用C#进行开发,当前使用的NPOI版本为2.5.5。由于两者的解决方案通用,因此本问题也适用于Apache POI场景。
我有一个扩展名为.xlsx的Excel文件,初始状态如下:
我通过NPOI对Excel工作表进行编辑,相关代码如下:
private void button_editByNpoi_Click(object sender, EventArgs e) { string filePath = destFileName; IWorkbook workbook; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { workbook = new XSSFWorkbook(fs); } /* //1枚目のシートを取得 ISheet sheet = workbook.GetSheetAt(0); //セルを取得 IRow row = sheet.GetRow(1); ICell cell = row.GetCell(1); //セルに書き込み //cell.SetCellValue("a"); */ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { //上書き保存する。 workbook.Write(fs); } }
编辑后保存得到的Excel文件效果如下:
编辑后文件中原有的浅灰色单元格背景色消失了,请问如何操作才能保留原有背景色?
解决方案
- 方案1:升级NPOI版本
这是NPOI 2.5.x版本的已知缺陷,该版本处理Excel索引色、主题色填充的样式时,会错误将其判定为无效样式在保存时清理。升级到NPOI 2.6.0及以上稳定版本即可解决,原有代码无需做任何修改。 - 方案2:低版本兼容处理
如果因项目依赖无法升级NPOI版本,可以在保存文件前遍历所有单元格,强制保留样式引用,避免被误清理,参考代码如下:// 在调用workbook.Write方法之前加入以下代码 for (int s = 0; s < workbook.NumberOfSheets; s++) { ISheet sheet = workbook.GetSheetAt(s); if (sheet.PhysicalNumberOfRows <= 0) continue; for (int r = sheet.FirstRowNum; r <= sheet.LastRowNum; r++) { IRow row = sheet.GetRow(r); if (row == null) continue; for (int c = row.FirstCellNum; c < row.LastCellNum; c++) { ICell cell = row.GetCell(c); if (cell != null) { // 强制刷新样式引用,避免被判定为未使用样式清理 cell.CellStyle = cell.CellStyle; } } } }
内容的提问来源于stack exchange,提问作者Angus B.
相关产品推荐
相关产品推荐

