我是NPOI的新人,当我在项目上工作时我面临着奇怪的问题,并且不知道如何修复它我正在阅读来自Excel工作表的数据包含Round函数并使用npoi评估器XSSFFormulaEvaluator重新评估单元格,直到这一刻工作正常我没有问题,直到这个问题在excel表中我有这个公式=圆(693.9648; 2)excel这个数字的结果将是693.96但NPOI Evaluator的结果将是693.97
任何人都回答我如何使evaluter的行为像excel表一样?!
我几乎完全一样的问题。数字481.75478在Excel ROUND()
函数中用于2dp。例如ROUND(481.75478, 2)
使用相同的工作簿执行此操作时:
它似乎取决于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。