C# 读取本地Excel并解析 Cannot get a xx value from a yy cell 【深度踩坑】

2024-03-26 17:10

本文主要是介绍C# 读取本地Excel并解析 Cannot get a xx value from a yy cell 【深度踩坑】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天记录一下C#读取本地Excel并解析的基本流程与问题解决。

众嗦粥汁,Excel不管在业务处理还是测试数据导入等方面都非常有用,嗯。

我这边使用的是NPOI 2.5.3。

这里准备了两个版本,诸君各取所需。

2.5.3

https://download.csdn.net/download/qq_35139974/85011468

2.5.5

https://download.csdn.net/download/qq_35139974/85011473

接下来,先说问题。

(1)问题如下:

 

 Excel单元格中,单元格格式非常多,存储交叉又比较复杂,如果用文本存储了一个数值,然后用数值类型获取就会报错,如果用文本类型获取又需要做类型转换,你还不确定编辑Excel的用户给你设置了个什么单元格格式……

但是相对来说,我们是知道哪一列正确数值是什么格式的,所以可以在读取单元格数据之前先把它设置为该格式,然后再读取,就好了:

// 不仅限于String类型,Numeric类型等也是一样
row.GetCell(0).SetCellType(CellType.String);
if (row.GetCell(0).IsNullOrEmpty() || row.GetCell(0).StringCellValue.IsNullOrEmpty())
{throw new Exception("Excel解析异常:第" + (r + 1) + "行某属性为空");
}
string strValue = row.GetCell(0).StringCellValue;

这样,就解决了。

下面说详细读取流程,个人记录,仅供参考。

(2)直接上代码吧。

try
{string localPath = "本地完整绝对路径";// 打开工作簿IWorkbook workbook = WorkbookFactory.Create(localPath);if (workbook == null){throw new Exception("解析异常:Excel工作簿获取异常");}// 获取第一个工作表ISheet sheet = workbook.GetSheetAt(0);if (sheet == null){throw new Exception("解析异常:Excel默认工作表获取异常");}// 获取总行数int rowCount = sheet.LastRowNum;// 按行遍历for (int r = 0; r < rowCount; r++){// 获取行数据IRow row = sheet.GetRow(r);if (row == null){throw new Exception("解析异常:获取第" + (r + 1) + "行失败");}// 获取列数 可以对列进行数据校验int columnCount = row.LastCellNum;if (columnCount != 5){throw new Exception("解析异常:每行应该有5列,当前为" + columnCount + "列");}row.GetCell(0).SetCellType(CellType.String);if (row.GetCell(0).IsNullOrEmpty() || row.GetCell(0).StringCellValue.IsNullOrEmpty()){throw new Exception("解析异常:第" + (r + 1) + "行某属性为空");}string strValue = row.GetCell(0).StringCellValue;row.GetCell(1).SetCellType(CellType.Numeric);if (row.GetCell(1).IsNullOrEmpty() || row.GetCell(1).NumericCellValue.IsNullOrEmpty()){throw new Exception("解析异常:第" + (r + 1) + "行某属性为空");}double realValue = row.GetCell(1).NumericCellValue;}
}
catch (Exception e)
{throw new Exception("Excel 解析异常:" + e.Message);
}

(3)如果还是没有解决  Cannot get a xx value from a yy cell,我自己封装了一个方法,先把单元格中的数据转为string读出,然后根据自己的需求转为各种格式。下面,贴代码吧。

/// <summary>
/// 读取Row中Cell的值
/// </summary>
/// <param name="row">当前行数据</param>
/// <param name="columnIndex">读取当前行第几列(从0开始)</param>
/// <param name="expString">解析什么文件,执行什么操作。为抛出异常提供信息支持</param>
/// <param name="rowIndex">当前行为第几行(从0开始)。为抛出异常提供信息支持</param>
/// <param name="filedName">当前列表头。为抛出异常提供信息支持</param>
/// <param name="allowEmpty">是否允许为空,不允许为空时如果遇到空值会抛出异常</param>
/// <returns></returns>
private static string GetCellValueFromRow(IRow row, int columnIndex, string expString, int rowIndex, string filedName, bool allowEmpty)
{if (row.GetCell(columnIndex).IsNullOrEmpty()){if (!allowEmpty){throw new Exception(expString + "解析异常:第" + (rowIndex + 1) + "行" + filedName + "为空");}else{return "";}}return row.GetCell(columnIndex).ToString();
}

调用也很简单:

// 读取文本类型
string name = GetCellValueFromRow(row, 0, "用户信息", r, "姓名", false);
// 读取数值类型
double height = Convert.ToDouble(GetCellValueFromRow(row, 2, "用户信息", r, "身高", false));

好了,记录完毕。

Thanks♪(・ω・)ノ

这篇关于C# 读取本地Excel并解析 Cannot get a xx value from a yy cell 【深度踩坑】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/849246

相关文章

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工