NPOI 读取单元格的格式

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

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

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

1
2
3
4
5
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, 然后解压, 解压后找到\xl\styles.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的实现类了, 难怪在接口上找不到. 

  把上面的代码给成这样:

1
2
3
4
5
6
7
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);
1
2
3
4
string  formatCode = df.GetFormat(cell.CellStyle.DataFormat);
if  (formatCode.EndsWith( "%" ))
{
}

  

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

 

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

 

 

      

使用 NPOI读取单元格内容的基本步骤如下: 1. 引入 NPOI 库 在 Visual Studio 中,右键单击项目,选择“管理 NuGet 程序包”,搜索并安装 NPOI 库。 2. 创建 Excel 文件对象 可以通过以下代码创建一个 Excel 文件对象: ``` using NPOI.HSSF.UserModel; // for .xls format using NPOI.XSSF.UserModel; // for .xlsx format // create a new workbook IWorkbook workbook = null; if (Path.GetExtension(filePath) == ".xls") { workbook = new HSSFWorkbook(File.OpenRead(filePath)); } else if (Path.GetExtension(filePath) == ".xlsx") { workbook = new XSSFWorkbook(File.OpenRead(filePath)); } ``` 其中,`filePath` 是 Excel 文件的路径。 3. 获取工作表对象 可以通过以下代码获取指定名称的工作表对象: ``` ISheet sheet = workbook.GetSheet("Sheet1"); // "Sheet1" 是工作表的名称 ``` 4. 获取单元格对象 可以通过以下代码获取指定行列位置的单元格对象: ``` IRow row = sheet.GetRow(rowIndex); // rowIndex 是行索引 ICell cell = row.GetCell(cellIndex); // cellIndex 是列索引 ``` 5. 读取单元格内容 可以通过以下代码读取单元格的字符串内容: ``` string cellValue = cell.StringCellValue; ``` 完整代码示例: ``` using System.IO; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; // file path string filePath = @"C:\temp\test.xlsx"; // create a new workbook IWorkbook workbook = null; if (Path.GetExtension(filePath) == ".xls") { workbook = new HSSFWorkbook(File.OpenRead(filePath)); } else if (Path.GetExtension(filePath) == ".xlsx") { workbook = new XSSFWorkbook(File.OpenRead(filePath)); } // get the sheet ISheet sheet = workbook.GetSheet("Sheet1"); // get the cell IRow row = sheet.GetRow(0); ICell cell = row.GetCell(0); // get the cell value string cellValue = cell.StringCellValue; // output the cell value Console.WriteLine(cellValue); ``` 注意事项: 1. Excel 文件必须已经存在,否则会抛出异常; 2. NPOI 库支持读取 .xls 格式和 .xlsx 格式的 Excel 文件; 3. 单元格内容的数据类型可能不同,需要根据实际情况进行类型转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值