POI/Excel/HTML单元格公式问题
一、问题描述
使用MyBatis从数据库中获取数据,然后用POI把数据填充到Excel模板中,生成最终的xls文件。把最终的xls文件转换为html文件,并返回给前台显示在Panel中。
Excel模板中,除了数据点位符外,还有一些计算公式。由于这些计算公式引用的数据在模板中是点位符,所以计算单元显示为“#VALUE!”。见下图:

生成Excel文件,在添加了重算的相关代码(见下文)后,计算单元格的值能够正常显示。转换为html后,这些计算单元格不会重新计算,仍然显示为“#VALUE!”。
二、问题分析
这个问题一直存在了两周左右,期间断断续续地花了一些时间研究,但问题没有得到解决。
这种使用第三方组件导致的问题,排查起来比较困难。在网上搜索了一大圈,没有发现对类似问题的描述。有一些关于使用POI重新计算Excel单元格公式的内容可参考。
下载了POI 3.11相关的源代码,在本机架设了测试环境,进行跟踪调试。发现是ExcelToHtmlConverter类中,在获取含有公式的单元格的CachedFormulaResultType时,总是返回Cell.CELL_TYPE_ERROR,导致该方法只能通过cell.getErrorCellValue()获取单元格的值(就是#VALUE!)并返回。

看了一下相关的源代码,POI把_record等属性设置为private,调用时无法修改。又在网上搜索了一番,更加没有什么有参考价值的信息。
三、问题解决
在用Excel打开并关闭填充数据后生成的xls文件时,Excel总是会提示是否要保存,但实际上没有进行任何的修改。如果“保存”这个模板,再生成html,单元格公式会计算,显示正常。总是感觉POI生成的xls文件实际上还是有兼容性问题,但MS在Office2007以前并没有开发相关文件的格式及说明,所以也怪不到POI。
生成Excel后,重新对公式单元格进行计算:

【仅仅setForceFormulaRecalculation(Boolean.TRUE)在转换为html时是无效的】
正式工程和一开始的测试代码中,取数生成Excel、转换为html是写在一个function中的。在测试中感觉不是太方便。于是就把生个Excel、转为html拆分为两个function,以便于控制是否重新生成Excel。没想到拆分完一运行测试代码,html中的计算单元竟然有值了!简直是简直了!
然后把正式工程中的代码也拆分了一下,这个让人抓狂的问题,就以这种无厘头的方式解决了。
四、问题总结
在同一个方法里进行生成xls文件、转换为html有问题,拆分为两个方法后就没有问题。这种现象是比较怪异的,应该还是代码层面存在问题。暂时就不再深究了。
POI/Excel/HTML单元格公式问题的更多相关文章
- 如何隐藏Excel中单元格公式且其他单元格可修改
需求:1.隐藏指定单元格公式.2.非公式单元格可修改,不影响公式计算. 操作步骤:1.全选工作表.右键.单元格格式.保护.锁定勾选取消. 2.编辑.定位(或按F5弹出该对话框).定位条件.公式(勾选) ...
- poi excel 合并单元格
结论:final CellRangeAddress cra = new CellRangeAddress(rowId, rowId + rowSkip, colId, colId + c ...
- POI按照源单元格设置目标单元格格式
原文:http://jjw198874.blog.163.com/blog/static/1889845522011102401854234/ POI按照源单元格设置目标单元格格式 poi按照一个源单 ...
- POI设置excle单元格样式
Java利用POI生成Excel强制换行 使用POI创建一个简单的 myXls.xls 文件 常用的包为 org.apache.poi.hssf.usermodel.*; ...
- poi读取合并单元格
poi读取合并单元格 学习了:http://blog.csdn.net/ycb1689/article/details/9764191 进行了列合并单元格的修正:原来是我自己找错了地方: import ...
- [从产品角度学EXCEL 03]-单元格的秘密
这是<从产品角度学EXCEL>系列——单元格的秘密. 前言请看: 0 为什么要关注EXCEL的本质 1 EXCEL是怎样运作的 2 EXCEL里的树形结构 或者你可以去微信公众号@尾巴说数 ...
- EXCEL表格单元格中包含数字英文和汉字,如何自动去掉汉字,保留英文和数字
EXCEL表格单元格中包含数字英文和汉字,如何自动去掉汉字,保留英文和数字 Function 求数字和字母(对象 As String) '在文本与数字混杂中提取数字和字母 Dim myReg ...
- python读取excel中单元格的内容返回的5种类型
(1) 读取单个sheetname的内容. 此部分转自:https://www.cnblogs.com/xxiong1031/p/7069006.html python读取excel中单元格的内容返回 ...
- asp.net C#取Excel 合并单元格内容
asp教程.net c#取excel 合并单元格内容读取excel数据,填充dataset// 连接字符串 string xlspath = server.mappath("~/www.11 ...
随机推荐
- JS设计模式(三) 数据访问对象模式
引言 HTML5 提供了两种在客户端存储数据的新方法:localStorage.sessionStorage,他们是Web Storage API 提供的两种存储机制,区别在于前者属于永久性存储,而后 ...
- JAVA 反射(1)
getDeclaredField是可以获取一个类的所有字段. getField只能获取类的public 字段.
- ssh (免密码登录、开启服务)
ssh 无密码登录要使用公钥与私钥.linux下可以用用ssh-keygen生成公钥/私钥对,下面我以Unbutun为例.有机器A(192.168.1.155),B(192.168.1.181).现想 ...
- Maximum repetition substring (poj3693 后缀数组求重复次数最多的连续重复子串)
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6328 Acc ...
- #云栖大会# 移动安全专场——APP加固新方向(演讲速记)
主持人导语: 近些年来,移动APP数量呈现爆炸式的增长,黑产也从原来的PC端转移到了移动端,伴随而来的逆向攻击手段也越来越高明.在解决加固产品容易被脱壳的方案中,代码混淆技术是对抗逆向攻击最有效的方式 ...
- Echarts数据可视化polar极坐标系,开发全解+完美注释
全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...
- 根据Dockerfile创建docker dotnet coer 镜像
那我们先来看看Dockerfile文件内容,注意这个文件是没后缀名的. #依赖原始的镜像,因为我们是要创建dotnet coer镜像,所以我就用了官方给的镜像[microsoft/dotnet:lat ...
- 对象反序列化时,抛出java.io.StreamCorruptedException: invalid type code: AC异常
问题描述:在使用java.io.ObjectInputStream类的readObject()方法去读取包含有序列化了多个(两个及两个以上)类的文件时,当读取到第二个类时,会抛出题目中提到的异常. 原 ...
- Java可变参数以及一个简单应用
可变参数: Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理. 注意:可变参数必须位于最后一项. 原因:当可变参数个数多余一个时,必将有一个不 ...
- ASP.NET Core 认证与授权[3]:OAuth & OpenID Connect认证
在上一章中,我们了解到,Cookie认证是一种本地认证方式,通常认证与授权都在同一个服务中,也可以使用Cookie共享的方式分开部署,但局限性较大,而如今随着微服务的流行,更加偏向于将以前的单体应用拆 ...