C#操作NPOI插件的HSSFWorkBook,常见的那些坑
使用HSSFWorkBook类实例化时,经常会遇到一个问题:HSSFWorkBook.isReadOnly。
HSSFWorkBook.isReadOnly,貌似是异常,但它又不影响你正常导出Excel模板,但是必须注意的是,Excel模板的后缀名要为.xls,如果是.xlsx,那么就会出现打开文件错误,其实是Excel版本的兼容性问题。
有时候HSSFRow sheetRow = (HSSFRow)sheet.CreateRow(index);创建新的row,接着使用sheetRow.CreateCell(2).SetCellValue(new HSSFRichTextString("字符串"));给每个cell赋值时,有可能遇到一个问题:
for (int i=0; i<ts.Days; i++)
{
HSSFRow sheetRow = (HSSFRow)sheet.CreateRow(4+i);
sheetRow.CreateCell(0).SetCellValue(new HSSFRichTextString(startDate.AddDays(i).ToString("yyyy-MM-dd")));//日期:2018-01-01
sheetRow.CreateCell(1).SetCellValue(new HSSFRichTextString(startDate.AddDays(i).ToString("dddd")));//周一、周二......
//必须添加上"",如果没有给空字符串,该cell为null,上传模板的时候,Cells的个数会根据user是否输入数据而有所改变
sheetRow.CreateCell(2).SetCellValue(new HSSFRichTextString(""));
sheetRow.CreateCell(3).SetCellValue(new HSSFRichTextString(""));
sheetRow.CreateCell(4).SetCellValue(new HSSFRichTextString(""));
}
注意,代码里头有3个cell的值设置为"",如果不设置,那么这3个cell根本就是null,再者,当用户把这个模板下载下来,有些cell输入值,有些cell没有输入,如:
test1 | test2 | test3 | test4 | test5 |
test2 | test4 | |||
test3 | ||||
test1 | test5 | |||
那么在读取数据的时候,第一行的Cells.Count==5,第二、四行的Cells.Count==2,第三行的Cells.Count==1,第五行的Cells.Count==0。如果像代码里面设置空字符串,就不管后续用户有没有输入新数据,都可以确保取到相关位置的值,不会出现out of range的异常。
使用GetCell(index)方法精确找位:
有时候你需要将上传的excel表格的值显示在客户端,同时还要根据某几个cell值是否为空值,或者null来进行剔除,如果真出现不定量的值为null的Cell个数,显然用Cells[index]是不行的,上面提及到,Cells.Count不统计null的Cell格子,譬如对于上图的第二行,Cells[0]的值可能就是test2,如何精确找到对应Cell的位置呢?为了应对此情况,NPOI还提供了一个方法来精确寻找Cell格子,就是GetCell(index)。那么通过GetCell(index)可以精确找到相应位置,进而可以判断是否为空,是否为null,然后进行筛选,赋值等操作。
使用StringCellValue方法,通常我们想要取出某个cell的值,可能会使用:
string resGp = sheet.GetRow(0).Cells[1].StringCellValue;
//但如果,sheet.GetRow(0).Cells[1]的值是一个数值,
//这里不是说数据类型,是形式上就是阿拉伯数字,
//那么调用StringCellValue就会抛出异常
//不调用StringCellValue,其效果一样,而且解决值为阿拉伯数字的情况
string resGp = sheet.GetRow(0).Cells[1];
//上面一句虽然避免了异常问题,但是,如果想获取阿拉伯数值的数据,那就使用ToString()
string resGp = sheet.GetRow(0).Cells[1].ToString();