-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
NPOI Version
2.7.3
File Type
- XLSX
- XLS
- DOCX
- XLSM
- OTHER
Upload the Excel File
Not really needed, but here's a spreadsheet with 2 different phone number formats, one works and one doesn't: Formatting_Issue_Test.xls
Reproduce Steps
Use DataFormatter.FormatCellValue() or DataFormatter.FormatRawCellContents() to format a 10 digit numeric value with the following phone number format: "###-###-####" or "###\\-###\\-####" as Excel provides it.
Cell B3 in the uploaded example .xls file has an example of the issue.
Issue Description
When creating the number format for "###-###-####" the DataFormatter.CreateNumberFormat method incorrectly identifies this format string as using '-' as an alternate grouping character and updates the format accordingly. This leads to the final output looking like this: "1-234-56-7-890".
You can test this quickly by adding a test like this to TestDataFormatter.cs
[Test]
public void TestPhoneNumberFormat()
{
DataFormatter formatter = new DataFormatter(CultureInfo.GetCultureInfo("en-US"));
Assert.AreEqual("(123) 456-7890", formatter.FormatRawCellContents(1234567890, -1, "[<=9999999]###\\-####;\\(###\\)\\ ###\\-####"));
Assert.AreEqual("123-456-7890", formatter.FormatRawCellContents(1234567890, -1, "###\\-###\\-####")); // returns 1-234-56-7-890
}
Note: This unit test also identifies a bug in DataFormatter.FormatRawCellContents when using SSNFormat, ZipPlusFourFormat, or PhoneFormat.
FormatRawCellContents converts the value to a decimal before calling Format:
result = numberFormat.Format(decimal.Parse(textValue));
But the Format methods of SSNFormat, ZipPlusFourFormat, and PhoneFormat all attempt to cast to a double, which throws an exception:
var result = ((double)obj).ToString(df, culture);
I updated these lines to use Convert.ToDouble the way DecimalFormat does in order to fix this:
var result = Convert.ToDouble(obj, CultureInfo.InvariantCulture).ToString(df, culture);