利用POI 解决Aspose excel转pdf四舍五入精度丢失问题

6 篇文章 0 订阅
4 篇文章 0 订阅

场景

excel转换pdf后源数据和对应数据不一致
在这里插入图片描述
在这里插入图片描述

排查过程

  1. 查看excel源文件单元格发现当前格式为公式计算后的结果=F19*B19

在这里插入图片描述

  1. 用计算器计算结果217512.275 发现两个结果都是错的

在这里插入图片描述

  1. 再次查看源文件发现单元格格式为货币类型且保留两位小数

在这里插入图片描述

  1. 大概猜出原因,excel源文件保留两位小数 采用四舍五入的形式 所以结果US$217,512.28 ,而转换时没有四舍五入所以结果US$217,512.27

尝试解决

  1. 大概判断原因是单元格计算导致结果与转换后的结果不一致
  2. 思路大概是在转换前把源文件中的计算公式替换成结果(提前一步在代码中计算)
  3. 由于Aspose代码不是开源的且加密过,对应的操作方法也不好找。最终决定用poi操作excel完成数据转换
  4. 查询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);错误值

于是这样写
在这里插入图片描述

  1. 之后换成手动获取转换格式 发现计算结果仍是错误的

在这里插入图片描述

  1. 随即获取单元格的格式然后针对不四舍五入的情况做处理
    在这里插入图片描述

取整模式
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)

  1. 只能更换poi支持的转换方式
    在这里插入图片描述

  2. 为了寻找poi方法在哪个地方设置取整方法跟随断点查看源码 发现针对四舍五入已经做了处理

在这里插入图片描述
在这里插入图片描述

  1. 继续跟踪断点发现是因为他在格式化时用double取值导致精度丢失(源码中也只针对BigDecimal做了四舍五入)217512.275---->217512.2749999999999999

精度丢失参考 :https://www.zhihu.com/question/42024389

  1. 所以最后的处理是取到值后转换为BigDecimal 再让其格式化,然后用格式化后的字符串替换掉源文件中的数据。
    在这里插入图片描述

修改后的结果完美展示
在这里插入图片描述

大概率还有其他方法来达到这种效果,比如从Aspose切入(之所以不一致可能也是上述原因)。我这种是我想到最快的解决方法,欢迎批评指正。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值