踩坑小记1
好久没搞过npoi了,本来就想着用NPOI编辑一下模板,但是写入值要么是打不开,要么是打开报一堆警告消息。
解决方案
最新版本的NPOI处理.xlsx格式有bug,建议降级到NPOI2.4.1
或者是使用xls格式。
网上的神们提供的操作步骤是:
- 读取excel,然后关闭filestream
using (FileStream fs = File.OpenRead(fileName)) { if (fileName.IndexOf(".xlsx") > 0) // 2007版本 workbook = new XSSFWorkbook(fs); else if (fileName.IndexOf(".xls") > 0) // 2003版本 workbook = new HSSFWorkbook(fs); fs.Close(); }
- 修改excel
cell.SetCellValue(value);
- 打开excel,并赋予它写的权限,然后保存即可
workbook.Write(fs)
下面是我的代码,仅供参考:
public void SetExcelCellValue(string fileName, int iSheetIndex, int iRow, int iCol, object value)
{
try
{
if (File.Exists(fileName))
{
IWorkbook workbook = null;
using (FileStream fs = File.OpenRead(fileName))
{
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs);
fs.Close();
}
ISheet sheet = workbook.GetSheetAt(iSheetIndex);
IRow row = sheet.GetRow(iRow);
if (row == null)
{
row = sheet.CreateRow(iRow);
}
ICell cell = row.GetCell(iCol);
if (cell == null)
{
row.CreateCell(iCol);
}
if (value is int)
{
cell.SetCellValue((int)value);
}
else if (value is double)
{
cell.SetCellValue((double)value);
}
else if (value is string)
{
cell.SetCellValue(value.ToString());
}
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write))
{
workbook.Write(fs);
workbook.Close();
fs.Close();
}
}
}
catch (Exception ex)
{
LogHelper.WriteLog(typeof(ExcelHelper), ex, "设置单元格出错!");
}
}
踩坑小记2
NPOI 大表输出的时候,会报错out of memory的错误(这块我的数据量大概有二十多万条记录)
解决方案
使用EPPlus
代替NPOI
操作Excel即可,速度又快又稳定。
-
Nuget搜索
EPPlus
并安装 -
命名空间引用
using OfficeOpenXml
-
编写代码
FileInfo file = new FileInfo(fileName); using (var package = new ExcelPackage(file)) { ExcelWorksheet sheet = package.Workbook.Worksheets[iSheetIndex]; sheet.SetValue(iRow, iCol, value); package.Save(); }
注:EPPlus的起始行列号是从1开始的
,NPOI是从0开始的。
参考链接:
5. NPOI操作Excel 踩坑记
6. https://github.com/tonyqus/npoi/issues/182