public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { double s0; String s1; try { s0 = TextFunction.EvaluateDoubleArg(arg0, srcRowIndex, srcColumnIndex); s1 = TextFunction.EvaluateStringArg(arg1, srcRowIndex, srcColumnIndex); } catch (EvaluationException e) { return e.GetErrorEval(); } if (Regex.Match(s1, "[y|m|M|d|s|h]+").Success) { //may be datetime string ValueEval result = TryParseDateTime(s0, s1); if (result != ErrorEval.VALUE_INVALID) return result; } //The regular expression needs ^ and $. if (Regex.Match(s1, @"^[\d,\#,\.,\$,\,]+$").Success) { //TODO: simulate DecimalFormat class in java. FormatBase formatter = new DecimalFormat(s1); return new StringEval(formatter.Format(s0)); } else if (s1.IndexOf("/", StringComparison.Ordinal) == s1.LastIndexOf("/", StringComparison.Ordinal) && s1.IndexOf("/", StringComparison.Ordinal) >= 0 && !s1.Contains("-")) { double wholePart = Math.Floor(s0); double decPart = s0 - wholePart; if (wholePart * decPart == 0) { return new StringEval("0"); } String[] parts = s1.Split(' '); String[] fractParts; if (parts.Length == 2) { fractParts = parts[1].Split('/'); } else { fractParts = s1.Split('/'); } if (fractParts.Length == 2) { double minVal = 1.0; double currDenom = Math.Pow(10, fractParts[1].Length) - 1d; double currNeum = 0; for (int i = (int)(Math.Pow(10, fractParts[1].Length) - 1d); i > 0; i--) { for (int i2 = (int)(Math.Pow(10, fractParts[1].Length) - 1d); i2 > 0; i2--) { if (minVal >= Math.Abs((double)i2 / (double)i - decPart)) { currDenom = i; currNeum = i2; minVal = Math.Abs((double)i2 / (double)i - decPart); } } } FormatBase neumFormatter = new DecimalFormat(fractParts[0]); FormatBase denomFormatter = new DecimalFormat(fractParts[1]); if (parts.Length == 2) { FormatBase wholeFormatter = new DecimalFormat(parts[0]); String result = wholeFormatter.Format(wholePart) + " " + neumFormatter.Format(currNeum) + "/" + denomFormatter.Format(currDenom); return new StringEval(result); } else { String result = neumFormatter.Format(currNeum + (currDenom * wholePart)) + "/" + denomFormatter.Format(currDenom); return new StringEval(result); } } else { return ErrorEval.VALUE_INVALID; } } else { return TryParseDateTime(s0, s1); } }
/// <summary> /// Formats a number or date cell, be that a real number, or the /// answer to a formula /// </summary> /// <param name="cell">The cell.</param> /// <param name="value">The value.</param> /// <returns></returns> private String FormatNumberDateCell(CellValueRecordInterface cell, double value) { // Get the built in format, if there is one int formatIndex = ft.GetFormatIndex(cell); String formatString = ft.GetFormatString(cell); if (formatString == null) { return value.ToString(CultureInfo.InvariantCulture); } else { // Is it a date? if (Zephyr.Utils.NPOI.SS.UserModel.DateUtil.IsADateFormat(formatIndex, formatString) && Zephyr.Utils.NPOI.SS.UserModel.DateUtil.IsValidExcelDate(value)) { // Java wants M not m for month formatString = formatString.Replace('m', 'M'); // Change \- into -, if it's there formatString = formatString.Replace("\\\\-", "-"); // Format as a date DateTime d = Zephyr.Utils.NPOI.SS.UserModel.DateUtil.GetJavaDate(value, false); SimpleDateFormat df = new SimpleDateFormat(formatString); return df.Format(d); } else { if (formatString == "General") { // Some sort of wierd default return value.ToString(CultureInfo.InvariantCulture); } // Format as a number DecimalFormat df = new DecimalFormat(formatString); return df.Format(value); } } }