diff --git a/src/EPPlus/FormulaParsing/EpplusExcelDataProvider.cs b/src/EPPlus/FormulaParsing/EpplusExcelDataProvider.cs
index 922835df62..c51ca54c19 100644
--- a/src/EPPlus/FormulaParsing/EpplusExcelDataProvider.cs
+++ b/src/EPPlus/FormulaParsing/EpplusExcelDataProvider.cs
@@ -24,6 +24,7 @@ Date Author Change
using OfficeOpenXml.FormulaParsing.Ranges;
using System.Runtime.InteropServices;
using OfficeOpenXml.Utils.String;
+using OfficeOpenXml.Style;
namespace OfficeOpenXml.FormulaParsing
{
@@ -641,7 +642,21 @@ public override string GetFormat(object value, string format, out bool isValidFo
{
isValidFormat = true;
var ws = _currentWorksheet ?? _context.CurrentWorksheet;
- var arg = new NumberFormatToTextArgs(ws, _context.CurrentCell.Row, _context.CurrentCell.Column, value, ws.GetStyleInner(_context.CurrentCell.Row, _context.CurrentCell.Column));
+
+ var existingId = ExcelNumberFormat.GetFromBuildIdFromFormat(format);
+
+ NumberFormatToTextArgs arg;
+ if (existingId == int.MinValue)
+ {
+ //The format does not have a corresponding styleId
+ //Still allow the NumberFormatToTextHandler to see the format
+ arg = new NumberFormatToTextArgs(ws, _context.CurrentCell.Row, _context.CurrentCell.Column, value, format);
+ }
+ else
+ {
+ arg = new NumberFormatToTextArgs(ws, _context.CurrentCell.Row, _context.CurrentCell.Column, value, existingId);
+ }
+ arg.FromFormula = true;
return _workbook.NumberFormatToTextHandler(arg);
}
}
diff --git a/src/EPPlus/NumberFormatToTextArgs.cs b/src/EPPlus/NumberFormatToTextArgs.cs
index a4a3ec55d7..1bbfbe8b66 100644
--- a/src/EPPlus/NumberFormatToTextArgs.cs
+++ b/src/EPPlus/NumberFormatToTextArgs.cs
@@ -12,6 +12,7 @@ Date Author Change
*************************************************************************************************/
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using OfficeOpenXml.Style;
+using OfficeOpenXml.Style.Interfaces;
using OfficeOpenXml.Style.XmlAccess;
using OfficeOpenXml.Utils.String;
@@ -23,6 +24,32 @@ namespace OfficeOpenXml
public class NumberFormatToTextArgs
{
internal int _styleId;
+
+ ExcelNumberFormatWithoutId fallbackNumberFormat = null;
+
+ ///
+ /// If these args are provided from a formula
+ ///
+ public bool FromFormula = false;
+
+ ///
+ /// Constructor when numberformat is not built in
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal NumberFormatToTextArgs(ExcelWorksheet ws, int row, int column, object value, string numberFormat)
+ {
+ Worksheet = ws;
+ Row = row;
+ Column = column;
+ Value = value;
+ _styleId = -1;
+ fallbackNumberFormat = new ExcelNumberFormatWithoutId(numberFormat);
+ }
+
internal NumberFormatToTextArgs(ExcelWorksheet ws, int row, int column, object value, int styleId)
{
Worksheet = ws;
@@ -31,6 +58,7 @@ internal NumberFormatToTextArgs(ExcelWorksheet ws, int row, int column, object v
Value = value;
_styleId = styleId;
}
+
///
/// The worksheet of the cell.
///
@@ -46,11 +74,18 @@ internal NumberFormatToTextArgs(ExcelWorksheet ws, int row, int column, object v
///
/// The number format settings for the cell
///
- public ExcelNumberFormatXml NumberFormat
+ public IExcelNumberFormat NumberFormat
{
get
{
- return ValueToTextHandler.GetNumberFormat(_styleId, Worksheet.Workbook.Styles);
+ if(fallbackNumberFormat != null)
+ {
+ return fallbackNumberFormat;
+ }
+ else
+ {
+ return ValueToTextHandler.GetNumberFormat(_styleId, Worksheet.Workbook.Styles);
+ }
}
}
///
@@ -64,6 +99,13 @@ public string Text
{
get
{
+ if(fallbackNumberFormat != null)
+ {
+ var ft = new ExcelFormatTranslator(NumberFormat.Format, -1);
+ bool isValidFormat = false;
+ var frmt = ValueToTextHandler.FormatValue(Value, false, ft, null, out isValidFormat);
+ return frmt;
+ }
return ValueToTextHandler.GetFormattedText(Value, Worksheet.Workbook, _styleId, false);
}
}
diff --git a/src/EPPlus/Style/Interfaces/IExcelNumberFormat.cs b/src/EPPlus/Style/Interfaces/IExcelNumberFormat.cs
new file mode 100644
index 0000000000..594b8b05aa
--- /dev/null
+++ b/src/EPPlus/Style/Interfaces/IExcelNumberFormat.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OfficeOpenXml.Style.Interfaces
+{
+ public interface IExcelNumberFormat
+ {
+ ///
+ /// The numberformat string
+ ///
+ public string Format { get; }
+ ///
+ /// Number format Id
+ ///
+ public int NumFmtId { get; }
+ ///
+ /// If this numberformat is built in
+ ///
+ public bool BuildIn { get; }
+ }
+}
diff --git a/src/EPPlus/Style/XmlAccess/ExcelNumberFormatWithoutId.cs b/src/EPPlus/Style/XmlAccess/ExcelNumberFormatWithoutId.cs
new file mode 100644
index 0000000000..9b953ad1f6
--- /dev/null
+++ b/src/EPPlus/Style/XmlAccess/ExcelNumberFormatWithoutId.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OfficeOpenXml.Style.Interfaces;
+
+namespace OfficeOpenXml.Style.XmlAccess
+{
+ internal class ExcelNumberFormatWithoutId : IExcelNumberFormat
+ {
+ internal ExcelNumberFormatWithoutId(string format)
+ {
+ Format = format;
+ NumFmtId = -1;
+ BuildIn = false;
+ }
+ public string Format { get; private set; }
+
+ public int NumFmtId { get; private set; }
+
+ public bool BuildIn { get; private set; }
+ }
+}
diff --git a/src/EPPlus/Style/XmlAccess/ExcelNumberFormatXml.cs b/src/EPPlus/Style/XmlAccess/ExcelNumberFormatXml.cs
index 7b6c4a6653..a0c0eb650e 100644
--- a/src/EPPlus/Style/XmlAccess/ExcelNumberFormatXml.cs
+++ b/src/EPPlus/Style/XmlAccess/ExcelNumberFormatXml.cs
@@ -10,22 +10,23 @@ Date Author Change
*************************************************************************************************
01/27/2020 EPPlus Software AB Initial release EPPlus 5
*************************************************************************************************/
+using OfficeOpenXml.Style.Interfaces;
+using OfficeOpenXml.Utils;
using System;
using System.Collections.Generic;
-using System.Text;
-using System.Xml;
using System.Globalization;
-using System.Text.RegularExpressions;
-using OfficeOpenXml.Utils;
-using System.Runtime.InteropServices;
using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Xml;
namespace OfficeOpenXml.Style.XmlAccess
{
///
/// Xml access class for number customFormats
///
- public sealed class ExcelNumberFormatXml : StyleXmlHelper
+ public sealed class ExcelNumberFormatXml : StyleXmlHelper, IExcelNumberFormat
{
internal ExcelNumberFormatXml(XmlNamespaceManager nameSpaceManager) : base(nameSpaceManager)
diff --git a/src/EPPlusTest/Drawing/Chart/ChartSeriesTest.cs b/src/EPPlusTest/Drawing/Chart/ChartSeriesTest.cs
index 353a22c52a..f6cea68a87 100644
--- a/src/EPPlusTest/Drawing/Chart/ChartSeriesTest.cs
+++ b/src/EPPlusTest/Drawing/Chart/ChartSeriesTest.cs
@@ -1,14 +1,22 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Castle.Components.DictionaryAdapter.Xml;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Newtonsoft.Json;
using OfficeOpenXml;
+using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.Drawing;
using OfficeOpenXml.Drawing.Chart;
using OfficeOpenXml.Drawing.Chart.ChartEx;
+using OfficeOpenXml.Drawing.Interfaces;
+using OfficeOpenXml.FormulaParsing.Utilities;
+using OfficeOpenXml.Style;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
+using System.Xml;
namespace EPPlusTest.Drawing.Chart
{
diff --git a/src/EPPlusTest/Issues/StylingIssues.cs b/src/EPPlusTest/Issues/StylingIssues.cs
index 6d0fa4bde0..1082c31630 100644
--- a/src/EPPlusTest/Issues/StylingIssues.cs
+++ b/src/EPPlusTest/Issues/StylingIssues.cs
@@ -8,6 +8,8 @@
using System.IO;
using System.Globalization;
using OfficeOpenXml.Style;
+using OfficeOpenXml.FormulaParsing;
+
namespace EPPlusTest
{
[TestClass]
@@ -424,6 +426,85 @@ public void s1007()
//SaveAndCleanup(p);
}
+
+ [TestMethod]
+ public void s1005()
+ {
+ SwitchToCulture("de-DE");
+
+ //Set specific built-in formats
+ if (!ExcelPackageSettings.CultureSpecificBuildInNumberFormats.ContainsKey("de-DE"))
+ {
+ ExcelPackageSettings.CultureSpecificBuildInNumberFormats.Add("de-DE",
+ new Dictionary
+ {
+ {14,"dd.MM.yyyy"},
+ {15,"dd. MMM yy"},
+ {16,"dd. MMM"},
+ {17,"MMM yy"},
+ {18,"hh:mm AM/PM" },
+ {22,"dd.MM.yyyy hh:mm"},
+ {37,"#,##0;-#,##0"},
+ {38,"#,##0;[Rot]-#,##0"},
+ {39,"#,##0.00;-#,##0.00"},
+ {40,"#,##0.00;[Rot]-#,##0.00"},
+ {47,"mm:ss,f"}
+ });
+ }
+
+ using (var p = OpenTemplatePackage("s1005.xlsx"))
+ {
+ //AND use a Custom Number Format
+ //This caused issues in the Text.cs file when we ran Calculate
+ p.Workbook.NumberFormatToTextHandler = CustomNumberFormatToTextExample;
+
+ var ws1 = p.Workbook.Worksheets[1];
+
+ var origText = ws1.Cells["D8"].Text;
+
+ //Verify cell contents match when test was written
+ Assert.IsTrue(origText.Contains(".8000"));
+ Assert.IsTrue(origText.Contains("(26895559.000)"));
+ Assert.IsTrue(origText.Contains("69928453.64000"));
+
+ ws1.Cells["D8"].Calculate();
+ var cellRich = ws1.Cells["D8"].RichText.Text;
+
+ //Verify formatting has changed appropriately for calculated string
+ Assert.IsTrue(cellRich.Contains("0,80"));
+ Assert.IsTrue(cellRich.Contains("(26.895.559,00)"));
+ Assert.IsTrue(cellRich.Contains("69.928.453,64"));
+
+ SaveAndCleanup(p);
+ }
+
+ SwitchBackToCurrentCulture();
+ }
+
+ private static string CustomNumberFormatToTextExample(NumberFormatToTextArgs options)
+ {
+ var result = options.Text;
+
+ switch (options.Value)
+ {
+ case DateTime dt:
+ {
+ switch (options.NumberFormat.Format)
+ {
+ case "dd. mmm yy":
+ result = dt.ToString("dd. mmm yy"); //Return your own formatted text. Example
+ break;
+ default:
+ result = dt.ToString(options.NumberFormat.Format);
+ break;
+ }
+ break;
+ }
+ }
+
+ return result;
+ }
+
public class TestData
{
public int Id { get; set; }