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


    场景

    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切入(之所以不一致可能也是上述原因)。我这种是我想到最快的解决方法,欢迎批评指正。

  • 相关阅读:
    ☆☆如何学习MATLAB☆☆
    在conda虚拟环境下安装PyTorch-gpu版本
    RabbitMQ的介绍
    Apache DolphinScheduler & 亚马逊云科技联合Meetup: 基于云上的最佳实践
    Selenium元素定位方法总结
    Nanoprobes金脂质偶联物的相关应用
    Cppcheck 详细介绍
    化学实验室大型仪器设备管理系统
    PAT甲级 1020 Tree Traversals
    拓扑排序及其衍生
  • 原文地址:https://blog.csdn.net/qq_37160010/article/details/125625985