【探讨】Java POI 处理 Excel 中的名称管理器

前言

最近遇到了一些导表的问题。原本的导表工具导不了使用名称管理器的Excel。
首先我们有两个Sheet。B1用的是名称管理器中的AAA, 而B2用的对应的公式。
在这里插入图片描述
在这里插入图片描述
第二个sheet,名为Test2:
在这里插入图片描述

这是一段简化的代码:

public class Main {public static void main(String[] args) {var inputFile = new File("src/main/java/poi/test.xlsx");var dataFormatter = new DataFormatter();try (var wb = new XSSFWorkbook(new FileInputStream(inputFile))) {wb.setForceFormulaRecalculation(true);var sheet = wb.getSheet("Test");var formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {var row = sheet.getRow(i);var list = new ArrayList<String>();for (var cell : row) {list.add(format(dataFormatter, formulaEvaluator, cell));}System.out.println(String.join(", ", list));}} catch (IOException e) {throw new RuntimeException(e);}}public static String format(DataFormatter dataFormatter, XSSFFormulaEvaluator formulaEvaluator, Cell cell) {return dataFormatter.formatCellValue(cell, formulaEvaluator);}
}

控制台的输出为:

1, #N/A
2, b

这意味着无法解析这个命名统计后的值。

为啥公式可以执行。但是从名称管理器拿不到?是否可以通过拿名称对应的公式来计算出相应的结果?

通过修改formatter:

    public static String format(DataFormatter dataFormatter, XSSFFormulaEvaluator formulaEvaluator, Cell cell) {if (cell.getCellType() == CellType.FORMULA) {System.out.println("Formula: " + cell.getCellFormula());System.out.println("RichString: " + cell.getRichStringCellValue().getString());System.out.println("Cache result type: " + cell.getCachedFormulaResultType());}return dataFormatter.formatCellValue(cell, formulaEvaluator);}

我们可以得到输出:

Formula: AAA
RichString: a
Cache result type: STRING
1, #N/A
---------------------------------------
Formula: VLOOKUP(A2,Test2!$A$1:$B$5,2)
RichString: b
Cache result type: STRING
2, b
---------------------------------------

这么看来RichString可以拿到我们想要的值。
但是当我把Sheet2中对应的值改为数字:
在这里插入图片描述

得到的一个保存的结果:

Formula: AAA
Exception in thread "main" java.lang.IllegalStateException: Cannot get a STRING value from a NUMERIC formula cellat org.apache.poi.xssf.usermodel.XSSFCell.typeMismatch(XSSFCell.java:946)at org.apache.poi.xssf.usermodel.XSSFCell.getRichStringCellValue(XSSFCell.java:330)at org.apache.poi.xssf.usermodel.XSSFCell.getRichStringCellValue(XSSFCell.java:77)at poi.Main.format(Main.java:43)at poi.Main.main(Main.java:29)

这里我想拿到一个可以区分是Name还是Formula的属性。但是我看了下从cell的方法好像没办法拿到。

一个解决方案

package poi;import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;public class Main {public static void main(String[] args) {var inputFile = new File("src/main/java/poi/test.xlsx");var dataFormatter = new DataFormatter();try (var wb = new XSSFWorkbook(new FileInputStream(inputFile))) {wb.setForceFormulaRecalculation(true);var sheet = wb.getSheet("Test");var formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {var row = sheet.getRow(i);var list = new ArrayList<String>();for (var cell : row) {list.add(format(dataFormatter, formulaEvaluator, cell));}System.out.println(String.join(", ", list));System.out.println("---------------------------------------");}} catch (IOException e) {throw new RuntimeException(e);}}public static String format(DataFormatter dataFormatter, XSSFFormulaEvaluator formulaEvaluator, Cell cell) {if (cell.getCellType() == CellType.FORMULA) {System.out.println("Formula: " + cell.getCellFormula());System.out.println("Cache result type: " + cell.getCachedFormulaResultType());if (cell.getCachedFormulaResultType() == CellType.STRING) {return cell.getRichStringCellValue().getString();} else {return String.valueOf(cell.getNumericCellValue());}}return dataFormatter.formatCellValue(cell, formulaEvaluator);}
}

执行后得到结果:

Formula: AAA
Cache result type: NUMERIC
1, 1.0
---------------------------------------
Formula: VLOOKUP(A2,Test2!$A$1:$B$5,2)
Cache result type: NUMERIC
2, 2.0
---------------------------------------

这样结果勉强可以用,但是感觉上这段代码是有BUG的,但是对POI的了解不是太透,本文相当于抛砖引玉,如果有懂的可以探讨下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.25 Qt

制作一个登陆界面 login.pro文件 QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on …

【Spring】更简单的读取和存储对象,五大类注解

经过前面的学习&#xff0c;我们已经可以实现基本的 Spring 读取和存储对象的操作了&#xff0c;但在操作的过程中我们发现读取和存储对象并没有想象中的那么 “简单”&#xff0c;所以接下来我们要学习更加简单的操作 Bean 对象的方法 在 Spring 中想要更简单的存储和读取对象…

【Linux】带你深入理解文件系统

目录 文件系统 背景知识 磁盘结构 磁盘的存储结构 磁盘抽象(逻辑&#xff0c;虚拟)结构 BootBlock&#xff1a; Super block Data blocks inode Table BlcokBitmap inode Bitmap Group Descriptor Table 文件名和inode编号 硬链接和软链接 软链接 硬链接 取消…

RocketMQ第一课-快速实战以及集群架构搭建

一、RocketMQ产品特点 1、RocketMQ介绍 ​ RocketMQ是阿里巴巴开源的一个消息中间件&#xff0c;在阿里内部历经了双十一等很多高并发场景的考验&#xff0c;能够处理亿万级别的消息。2016年开源后捐赠给Apache&#xff0c;现在是Apache的一个顶级项目。 ​ 早期阿里使用Act…

设计模式行为型——责任链模式

目录 什么是责任链模式 责任链模式的实现 责任链模式角色 责任链模式类图 责任链模式举例 责任链模式代码实现 责任链模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是责任链模式 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;又叫职…

【C语言项目】多臂井径电子测井成像项目(一)

目录 1、目的和意义2、本章概述3、串口R2324、OpenGL5、开发环境6、环境配置6.1、VS安装OpenGL6.2、虚拟串口生成工具 7、成品速览参考文献 1、目的和意义 本项目为获取矿藏地层的油气当量和及时精确地测量含油、含气层的压力及温度值的需求&#xff0c;辅助生产管理人员完成对…

警惕!通过谷歌和必应搜索广告传播的新型恶意活动

据观察&#xff0c;一种新的恶意广告活动利用谷歌搜索和必应的广告&#xff0c;以AnyDesk、Cisco AnyConnect VPN和WinSCP等IT工具的用户为目标&#xff0c;诱骗他们下载木马安装程序&#xff0c;目的是入侵企业网络&#xff0c;并可能在未来实施勒索软件攻击。 Sophos在周三的…

最快桌面UI:Siticone Desktop UI 2.1.1 cRACK

富图尔主义控制 80 多个 .NET UI 组件和控件 现代未来 UI/UX 组件 为 Visual Studio 开发做好准备 无限的免费产品支持案例 超轻量和快速性能 广泛可定制和主题化 低资源消耗和占地面积 免版税开发和部署 NET 的最佳 UI 和 UX 库 从最好的图书馆探索无缝流畅的体验 使…

30-使用RocketMQ做削峰处理

1、增加排队功能的思路 在出票模块里,一个消费者拿到了某个车次锁,则该车次下所有的票都由他来出,一张一张的出,知道所有的订单都出完。 2、实现排队出票功能 2.1、 修改发送到MQ消息的内容 修改MQ消息内容,只需要通知出哪天和哪个车次的票(即:组成锁的内容),不需要…

【时频分析,非线性中频】非线性STFT在瞬时频率估计中的应用(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

MATLAB与ROS联合仿真——实例程序搭建思路

一、基础运动控制实例程序搭建思路 1、需要完成的任务&#xff1a; &#xff08;1&#xff09;通过设定小车运动的速度及转角来控制ROS中小车运动。 &#xff08;2&#xff09;通过键盘输入指令控制ROS中小车运动&#xff0c;键盘输入w小车前行&#xff0c;s小车后退&#x…

uniapp 选择城市定位 根据城市首字母分类排序

获取城市首字母排序&#xff0c;按字母顺序排序 <template><view class"address-wrap" id"address"><!-- 搜索输入框-end --><template v-if"!isSearch"><!-- 城市列表-start --><view class"address-sc…

idea 关闭页面右侧预览框/预览条

idea 关闭页面右侧预览框 如图&#xff0c;预览框存在想去除 找了好多方法&#xff0c;什么去掉“setting->appearance里的show editor preview tooltips”的对钩&#xff1b;又或者在该预览区的滚动条上右键&#xff0c;“取消勾选show code lens on scrollbar hover”。都…

《向量数据库指南》——Milvus Cloud2.2.12 易用性,可视化,自动化大幅提升

Milvus Cloud又迎版本升级,三大新特性全力加持,易用性再上新台阶! 近期,Milvus Cloud上线了 2.2.12 版本,此次更新不仅一次性增加了支持 Restful API、召回原始向量、json_contains 函数这三大特性,还优化了 standalone 模式下的 CPU 使用、查询链路等性能,用一句话总…

【MySQL】centos 7下MySQL的环境搭建

从本期博客开始我们正式进入到数据库的学习&#xff0c;在学习数据库时所用到的工具是Linux环境下的MySQL 目录 一、检查环境中是否装有MySQL 二、获取MySQL官方yum源 三、配置MySQL官方yum源 四、一键安装MySQL 五、启动mysql服务 六、登录MySQL 七、修改mysql配置文件…

JS正则表达式:常用正则手册/RegExp/正则积累

一、正则基础语法 JavaScript 正则表达式 | 菜鸟教程 JS正则表达式语法大全&#xff08;非常详细&#xff09; 二、使用场景 2.1、校验中国大陆手机号的正则表达式 正则 /^1[3456789]\d{9}$/解释 序号正则解释1^1以数字 1 开头2[3456789]第二位可以是 3、4、5、6、7、8、…

cnn卷积神经网络(基础)

convolutional neural networks 特征提取&#xff08;卷积、下采样&#xff09;->分类器 &#xff08;全连接&#xff09; 卷积过程 依次进行数乘 &#xff08;每个相同位置上的数字相乘再加和&#xff09; 左右数乘矩阵channel数量要一样&#xff0c;输出得到一个通道 卷…

RabbitMQ 教程 | RabbitMQ 入门

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

动态线程池问题的解决

项目中需要将线程池也监控管理起来。 于是决定引入了hippo4j&#xff0c;这个引入很简单&#xff0c;官方的例子也很简单&#xff0c;拿过来直接跑。 出现问题了&#xff0c;用的和例子一模一样的&#xff0c;也没什么错&#xff0c;但是就是在服务器的管理控制台上没有找到动态…

Flutter 状态组件 InheritedWidget

Flutter 状态组件 InheritedWidget 视频 前言 今天会讲下 inheritedWidget 组件&#xff0c;InheritedWidget 是 Flutter 中非常重要和强大的一种 Widget&#xff0c;它可以使 Widget 树中的祖先 Widget 共享数据给它们的后代 Widget&#xff0c;从而简化了状态管理和数据传递…