通过POI获取公式列的值但不刷新仍是上一次值的解决方案

在做Excel导出是遇到一个问题,通过POI修改Excel的公式列后再次读取时数据不是最新修改值,奇怪的是在WPS保存后再次读取就可以读取到最新修改值了
使用的读取方法为

cell.getNumericCellValue()

这样读取到的数据为上一次的缓存值

经过改进使用重新计算公式的方法在读取时重新计算一下公式可以读到最新值,但我这里在循环执行时会报错,所以不可用

          FormulaEvaluator formulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
          CellType cellType = cell.getCellType();
          if (cellType.equals(CellType.FORMULA)) {
              String cellFormula = cell.getCellFormula();
              System.out.println(cellFormula);
              CellValue evaluate = formulaEvaluator.evaluate(cell);
              System.out.println(evaluate.formatAsString());
          }

问题分析

当xlsx表格被生成并在Excel程序中打开并保存之后(这个过程Excel会把公式结果计算出来),该文件附带有两套值,一套是公式全都没有计算的,一套是公式计算了结果的。
(如果没有被Excel打开并保存,则保存的值不会被重新计算,仍然是上次读取后缓存的值。
如想重新获得两套值,则仍旧需要用Excel程序打开该文件并保存。

解决方法

在Java代码中通过调用命令行的形式调用Python脚本或Linux命令打开Excel软件模拟手动保存动作

Runtime.getRuntime().exec(arguments)

1.Windows下:

可以使用Python安装win32com的第三方库,模拟一下手动打开在关闭Excel软件的操作,这样可以取到最新的值.
注意必须使用Microsoft Excel软件不能使用WPS

from win32com.client import Dispatch
def just_open(filename):
xlApp = Dispatch(“Excel.Application”)
xlApp.Visible = False
xlBook = xlApp.Workbooks.Open(filename)
xlBook.Save()
xlBook.Close()

2.Linux或Mac下:

由于Linux或Mac不同于windows系统所以无法使用Python第三方库win32com的解决方案。
我这里的解决方案是在服务器上安装:LibreOffice
这是一款开源的Office软件
用它来把代码生成的xlsx表在转化成xls或者将xls转换成xlsx,经过测试相当完成了一次打开保存关闭的操作,这样底层就会生成两套值了
这样就可以获取到最新值.

LibreOffice For Linux安装步骤

安装Libreoffice
1、查看当前yum支持当前Linux安装的LibreOffice版本

yum search libreoffic

2、查看libreoffice安装包基本信息

yum info libreoffice

3、安装libreoffice

yum install -y libreoffice

4.查看是否安装成功

libreoffice --version

5.进行一下文件转换操作,将xls转换为xlsx

libreoffice --headless --convert-to xlsx  要转换的文件路径 --outdir 输出目录

转换后发现缺失字体的可以安装一下Windows的字体包(自行搜索教程)

然后重启LibreOffice服务

kill -9 pid

执行

libreoffice

LibreOffice For Mac安装步骤

去官网下载对应mac版本的安装包 mac分为intel芯片版和M芯片版
向安装其他软件一样安装,安装完后打开软件,设置一下允许访问的文件夹
1进入到应用程序找到Libreoffice,右键查看包路径

/Applications/LibreOffice.app/Contents/MacOS

2.进入当前目录

cd /Applications/LibreOffice.app/Contents/MacOS

3.执行转换命令

./soffice  --headless --convert-to xlsx 目标文件路径 --outdir 输出目录
或
/Applications/LibreOffice.app/Contents/MacOS/soffice  --headless --convert-to xlsx 目标文件路径 --outdir 输出目录### LibreOffice For Linux安装步骤
转换后再次通过cell.getNumericCellValue()读取到的值就是修改后的最新值了
  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
POI库提供了计算公式的功能,可以通过公式器计算单元格中包含的公式的结果。下面是一个Java代码示例,可以使用POI库来获取公式计算后的: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.*; import org.apache.poi.xssf.usermodel.*; import java.io.File; import java.io.FileInputStream; public class PoiFormulaEvaluatorExample { public static void main(String[] args) throws Exception { // 读取Excel文件 File file = new File("example.xlsx"); FileInputStream inputStream = new FileInputStream(file); XSSFWorkbook workbook = new XSSFWorkbook(inputStream); XSSFSheet sheet = workbook.getSheetAt(0); // 获取第一行第一单元格 CellReference cellReference = new CellReference("A1"); XSSFRow row = sheet.getRow(cellReference.getRow()); XSSFCell cell = row.getCell(cellReference.getCol()); // 获取公式计算器 FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); // 计算公式的结果 CellValue cellValue = evaluator.evaluate(cell); // 获取计算后的 double value = cellValue.getNumberValue(); System.out.println("计算后的为: " + value); // 关闭Excel文件 workbook.close(); inputStream.close(); } } ``` 在这个例子中,我们假设我们要获取第一行第一单元格的。我们首先使用 `CellReference` 类来获取这个单元格的引用,然后使用 `XSSFRow` 和 `XSSFCell` 类获取这个单元格。接下来,我们使用 `XSSFWorkbook` 类读取Excel文件,并使用 `FormulaEvaluator` 获取公式计算器。最后,我们使用 `evaluate` 方法计算单元格中的公式的结果,并使用 `CellValue` 类获取计算后的。 请注意,上述代码仅适用于使用XSSF格式的Excel文件。如果您使用的是HSSF格式的Excel文件,则需要使用 `HSSFWorkbook` 和 `HSSFCell` 类来获取单元格,并使用 `HSSFFormulaEvaluator` 类获取公式计算器。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值