通过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()读取到的值就是修改后的最新值了

你可能感兴趣的:(java)