NPOI 读取单元格的格式

    最近做项目需要导入一部分数据, 导入的数据的中, 有部分的百分比数据使用的是excel 的百分比, 有部分的数据使用的是字符串形式的格式,(数据来源于不同的人统计), 格式略微有点乱, 要求导入系统的时候, 将所有百分比的数据转换成百分制的数据存储起来. 

    因为之前项目使用的读取excel 的组件式NPOI , 所以我也就直接使用npoi来读, 我用的NPOI是2.0的版本的, 不算太新.  

    常规读取的时候, 是按照下面的方式读取到ICell的

IWorkbook workbook = null;
var workbook = NPOI.SS.UserModel.WorkbookFactory.Create(fileStream);
ISheet sheet = workbook .GetSheetAt(0);
IRow firstRow = sheet.GetRow(1);
ICell cell = firstRow.GetCell(0);

  这样获取到ICell对象以后, 可以通过ICell.CellType 判断到单元格的数据类型, 从 ICell.CellStyle.DataFormat可以去到单元格的格式, 但是问题来了: CellStyle.DataFormat只能获取到一个格式的数字编码(例如186), 不能获取到具体的格式是什么(例如0.00%). 

  那么需要有地方完成从格式数字编码到具体的格式之间的转换, 我从网上找了好久, 没有找到具体的方法, 后来想了想excel是xml格式的, 要不还是先从excel下手. 

      ok, 先把excel后缀改为.rar, 然后解压, 解压后找到xlstyles.xml, 这个就是excel的样式文件, 打开看看, 发现数据格式就在最开始的地方, 是个一个<numFmt numFmtId="178" formatCode="0.000%"/>的数值, 蛮清楚, 不过总不能自己去硬解码样式吧, 这样也太土了点, 想想先按下不表, 还是从NPOI 下手. 

      后来咨询了下同事, 同事也没有干过这种事情, 不过给了点先线索, 他用过一个检查单元格是否是时间格式的方法, 在NPOI的UserModel命名空间下, 不过他用的那个方法是用来检查excel 的内置格式的, 不包含自定义格式.  我一想也许获取样式的代码在其他命名空间下,  好吧, 开始翻dll吧(苦逼, 没有找到api, 直接用vs看dll 的命名空间下有哪些类)

  好在NPOI不是很大, 翻到第二个dll就找打了线索, NPOI.OOXML.dll下有个类 NPOI.XSSF.UserModel.XSSFDataFormat, 这个类有个方法NPOI.XSSF.UserModel.XSSFDataFormat.GetFormat(short) 看起来像是获取格式的, 但是XSSFDataFormat这个类的构造函数是这样的:XSSFDataFormat(NPOI.XSSF.Model.StylesTable), 要求传入一个StylesTable对象, 找打这个StylesTable的类定义, 发现这个类的构造函数没有参数, 也没有create方法, 好像不对. 

     这个时候, 同事出了个主意: 这个NPOI是开源了, 把源代码下下来, 看看有没有StylesTable的实例, 想了下, 好主意. 几分钟, 代码就下下来了, 整个项目搜索StylesTable , 马上就发现了一行代码

StylesTable st = ((XSSFWorkbook)workbook).GetStylesSource();

哈哈, 原来是在IWookbook的实现类了, 难怪在接口上找不到. 

  把上面的代码给成这样:

IWorkbook workbook = null;
StylesTable st = ((XSSFWorkbook)workbook ).GetStylesSource();
XSSFDataFormat df = new XSSFDataFormat(st);
var workbook = NPOI.SS.UserModel.WorkbookFactory.Create(fileStream);
ISheet sheet = workbook .GetSheetAt(0);
IRow firstRow = sheet.GetRow(1);
ICell cell = firstRow.GetCell(0);
string formatCode = df.GetFormat(cell.CellStyle.DataFormat);
if (formatCode.EndsWith("%"))
{
}

  

  这样获取到的formatcode就是"0.000%" 格式的, 瞬间爽了. 

  最后发现: 开源的东西, 最好的办法是去源代码里面找你要的东西, 加上google的线索, 绝对事半功倍.

 后来经 烽火情怀 提醒, 有简单方法: ICell.CellStyle.GetDataFormatString()就能获取到格式字符串.

      

原文地址:https://www.cnblogs.com/dunnice/p/npoicelldataformat.html