场景
excel转换pdf后源数据和对应数据不一致
排查过程
- 查看excel源文件单元格发现当前格式为公式计算后的结果=F19*B19
- 用计算器计算结果217512.275 发现两个结果都是错的
- 再次查看源文件发现单元格格式为货币类型且保留两位小数
- 大概猜出原因,excel源文件保留两位小数 采用四舍五入的形式 所以结果US$217,512.28 ,而转换时没有四舍五入所以结果US$217,512.27
尝试解决
- 大概判断原因是单元格计算导致结果与转换后的结果不一致
- 思路大概是在转换前把源文件中的计算公式替换成结果(提前一步在代码中计算)
- 由于Aspose代码不是开源的且加密过,对应的操作方法也不好找。最终决定用poi操作excel完成数据转换
- 查询poi Cell中的方法发现 ,有专门用来判断类型方法,以及计算后判断类型的方法
方法 | 描述 | 相关枚举 |
---|---|---|
getCellType() | 获取单元格的格式 | _NONE(-1), 无类型 NUMERIC(0), 数值 STRING(1), 字符串 FORMULA(2), 公式 BLANK(3),空 BOOLEAN(4),布尔值 ERROR(5);错误值 |
getCachedFormulaResultType() | 获取公式计算出的结果的类型 | _NONE(-1), 无类型 NUMERIC(0), 数值 STRING(1), 字符串 FORMULA(2), 公式 BLANK(3),空 BOOLEAN(4),布尔值 ERROR(5);错误值 |
于是这样写
- 之后换成手动获取转换格式 发现计算结果仍是错误的
- 随即获取单元格的格式然后针对不四舍五入的情况做处理
取整模式
ROUND_CEILING: 舍位时往正无穷方向移动 1.1->2 1.5->2 1.8->2 -1.1->-1 -1.5->-1 -1.8->-1
ROUND_DOWN:向0的方向移动1.1->1 1.5->1 1.8->1 -1.1->-1 -1.5->-1 -1.8>-1
ROUND_FLOOR:与CEILING相反,往负无穷 1.1->1 1.5->1 1.8->1 -1.1->-2 -1.5->-2 -1.8->-2
ROUND_HALF_DOWN:以5为分界线,或五舍六入1.5->1 1.6->1 -1.5->-1 -1.6->-2 1.15->1.1 1.16->1.2 1.55->1.6 1.56->1.6
ROUND_HALF_EVEN:同样以5为分界线,如果是5,则前一位变偶数1.15->1.2 1.16->1.2 1.25->1.2 1.26->1.3
ROUND_HALF_UP:最常见的四舍五入
ROUND_UNNECESSARY:无需舍位
ROUND_UP:与ROUND_DOWN,远离0的方向1.1->2 1.5->2 1.8->2 -1.1->-2 -1.5->-2 -1.8->-2
最后发现结果是对的 但是格式出现问题。
后来查询资料 NumberFormat格式转换和excel的格式不匹配"USKaTeX parse error: Expected 'EOF', got '#' at position 2: "#̲,##0.00_);[Red]…"#,##0.00)
-
只能更换poi支持的转换方式
-
为了寻找poi方法在哪个地方设置取整方法跟随断点查看源码 发现针对四舍五入已经做了处理
- 继续跟踪断点发现是因为他在格式化时用double取值导致精度丢失(源码中也只针对BigDecimal做了四舍五入)217512.275---->217512.2749999999999999
- 所以最后的处理是取到值后转换为BigDecimal 再让其格式化,然后用格式化后的字符串替换掉源文件中的数据。
修改后的结果完美展示