Npoi圆形配方

问题描述 投票:1回答:1

我是NPOI的新人,当我在项目上工作时我面临着奇怪的问题,并且不知道如何修复它我正在阅读来自Excel工作表的数据包含Round函数并使用npoi评估器XSSFFormulaEvaluator重新评估单元格,直到这一刻工作正常我没有问题,直到这个问题在excel表中我有这个公式=圆(693.9648; 2)excel这个数字的结果将是693.96但NPOI Evaluator的结果将是693.97

任何人都回答我如何使evaluter的行为像excel表一样?!

c# .net excel npoi
1个回答
1
投票

我几乎完全一样的问题。数字481.75478在Excel ROUND()函数中用于2dp。例如ROUND(481.75478, 2)

使用相同的工作簿执行此操作时:

  • Excel将评估为481.75
  • NPOI将评估为481.76

它似乎取决于NPOI在C#中实现Excel ROUND功能的方式。最后,我下载了NPOI库的源代码,将ROUND函数更改为使用标准.NET舍入(使用MidpointRounding.AwayFromZero作为我们的目的参数)并使用我的自定义DLL。

downloaded the source code并做了以下修改:

文件:\main\SS\Formula\Functions\MathX.cs

原始代码

    public static double Round(double n, int p)
    {
        double retval;

        if (double.IsNaN(n) || double.IsInfinity(n))
        {
            retval = double.NaN;
        }
        else if (double.MaxValue == n)
            return double.MaxValue;
        else if (double.MinValue == n)
            return 0;
        else
        {
            if (p >= 0)
            {
                int temp = (int)Math.Pow(10, p);
                double delta = 0.5;
                int x = p + 1;
                while (x > 0)
                {
                    delta = delta / 10;
                    x--;
                }
                retval = (double)(Math.Round((decimal)(n + delta) * temp) / temp);
            }
            else
            {
                int temp = (int)Math.Pow(10, Math.Abs(p));
                retval = (double)(Math.Round((decimal)(n) / temp) * temp);
            }
        }

        return retval;
    }

更新的代码

    public static double Round(double n, int p)
    {
        double retval;

        if (double.IsNaN(n) || double.IsInfinity(n))
        {
            retval = double.NaN;
        }
        else if (double.MaxValue == n)
            return double.MaxValue;
        else if (double.MinValue == n)
            return 0;
        else
        {
            if (p >= 0)
            {
                // ***** updated to use .NET MidpointRounding.AwayFromZero rounding ***** //
                retval = (double)Math.Round((decimal)n, p, MidpointRounding.AwayFromZero);
            }
            else
            {
                retval = (double)(Math.Round((decimal)(n) / temp) * temp);
            }
        }

        return retval;
    }

注意/免责声明

这尚未经过测试,因此可能会导致其他一些无法预料的错误(我不确定为什么原始代码会进行某种类型的deltafication),但这解决了我在Excel和NPOI之间舍入不同的问题。如果我在愤怒中使用该应用程序时发现任何问题,我会回来并更新答案。

更新2017-12-04

这已经有一段时间没有问题了。我也意识到我应该向项目which I now have提交PR。

© www.soinside.com 2019 - 2024. All rights reserved.