Skip to content
This repository was archived by the owner on Aug 26, 2022. It is now read-only.

Commit 8982017

Browse files
authored
Use standard built-it style formats (#37)
As defined in ECMA-376, 3rd Edition, Part 1, 18.8.30 numFmt (Number Format). > Some of these Ids can be interpreted differently, depending on the UI language of the implementing application. This renders dates properly in Excel, matching the current computer locale settings. For example, cell D5 in the "Test" worksheet of the sample app is correctly rendered as `26.04.2022 13:14` on a computer configured with a French (Switzerland) regional format. Without this change, the date was incorrectly displayed as `4.26.2022 13:14`.
1 parent 56d561a commit 8982017

File tree

3 files changed

+70
-33
lines changed

3 files changed

+70
-33
lines changed

src/Simplexcel.TestApp/Program.cs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,33 +71,35 @@ static void Main()
7171
sheet.Cells[0, 6] = "👪";
7272
sheet.Cells[0, 7] = "👨‍👩‍👧‍👦";
7373

74-
sheet.Cells["D4"] = DateTime.Now;
75-
sheet.Cells["D5"] = new Cell(CellType.Date, DateTime.Now, BuiltInCellFormat.DateOnly);
76-
sheet.Cells["D6"] = new Cell(CellType.Date, DateTime.Now, BuiltInCellFormat.TimeOnly);
77-
sheet.Cells["D7"] = long.MaxValue;
78-
sheet.Cells["D8"] = long.MinValue;
79-
sheet.Cells["D9"] = decimal.MaxValue;
80-
sheet.Cells["D10"] = decimal.MinValue;
81-
82-
sheet.Cells["D11"] = 9999999999L;
83-
sheet.Cells["D12"] = 99999999999L;
84-
sheet.Cells["D13"] = 100000000000L;
85-
sheet.Cells["D14"] = 100000000001L;
86-
sheet.Cells["D15"] = 1000000000000L;
87-
sheet.Cells["D16"] = 1000000000001L;
88-
sheet.Cells["D17"] = Cell.LargeNumberPositiveLimit;
89-
sheet.Cells["D18"] = Cell.LargeNumberPositiveLimit + 1;
90-
sheet.Cells["D19"] = Cell.LargeNumberPositiveLimit - 1;
91-
92-
sheet.Cells["D20"] = -9999999999L;
93-
sheet.Cells["D21"] = -99999999999L;
94-
sheet.Cells["D22"] = -100000000000L;
95-
sheet.Cells["D23"] = -100000000001L;
96-
sheet.Cells["D24"] = -1000000000000L;
97-
sheet.Cells["D25"] = -1000000000001L;
98-
sheet.Cells["D26"] = Cell.LargeNumberNegativeLimit;
99-
sheet.Cells["D27"] = Cell.LargeNumberNegativeLimit + 1;
100-
sheet.Cells["D28"] = Cell.LargeNumberNegativeLimit - 1;
74+
var dateTime = new DateTime(2022, 4, 26, 13, 14, 15);
75+
sheet.Cells["D4"] = dateTime;
76+
sheet.Cells["D5"] = new Cell(CellType.Date, dateTime, BuiltInCellFormat.DateOnly);
77+
sheet.Cells["D6"] = new Cell(CellType.Date, dateTime, BuiltInCellFormat.TimeOnly);
78+
sheet.Cells["D7"] = new Cell(CellType.Date, dateTime, "yyyy\"_\"mm\"_\"dd\"_\"hh\"_\"mm\"_\"ss");
79+
sheet.Cells["D8"] = long.MaxValue;
80+
sheet.Cells["D9"] = long.MinValue;
81+
sheet.Cells["D10"] = decimal.MaxValue;
82+
sheet.Cells["D11"] = decimal.MinValue;
83+
84+
sheet.Cells["D12"] = 9999999999L;
85+
sheet.Cells["D13"] = 99999999999L;
86+
sheet.Cells["D14"] = 100000000000L;
87+
sheet.Cells["D15"] = 100000000001L;
88+
sheet.Cells["D16"] = 1000000000000L;
89+
sheet.Cells["D17"] = 1000000000001L;
90+
sheet.Cells["D18"] = Cell.LargeNumberPositiveLimit;
91+
sheet.Cells["D19"] = Cell.LargeNumberPositiveLimit + 1;
92+
sheet.Cells["D20"] = Cell.LargeNumberPositiveLimit - 1;
93+
94+
sheet.Cells["D21"] = -9999999999L;
95+
sheet.Cells["D22"] = -99999999999L;
96+
sheet.Cells["D23"] = -100000000000L;
97+
sheet.Cells["D24"] = -100000000001L;
98+
sheet.Cells["D25"] = -1000000000000L;
99+
sheet.Cells["D26"] = -1000000000001L;
100+
sheet.Cells["D27"] = Cell.LargeNumberNegativeLimit;
101+
sheet.Cells["D28"] = Cell.LargeNumberNegativeLimit + 1;
102+
sheet.Cells["D29"] = Cell.LargeNumberNegativeLimit - 1;
101103
sheet.LargeNumberHandlingMode = LargeNumberHandlingMode.StoreAsText;
102104

103105
sheet.Cells["C5"] = "ThinDiagonalCrosshatch";

src/Simplexcel/Cells/BuiltInCellFormat.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ public static class BuiltInCellFormat
3636
public const string Text = "@";
3737

3838
/// <summary>
39-
/// m/d/yyyy h:mm
39+
/// m/d/yy h:mm
4040
/// </summary>
41-
public const string DateAndTime = "m/d/yyyy h:mm";
41+
public const string DateAndTime = "m/d/yy h:mm";
4242

4343
/// <summary>
44-
/// m/d/yyyy
44+
/// mm-dd-yy
4545
/// </summary>
46-
public const string DateOnly = "m/d/yyyy";
46+
public const string DateOnly = "mm-dd-yy";
4747

4848
/// <summary>
4949
/// h:mm

src/Simplexcel/XlsxInternal/StyleWriter.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,41 @@ internal static class StyleWriter
99
// There are up to 164 built in number formats (0-163), all else are custom (164 and above)
1010
private const int CustomFormatIndex = 164;
1111

12+
/// <summary>
13+
/// Standard format codes as defined in ECMA-376, 3rd Edition, Part 1, 18.8.30 numFmt (Number Format)
14+
/// </summary>
15+
private static Dictionary<string, int> StandardFormatIds = new Dictionary<string, int>
16+
{
17+
["General"] = 0,
18+
["0"] = 1,
19+
["0.00"] = 2,
20+
["#,##0"] = 3,
21+
["#,##0.00"] = 4,
22+
["0%"] = 9,
23+
["0.00%"] = 10,
24+
["0.00E+00"] = 11,
25+
["# ?/?"] = 12,
26+
["# ??/??"] = 13,
27+
["mm-dd-yy"] = 14,
28+
["d-mmm-yy"] = 15,
29+
["d-mmm"] = 16,
30+
["mmm-yy"] = 17,
31+
["h:mm AM/PM"] = 18,
32+
["h:mm:ss AM/PM"] = 19,
33+
["h:mm"] = 20,
34+
["h:mm:ss"] = 21,
35+
["m/d/yy h:mm"] = 22,
36+
["#,##0 ;(#,##0)"] = 37,
37+
["#,##0 ;[Red](#,##0)"] = 38,
38+
["#,##0.00;(#,##0.00)"] = 39,
39+
["#,##0.00;[Red](#,##0.00)"] = 40,
40+
["mm:ss"] = 45,
41+
["[h]:mm:ss"] = 46,
42+
["mmss.0"] = 47,
43+
["##0.0E+0"] = 48,
44+
["@"] = 49,
45+
};
46+
1247
/// <summary>
1348
/// Create a styles.xml file
1449
/// </summary>
@@ -29,7 +64,7 @@ internal static XmlFile CreateStyleXml(IList<XlsxCellStyle> styles)
2964
uniqueBorders.Add(style.Border);
3065
}
3166

32-
if (!numberFormats.Contains(style.Format))
67+
if (!numberFormats.Contains(style.Format) && !StandardFormatIds.ContainsKey(style.Format))
3368
{
3469
numberFormats.Add(style.Format);
3570
}
@@ -79,7 +114,7 @@ private static void StyleAddCellXfsElement(XDocument doc, IList<XlsxCellStyle> s
79114

80115
foreach (var style in styles)
81116
{
82-
var numFmtId = numberFormats.IndexOf(style.Format) + CustomFormatIndex;
117+
var numFmtId = StandardFormatIds.TryGetValue(style.Format, out var standardNumFmtId) ? standardNumFmtId : numberFormats.IndexOf(style.Format) + CustomFormatIndex;
83118
var fontId = fontInfos.IndexOf(style.Font);
84119
var fillId = fills.IndexOf(style.Fill);
85120
var borderId = uniqueBorders.IndexOf(style.Border);

0 commit comments

Comments
 (0)