From 49234fb95ea115357757251905857c8c8f53eddd Mon Sep 17 00:00:00 2001 From: xuri Date: Thu, 11 May 2023 09:08:38 +0800 Subject: [PATCH] Ref #1199, this support applies partial built-in language number format code - Remove the `Lang` field in the `Style` data type - Rename field name `ShortDateFmtCode` to `ShortDatePattern` in the `Options` data type - Rename field name `LongDateFmtCode` to `LongDatePattern` in the `Options` data type - Rename field name `LongTimeFmtCode` to `LongTimePattern` in the `Options` data type - Apply built-in language number format code number when creating a new style - Checking and returning error if the date and time pattern was invalid - Add new `Options` field `CultureInfo` and new exported data type `CultureName` - Add new culture name types enumeration for country code - Update unit tests - Move built-in number format code and currency number format code definition source code - Remove the built-in language number format code mapping with Unicode values - Fix incorrect number formatted result for date and time with 12 hours at AM --- cell.go | 11 +- excelize.go | 22 +- excelize_test.go | 68 +++- numfmt.go | 721 +++++++++++++++++++++++++++++++++++++- numfmt_test.go | 6 +- rows_test.go | 2 +- styles.go | 888 +---------------------------------------------- styles_test.go | 6 +- xmlStyles.go | 1 - 9 files changed, 806 insertions(+), 919 deletions(-) diff --git a/cell.go b/cell.go index 064eba49..2de8e853 100644 --- a/cell.go +++ b/cell.go @@ -1336,15 +1336,6 @@ func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c return "", nil } -// applyBuiltInNumFmt provides a function to returns a value after formatted -// with built-in number format code, or specified sort date format code. -func (f *File) applyBuiltInNumFmt(c *xlsxC, fmtCode string, numFmtID int, date1904 bool, cellType CellType) string { - if numFmtID == 14 && f.options != nil && f.options.ShortDateFmtCode != "" { - fmtCode = f.options.ShortDateFmtCode - } - return format(c.V, fmtCode, date1904, cellType, f.options) -} - // formattedValue provides a function to returns a value after formatted. If // it is possible to apply a format to the cell value, it will do so, if not // then an error will be returned, along with the raw value of the cell. @@ -1374,7 +1365,7 @@ func (f *File) formattedValue(c *xlsxC, raw bool, cellType CellType) (string, er if wb != nil && wb.WorkbookPr != nil { date1904 = wb.WorkbookPr.Date1904 } - if fmtCode, ok := builtInNumFmt[numFmtID]; ok { + if fmtCode, ok := f.getBuiltInNumFmtCode(numFmtID); ok { return f.applyBuiltInNumFmt(c, fmtCode, numFmtID, date1904, cellType), err } if styleSheet.NumFmts == nil { diff --git a/excelize.go b/excelize.go index 7d84e579..d6772856 100644 --- a/excelize.go +++ b/excelize.go @@ -60,7 +60,7 @@ type File struct { // the spreadsheet from non-UTF-8 encoding. type charsetTranscoderFn func(charset string, input io.Reader) (rdr io.Reader, err error) -// Options define the options for open and reading spreadsheet. +// Options define the options for o`pen and reading spreadsheet. // // MaxCalcIterations specifies the maximum iterations for iterative // calculation, the default value is 0. @@ -80,26 +80,30 @@ type charsetTranscoderFn func(charset string, input io.Reader) (rdr io.Reader, e // should be less than or equal to UnzipSizeLimit, the default value is // 16MB. // -// ShortDateFmtCode specifies the short date number format code. In the +// ShortDatePattern specifies the short date number format code. In the // spreadsheet applications, date formats display date and time serial numbers // as date values. Date formats that begin with an asterisk (*) respond to // changes in regional date and time settings that are specified for the // operating system. Formats without an asterisk are not affected by operating -// system settings. The ShortDateFmtCode used for specifies apply date formats +// system settings. The ShortDatePattern used for specifies apply date formats // that begin with an asterisk. // -// LongDateFmtCode specifies the long date number format code. +// LongDatePattern specifies the long date number format code. // -// LongTimeFmtCode specifies the long time number format code. +// LongTimePattern specifies the long time number format code. +// +// CultureInfo specifies the country code for applying built-in language number +// format code these effect by the system's local language settings. type Options struct { MaxCalcIterations uint Password string RawCellValue bool UnzipSizeLimit int64 UnzipXMLSizeLimit int64 - ShortDateFmtCode string - LongDateFmtCode string - LongTimeFmtCode string + ShortDatePattern string + LongDatePattern string + LongTimePattern string + CultureInfo CultureName } // OpenFile take the name of an spreadsheet file and returns a populated @@ -162,7 +166,7 @@ func (f *File) checkOpenReaderOptions() error { if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit { return ErrOptionsUnzipSizeLimit } - return nil + return f.checkDateTimePattern() } // OpenReader read data stream from io.Reader and return a populated diff --git a/excelize_test.go b/excelize_test.go index 6116b425..cba95522 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -752,7 +752,7 @@ func TestSetCellStyleNumberFormat(t *testing.T) { expected := [][]string{ {"37947.7500001", "37948", "37947.75", "37,948", "37,947.75", "3794775%", "3794775.00%", "3.79E+04", "37947.7500001", "37947.7500001", "11-22-03", "22-Nov-03", "22-Nov", "Nov-03", "6:00 PM", "6:00:00 PM", "18:00", "18:00:00", "11/22/03 18:00", "37,948 ", "37,948 ", "37,947.75 ", "37,947.75 ", "37947.7500001", "37947.7500001", "37947.7500001", "37947.7500001", "00:00", "910746:00:00", "00:00.0", "37947.7500001", "37947.7500001"}, {"-37947.7500001", "-37948", "-37947.75", "-37,948", "-37,947.75", "-3794775%", "-3794775.00%", "-3.79E+04", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "(37,948)", "(37,948)", "(37,947.75)", "(37,947.75)", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001", "-37947.7500001"}, - {"0.007", "0", "0.01", "0", "0.01", "1%", "0.70%", "7.00E-03", "0.007", "0.007", "12-30-99", "30-Dec-99", "30-Dec", "Dec-99", "0:10 AM", "0:10:05 AM", "00:10", "00:10:05", "12/30/99 00:10", "0 ", "0 ", "0.01 ", "0.01 ", "0.007", "0.007", "0.007", "0.007", "10:05", "0:10:05", "10:04.8", "0.007", "0.007"}, + {"0.007", "0", "0.01", "0", "0.01", "1%", "0.70%", "7.00E-03", "0.007", "0.007", "12-30-99", "30-Dec-99", "30-Dec", "Dec-99", "12:10 AM", "12:10:05 AM", "00:10", "00:10:05", "12/30/99 00:10", "0 ", "0 ", "0.01 ", "0.01 ", "0.007", "0.007", "0.007", "0.007", "10:05", "0:10:05", "10:04.8", "0.007", "0.007"}, {"2.1", "2", "2.10", "2", "2.10", "210%", "210.00%", "2.10E+00", "2.1", "2.1", "01-01-00", "1-Jan-00", "1-Jan", "Jan-00", "2:24 AM", "2:24:00 AM", "02:24", "02:24:00", "1/1/00 02:24", "2 ", "2 ", "2.10 ", "2.10 ", "2.1", "2.1", "2.1", "2.1", "24:00", "50:24:00", "24:00.0", "2.1", "2.1"}, {"String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String"}, } @@ -811,19 +811,19 @@ func TestSetCellStyleCurrencyNumberFormat(t *testing.T) { assert.NoError(t, f.SetCellValue("Sheet1", "A1", 42920.5)) assert.NoError(t, f.SetCellValue("Sheet1", "A2", 42920.5)) - _, err = f.NewStyle(&Style{NumFmt: 26, Lang: "zh-tw"}) + _, err = f.NewStyle(&Style{NumFmt: 26}) assert.NoError(t, err) style, err := f.NewStyle(&Style{NumFmt: 27}) assert.NoError(t, err) assert.NoError(t, f.SetCellStyle("Sheet1", "A1", "A1", style)) - style, err = f.NewStyle(&Style{NumFmt: 31, Lang: "ko-kr"}) + style, err = f.NewStyle(&Style{NumFmt: 31}) assert.NoError(t, err) assert.NoError(t, f.SetCellStyle("Sheet1", "A2", "A2", style)) - style, err = f.NewStyle(&Style{NumFmt: 71, Lang: "th-th"}) + style, err = f.NewStyle(&Style{NumFmt: 71}) assert.NoError(t, err) assert.NoError(t, f.SetCellStyle("Sheet1", "A2", "A2", style)) @@ -831,6 +831,41 @@ func TestSetCellStyleCurrencyNumberFormat(t *testing.T) { }) } +func TestSetCellStyleLangNumberFormat(t *testing.T) { + rawCellValues := [][]string{{"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}} + for lang, expected := range map[CultureName][][]string{ + CultureNameUnknown: rawCellValues, + CultureNameEnUS: {{"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"0:00:00"}, {"0:00:00"}, {"0:00:00"}, {"0:00:00"}, {"45162"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"8/24/23"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}}, + CultureNameZhCN: {{"2023年8月"}, {"8月24日"}, {"8月24日"}, {"8/24/23"}, {"2023年8月24日"}, {"0时00分"}, {"0时00分00秒"}, {"上午12时00分"}, {"上午12时00分00秒"}, {"2023年8月"}, {"2023年8月"}, {"8月24日"}, {"2023年8月"}, {"8月24日"}, {"8月24日"}, {"上午12时00分"}, {"上午12时00分00秒"}, {"2023年8月"}, {"8月24日"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}}, + } { + f, err := prepareTestBook5(Options{CultureInfo: lang}) + assert.NoError(t, err) + rows, err := f.GetRows("Sheet1") + assert.NoError(t, err) + assert.Equal(t, expected, rows) + assert.NoError(t, f.Close()) + } + // Test apply language number format code with date and time pattern + for lang, expected := range map[CultureName][][]string{ + CultureNameEnUS: {{"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"00:00:00"}, {"00:00:00"}, {"00:00:00"}, {"00:00:00"}, {"45162"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"2023-8-24"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}}, + CultureNameZhCN: {{"2023年8月"}, {"8月24日"}, {"8月24日"}, {"2023-8-24"}, {"2023年8月24日"}, {"00:00:00"}, {"00:00:00"}, {"上午12时00分"}, {"上午12时00分00秒"}, {"2023年8月"}, {"2023年8月"}, {"8月24日"}, {"2023年8月"}, {"8月24日"}, {"8月24日"}, {"上午12时00分"}, {"上午12时00分00秒"}, {"2023年8月"}, {"8月24日"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}, {"45162"}}, + } { + f, err := prepareTestBook5(Options{CultureInfo: lang, ShortDatePattern: "yyyy-M-d", LongTimePattern: "hh:mm:ss"}) + assert.NoError(t, err) + rows, err := f.GetRows("Sheet1") + assert.NoError(t, err) + assert.Equal(t, expected, rows) + assert.NoError(t, f.Close()) + } + // Test open workbook with invalid date and time pattern options + _, err := OpenFile(filepath.Join("test", "Book1.xlsx"), Options{LongDatePattern: "0.00"}) + assert.Equal(t, ErrUnsupportedNumberFormat, err) + _, err = OpenFile(filepath.Join("test", "Book1.xlsx"), Options{LongTimePattern: "0.00"}) + assert.Equal(t, ErrUnsupportedNumberFormat, err) + _, err = OpenFile(filepath.Join("test", "Book1.xlsx"), Options{ShortDatePattern: "0.00"}) + assert.Equal(t, ErrUnsupportedNumberFormat, err) +} + func TestSetCellStyleCustomNumberFormat(t *testing.T) { f := NewFile() assert.NoError(t, f.SetCellValue("Sheet1", "A1", 42920.5)) @@ -1612,6 +1647,31 @@ func prepareTestBook4() (*File, error) { return f, nil } +func prepareTestBook5(opts Options) (*File, error) { + f := NewFile(opts) + var rowNum int + for _, idxRange := range [][]int{{27, 36}, {50, 81}} { + for numFmtIdx := idxRange[0]; numFmtIdx <= idxRange[1]; numFmtIdx++ { + rowNum++ + styleID, err := f.NewStyle(&Style{NumFmt: numFmtIdx}) + if err != nil { + return f, err + } + cell, err := CoordinatesToCellName(1, rowNum) + if err != nil { + return f, err + } + if err := f.SetCellValue("Sheet1", cell, 45162); err != nil { + return f, err + } + if err := f.SetCellStyle("Sheet1", cell, cell, styleID); err != nil { + return f, err + } + } + } + return f, nil +} + func fillCells(f *File, sheet string, colCount, rowCount int) error { for col := 1; col <= colCount; col++ { for row := 1; row <= rowCount; row++ { diff --git a/numfmt.go b/numfmt.go index 5e8155ef..cea63a1a 100644 --- a/numfmt.go +++ b/numfmt.go @@ -46,7 +46,639 @@ type numberFormat struct { useCommaSep, usePointer, usePositive, useScientificNotation bool } +// CultureName is the type of supported language country codes types for apply +// number format. +type CultureName byte + +// This section defines the currently supported country code types enumeration +// for apply number format. +const ( + CultureNameUnknown CultureName = iota + CultureNameEnUS + CultureNameZhCN +) + var ( + // Excel styles can reference number formats that are built-in, all of which + // have an id less than 164. Note that this number format code list is under + // English localization. + builtInNumFmt = map[int]string{ + 0: "general", + 1: "0", + 2: "0.00", + 3: "#,##0", + 4: "#,##0.00", + 9: "0%", + 10: "0.00%", + 11: "0.00E+00", + 12: "# ?/?", + 13: "# ??/??", + 14: "mm-dd-yy", + 15: "d-mmm-yy", + 16: "d-mmm", + 17: "mmm-yy", + 18: "h:mm AM/PM", + 19: "h:mm:ss AM/PM", + 20: "hh:mm", + 21: "hh:mm:ss", + 22: "m/d/yy hh:mm", + 37: "#,##0 ;(#,##0)", + 38: "#,##0 ;[red](#,##0)", + 39: "#,##0.00 ;(#,##0.00)", + 40: "#,##0.00 ;[red](#,##0.00)", + 41: `_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)`, + 42: `_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)`, + 43: `_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)`, + 44: `_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)`, + 45: "mm:ss", + 46: "[h]:mm:ss", + 47: "mm:ss.0", + 48: "##0.0E+0", + 49: "@", + } + // langNumFmt defined number format code provided for language glyphs where + // they occur in different language. + langNumFmt = map[string]map[int]string{ + "zh-tw": { + 27: "[$-404]e/m/d", + 28: `[$-404]e"年"m"月"d"日"`, + 29: `[$-404]e"年"m"月"d"日"`, + 30: "m/d/yy", + 31: `yyyy"年"m"月"d"日"`, + 32: `hh"時"mm"分"`, + 33: `hh"時"mm"分"ss"秒"`, + 34: `上午/下午 hh"時"mm"分"`, + 35: `上午/下午 hh"時"mm"分"ss"秒"`, + 36: "[$-404]e/m/d", + 50: "[$-404]e/m/d", + 51: `[$-404]e"年"m"月"d"日"`, + 52: `上午/下午 hh"時"mm"分"`, + 53: `上午/下午 hh"時"mm"分"ss"秒"`, + 54: `[$-404]e"年"m"月"d"日"`, + 55: `上午/下午 hh"時"mm"分"`, + 56: `上午/下午 hh"時"mm"分"ss"秒"`, + 57: "[$-404]e/m/d", + 58: `[$-404]e"年"m"月"d"日"`, + }, + "zh-cn": { + 27: `yyyy"年"m"月"`, + 28: `m"月"d"日"`, + 29: `m"月"d"日"`, + 30: "m/d/yy", + 31: `yyyy"年"m"月"d"日"`, + 32: `h"时"mm"分"`, + 33: `h"时"mm"分"ss"秒"`, + 34: `上午/下午 h"时"mm"分"`, + 35: `上午/下午 h"时"mm"分"ss"秒"`, + 36: `yyyy"年"m"月"`, + 50: `yyyy"年"m"月"`, + 51: `m"月"d"日"`, + 52: `yyyy"年"m"月"`, + 53: `m"月"d"日"`, + 54: `m"月"d"日"`, + 55: `上午/下午 h"时"mm"分"`, + 56: `上午/下午 h"时"mm"分"ss"秒"`, + 57: `yyyy"年"m"月"`, + 58: `m"月"d"日"`, + }, + "ja-jp": { + 27: "[$-411]ge.m.d", + 28: `[$-411]ggge"年"m"月"d"日"`, + 29: `[$-411]ggge"年"m"月"d"日"`, + 30: "m/d/yy", + 31: `yyyy"年"m"月"d"日"`, + 32: `h"時"mm"分"`, + 33: `h"時"mm"分"ss"秒"`, + 34: `yyyy"年"m"月"`, + 35: `m"月"d"日"`, + 36: "[$-411]ge.m.d", + 50: "[$-411]ge.m.d", + 51: `[$-411]ggge"年"m"月"d"日"`, + 52: `yyyy"年"m"月"`, + 53: `m"月"d"日"`, + 54: `[$-411]ggge"年"m"月"d"日"`, + 55: `yyyy"年"m"月"`, + 56: `m"月"d"日"`, + 57: "[$-411]ge.m.d", + 58: `[$-411]ggge"年"m"月"d"日"`, + }, + "ko-kr": { + 27: `yyyy"年" mm"月" dd"日"`, + 28: "mm-dd", + 29: "mm-dd", + 30: "mm-dd-yy", + 31: `yyyy"년" mm"월" dd"일"`, + 32: `h"시" mm"분"`, + 33: `h"시" mm"분" ss"초"`, + 34: `yyyy-mm-dd`, + 35: `yyyy-mm-dd`, + 36: `yyyy"年" mm"月" dd"日"`, + 50: `yyyy"年" mm"月" dd"日"`, + 51: "mm-dd", + 52: "yyyy-mm-dd", + 53: "yyyy-mm-dd", + 54: "mm-dd", + 55: "yyyy-mm-dd", + 56: "yyyy-mm-dd", + 57: `yyyy"年" mm"月" dd"日"`, + 58: "mm-dd", + }, + "th-th": { + 59: "t0", + 60: "t0.00", + 61: "t#,##0", + 62: "t#,##0.00", + 67: "t0%", + 68: "t0.00%", + 69: "t# ?/?", + 70: "t# ??/??", + 71: "ว/ด/ปปปป", + 72: "ว-ดดด-ปป", + 73: "ว-ดดด", + 74: "ดดด-ปป", + 75: "ช:นน", + 76: "ช:นน:ทท", + 77: "ว/ด/ปปปป ช:นน", + 78: "นน:ทท", + 79: "[ช]:นน:ทท", + 80: "นน:ทท.0", + 81: "d/m/bb", + }, + } + // currencyNumFmt defined the currency number format map. + currencyNumFmt = map[int]string{ + 164: `"¥"#,##0.00`, + 165: "[$$-409]#,##0.00", + 166: "[$$-45C]#,##0.00", + 167: "[$$-1004]#,##0.00", + 168: "[$$-404]#,##0.00", + 169: "[$$-C09]#,##0.00", + 170: "[$$-2809]#,##0.00", + 171: "[$$-1009]#,##0.00", + 172: "[$$-2009]#,##0.00", + 173: "[$$-1409]#,##0.00", + 174: "[$$-4809]#,##0.00", + 175: "[$$-2C09]#,##0.00", + 176: "[$$-2409]#,##0.00", + 177: "[$$-1000]#,##0.00", + 178: `#,##0.00\ [$$-C0C]`, + 179: "[$$-475]#,##0.00", + 180: "[$$-83E]#,##0.00", + 181: `[$$-86B]\ #,##0.00`, + 182: `[$$-340A]\ #,##0.00`, + 183: "[$$-240A]#,##0.00", + 184: `[$$-300A]\ #,##0.00`, + 185: "[$$-440A]#,##0.00", + 186: "[$$-80A]#,##0.00", + 187: "[$$-500A]#,##0.00", + 188: "[$$-540A]#,##0.00", + 189: `[$$-380A]\ #,##0.00`, + 190: "[$£-809]#,##0.00", + 191: "[$£-491]#,##0.00", + 192: "[$£-452]#,##0.00", + 193: "[$¥-804]#,##0.00", + 194: "[$¥-411]#,##0.00", + 195: "[$¥-478]#,##0.00", + 196: "[$¥-451]#,##0.00", + 197: "[$¥-480]#,##0.00", + 198: "#,##0.00\\ [$\u058F-42B]", + 199: "[$\u060B-463]#,##0.00", + 200: "[$\u060B-48C]#,##0.00", + 201: "[$\u09F3-845]\\ #,##0.00", + 202: "#,##0.00[$\u17DB-453]", + 203: "[$\u20A1-140A]#,##0.00", + 204: "[$\u20A6-468]\\ #,##0.00", + 205: "[$\u20A6-470]\\ #,##0.00", + 206: "[$\u20A9-412]#,##0.00", + 207: "[$\u20AA-40D]\\ #,##0.00", + 208: "#,##0.00\\ [$\u20AB-42A]", + 209: "#,##0.00\\ [$\u20AC-42D]", + 210: "#,##0.00\\ [$\u20AC-47E]", + 211: "#,##0.00\\ [$\u20AC-403]", + 212: "#,##0.00\\ [$\u20AC-483]", + 213: "[$\u20AC-813]\\ #,##0.00", + 214: "[$\u20AC-413]\\ #,##0.00", + 215: "[$\u20AC-1809]#,##0.00", + 216: "#,##0.00\\ [$\u20AC-425]", + 217: "[$\u20AC-2]\\ #,##0.00", + 218: "#,##0.00\\ [$\u20AC-1]", + 219: "#,##0.00\\ [$\u20AC-40B]", + 220: "#,##0.00\\ [$\u20AC-80C]", + 221: "#,##0.00\\ [$\u20AC-40C]", + 222: "#,##0.00\\ [$\u20AC-140C]", + 223: "#,##0.00\\ [$\u20AC-180C]", + 224: "[$\u20AC-200C]#,##0.00", + 225: "#,##0.00\\ [$\u20AC-456]", + 226: "#,##0.00\\ [$\u20AC-C07]", + 227: "#,##0.00\\ [$\u20AC-407]", + 228: "#,##0.00\\ [$\u20AC-1007]", + 229: "#,##0.00\\ [$\u20AC-408]", + 230: "#,##0.00\\ [$\u20AC-243B]", + 231: "[$\u20AC-83C]#,##0.00", + 232: "[$\u20AC-410]\\ #,##0.00", + 233: "[$\u20AC-476]#,##0.00", + 234: "#,##0.00\\ [$\u20AC-2C1A]", + 235: "[$\u20AC-426]\\ #,##0.00", + 236: "#,##0.00\\ [$\u20AC-427]", + 237: "#,##0.00\\ [$\u20AC-82E]", + 238: "#,##0.00\\ [$\u20AC-46E]", + 239: "[$\u20AC-43A]#,##0.00", + 240: "#,##0.00\\ [$\u20AC-C3B]", + 241: "#,##0.00\\ [$\u20AC-482]", + 242: "#,##0.00\\ [$\u20AC-816]", + 243: "#,##0.00\\ [$\u20AC-301A]", + 244: "#,##0.00\\ [$\u20AC-203B]", + 245: "#,##0.00\\ [$\u20AC-41B]", + 246: "#,##0.00\\ [$\u20AC-424]", + 247: "#,##0.00\\ [$\u20AC-C0A]", + 248: "#,##0.00\\ [$\u20AC-81D]", + 249: "#,##0.00\\ [$\u20AC-484]", + 250: "#,##0.00\\ [$\u20AC-42E]", + 251: "[$\u20AC-462]\\ #,##0.00", + 252: "#,##0.00\\ [$₭-454]", + 253: "#,##0.00\\ [$₮-450]", + 254: "[$\u20AE-C50]#,##0.00", + 255: "[$\u20B1-3409]#,##0.00", + 256: "[$\u20B1-464]#,##0.00", + 257: "#,##0.00[$\u20B4-422]", + 258: "[$\u20B8-43F]#,##0.00", + 259: "[$\u20B9-460]#,##0.00", + 260: "[$\u20B9-4009]\\ #,##0.00", + 261: "[$\u20B9-447]\\ #,##0.00", + 262: "[$\u20B9-439]\\ #,##0.00", + 263: "[$\u20B9-44B]\\ #,##0.00", + 264: "[$\u20B9-860]#,##0.00", + 265: "[$\u20B9-457]\\ #,##0.00", + 266: "[$\u20B9-458]#,##0.00", + 267: "[$\u20B9-44E]\\ #,##0.00", + 268: "[$\u20B9-861]#,##0.00", + 269: "[$\u20B9-448]\\ #,##0.00", + 270: "[$\u20B9-446]\\ #,##0.00", + 271: "[$\u20B9-44F]\\ #,##0.00", + 272: "[$\u20B9-459]#,##0.00", + 273: "[$\u20B9-449]\\ #,##0.00", + 274: "[$\u20B9-820]#,##0.00", + 275: "#,##0.00\\ [$\u20BA-41F]", + 276: "#,##0.00\\ [$\u20BC-42C]", + 277: "#,##0.00\\ [$\u20BC-82C]", + 278: "#,##0.00\\ [$\u20BD-419]", + 279: "#,##0.00[$\u20BD-485]", + 280: "#,##0.00\\ [$\u20BE-437]", + 281: "[$B/.-180A]\\ #,##0.00", + 282: "[$Br-472]#,##0.00", + 283: "[$Br-477]#,##0.00", + 284: "#,##0.00[$Br-473]", + 285: "[$Bs-46B]\\ #,##0.00", + 286: "[$Bs-400A]\\ #,##0.00", + 287: "[$Bs.-200A]\\ #,##0.00", + 288: "[$BWP-832]\\ #,##0.00", + 289: "[$C$-4C0A]#,##0.00", + 290: "[$CA$-85D]#,##0.00", + 291: "[$CA$-47C]#,##0.00", + 292: "[$CA$-45D]#,##0.00", + 293: "[$CFA-340C]#,##0.00", + 294: "[$CFA-280C]#,##0.00", + 295: "#,##0.00\\ [$CFA-867]", + 296: "#,##0.00\\ [$CFA-488]", + 297: "#,##0.00\\ [$CHF-100C]", + 298: "[$CHF-1407]\\ #,##0.00", + 299: "[$CHF-807]\\ #,##0.00", + 300: "[$CHF-810]\\ #,##0.00", + 301: "[$CHF-417]\\ #,##0.00", + 302: "[$CLP-47A]\\ #,##0.00", + 303: "[$CN¥-850]#,##0.00", + 304: "#,##0.00\\ [$DZD-85F]", + 305: "[$FCFA-2C0C]#,##0.00", + 306: "#,##0.00\\ [$Ft-40E]", + 307: "[$G-3C0C]#,##0.00", + 308: "[$Gs.-3C0A]\\ #,##0.00", + 309: "[$GTQ-486]#,##0.00", + 310: "[$HK$-C04]#,##0.00", + 311: "[$HK$-3C09]#,##0.00", + 312: "#,##0.00\\ [$HRK-41A]", + 313: "[$IDR-3809]#,##0.00", + 314: "[$IQD-492]#,##0.00", + 315: "#,##0.00\\ [$ISK-40F]", + 316: "[$K-455]#,##0.00", + 317: "#,##0.00\\ [$K\u010D-405]", + 318: "#,##0.00\\ [$KM-141A]", + 319: "#,##0.00\\ [$KM-101A]", + 320: "#,##0.00\\ [$KM-181A]", + 321: "[$kr-438]\\ #,##0.00", + 322: "[$kr-43B]\\ #,##0.00", + 323: "#,##0.00\\ [$kr-83B]", + 324: "[$kr-414]\\ #,##0.00", + 325: "[$kr-814]\\ #,##0.00", + 326: "#,##0.00\\ [$kr-41D]", + 327: "[$kr.-406]\\ #,##0.00", + 328: "[$kr.-46F]\\ #,##0.00", + 329: "[$Ksh-441]#,##0.00", + 330: "[$L-818]#,##0.00", + 331: "[$L-819]#,##0.00", + 332: "[$L-480A]\\ #,##0.00", + 333: "#,##0.00\\ [$Lek\u00EB-41C]", + 334: "[$MAD-45F]#,##0.00", + 335: "[$MAD-380C]#,##0.00", + 336: "#,##0.00\\ [$MAD-105F]", + 337: "[$MOP$-1404]#,##0.00", + 338: "#,##0.00\\ [$MVR-465]_-", + 339: "#,##0.00[$Nfk-873]", + 340: "[$NGN-466]#,##0.00", + 341: "[$NGN-467]#,##0.00", + 342: "[$NGN-469]#,##0.00", + 343: "[$NGN-471]#,##0.00", + 344: "[$NOK-103B]\\ #,##0.00", + 345: "[$NOK-183B]\\ #,##0.00", + 346: "[$NZ$-481]#,##0.00", + 347: "[$PKR-859]\\ #,##0.00", + 348: "[$PYG-474]#,##0.00", + 349: "[$Q-100A]#,##0.00", + 350: "[$R-436]\\ #,##0.00", + 351: "[$R-1C09]\\ #,##0.00", + 352: "[$R-435]\\ #,##0.00", + 353: "[$R$-416]\\ #,##0.00", + 354: "[$RD$-1C0A]#,##0.00", + 355: "#,##0.00\\ [$RF-487]", + 356: "[$RM-4409]#,##0.00", + 357: "[$RM-43E]#,##0.00", + 358: "#,##0.00\\ [$RON-418]", + 359: "[$Rp-421]#,##0.00", + 360: "[$Rs-420]#,##0.00_-", + 361: "[$Rs.-849]\\ #,##0.00", + 362: "#,##0.00\\ [$RSD-81A]", + 363: "#,##0.00\\ [$RSD-C1A]", + 364: "#,##0.00\\ [$RUB-46D]", + 365: "#,##0.00\\ [$RUB-444]", + 366: "[$S/.-C6B]\\ #,##0.00", + 367: "[$S/.-280A]\\ #,##0.00", + 368: "#,##0.00\\ [$SEK-143B]", + 369: "#,##0.00\\ [$SEK-1C3B]", + 370: "#,##0.00\\ [$so\u02BBm-443]", + 371: "#,##0.00\\ [$so\u02BBm-843]", + 372: "#,##0.00\\ [$SYP-45A]", + 373: "[$THB-41E]#,##0.00", + 374: "#,##0.00[$TMT-442]", + 375: "[$US$-3009]#,##0.00", + 376: "[$ZAR-46C]\\ #,##0.00", + 377: "[$ZAR-430]#,##0.00", + 378: "[$ZAR-431]#,##0.00", + 379: "[$ZAR-432]\\ #,##0.00", + 380: "[$ZAR-433]#,##0.00", + 381: "[$ZAR-434]\\ #,##0.00", + 382: "#,##0.00\\ [$z\u0142-415]", + 383: "#,##0.00\\ [$\u0434\u0435\u043D-42F]", + 384: "#,##0.00\\ [$КМ-201A]", + 385: "#,##0.00\\ [$КМ-1C1A]", + 386: "#,##0.00\\ [$\u043B\u0432.-402]", + 387: "#,##0.00\\ [$р.-423]", + 388: "#,##0.00\\ [$\u0441\u043E\u043C-440]", + 389: "#,##0.00\\ [$\u0441\u043E\u043C-428]", + 390: "[$\u062C.\u0645.-C01]\\ #,##0.00_-", + 391: "[$\u062F.\u0623.-2C01]\\ #,##0.00_-", + 392: "[$\u062F.\u0625.-3801]\\ #,##0.00_-", + 393: "[$\u062F.\u0628.-3C01]\\ #,##0.00_-", + 394: "[$\u062F.\u062A.-1C01]\\ #,##0.00_-", + 395: "[$\u062F.\u062C.-1401]\\ #,##0.00_-", + 396: "[$\u062F.\u0639.-801]\\ #,##0.00_-", + 397: "[$\u062F.\u0643.-3401]\\ #,##0.00_-", + 398: "[$\u062F.\u0644.-1001]#,##0.00_-", + 399: "[$\u062F.\u0645.-1801]\\ #,##0.00_-", + 400: "[$\u0631-846]\\ #,##0.00", + 401: "[$\u0631.\u0633.-401]\\ #,##0.00_-", + 402: "[$\u0631.\u0639.-2001]\\ #,##0.00_-", + 403: "[$\u0631.\u0642.-4001]\\ #,##0.00_-", + 404: "[$\u0631.\u064A.-2401]\\ #,##0.00_-", + 405: "[$\u0631\u06CC\u0627\u0644-429]#,##0.00_-", + 406: "[$\u0644.\u0633.-2801]\\ #,##0.00_-", + 407: "[$\u0644.\u0644.-3001]\\ #,##0.00_-", + 408: "[$\u1265\u122D-45E]#,##0.00", + 409: "[$\u0930\u0942-461]#,##0.00", + 410: "[$\u0DBB\u0DD4.-45B]\\ #,##0.00", + 411: "[$ADP]\\ #,##0.00", + 412: "[$AED]\\ #,##0.00", + 413: "[$AFA]\\ #,##0.00", + 414: "[$AFN]\\ #,##0.00", + 415: "[$ALL]\\ #,##0.00", + 416: "[$AMD]\\ #,##0.00", + 417: "[$ANG]\\ #,##0.00", + 418: "[$AOA]\\ #,##0.00", + 419: "[$ARS]\\ #,##0.00", + 420: "[$ATS]\\ #,##0.00", + 421: "[$AUD]\\ #,##0.00", + 422: "[$AWG]\\ #,##0.00", + 423: "[$AZM]\\ #,##0.00", + 424: "[$AZN]\\ #,##0.00", + 425: "[$BAM]\\ #,##0.00", + 426: "[$BBD]\\ #,##0.00", + 427: "[$BDT]\\ #,##0.00", + 428: "[$BEF]\\ #,##0.00", + 429: "[$BGL]\\ #,##0.00", + 430: "[$BGN]\\ #,##0.00", + 431: "[$BHD]\\ #,##0.00", + 432: "[$BIF]\\ #,##0.00", + 433: "[$BMD]\\ #,##0.00", + 434: "[$BND]\\ #,##0.00", + 435: "[$BOB]\\ #,##0.00", + 436: "[$BOV]\\ #,##0.00", + 437: "[$BRL]\\ #,##0.00", + 438: "[$BSD]\\ #,##0.00", + 439: "[$BTN]\\ #,##0.00", + 440: "[$BWP]\\ #,##0.00", + 441: "[$BYR]\\ #,##0.00", + 442: "[$BZD]\\ #,##0.00", + 443: "[$CAD]\\ #,##0.00", + 444: "[$CDF]\\ #,##0.00", + 445: "[$CHE]\\ #,##0.00", + 446: "[$CHF]\\ #,##0.00", + 447: "[$CHW]\\ #,##0.00", + 448: "[$CLF]\\ #,##0.00", + 449: "[$CLP]\\ #,##0.00", + 450: "[$CNY]\\ #,##0.00", + 451: "[$COP]\\ #,##0.00", + 452: "[$COU]\\ #,##0.00", + 453: "[$CRC]\\ #,##0.00", + 454: "[$CSD]\\ #,##0.00", + 455: "[$CUC]\\ #,##0.00", + 456: "[$CVE]\\ #,##0.00", + 457: "[$CYP]\\ #,##0.00", + 458: "[$CZK]\\ #,##0.00", + 459: "[$DEM]\\ #,##0.00", + 460: "[$DJF]\\ #,##0.00", + 461: "[$DKK]\\ #,##0.00", + 462: "[$DOP]\\ #,##0.00", + 463: "[$DZD]\\ #,##0.00", + 464: "[$ECS]\\ #,##0.00", + 465: "[$ECV]\\ #,##0.00", + 466: "[$EEK]\\ #,##0.00", + 467: "[$EGP]\\ #,##0.00", + 468: "[$ERN]\\ #,##0.00", + 469: "[$ESP]\\ #,##0.00", + 470: "[$ETB]\\ #,##0.00", + 471: "[$EUR]\\ #,##0.00", + 472: "[$FIM]\\ #,##0.00", + 473: "[$FJD]\\ #,##0.00", + 474: "[$FKP]\\ #,##0.00", + 475: "[$FRF]\\ #,##0.00", + 476: "[$GBP]\\ #,##0.00", + 477: "[$GEL]\\ #,##0.00", + 478: "[$GHC]\\ #,##0.00", + 479: "[$GHS]\\ #,##0.00", + 480: "[$GIP]\\ #,##0.00", + 481: "[$GMD]\\ #,##0.00", + 482: "[$GNF]\\ #,##0.00", + 483: "[$GRD]\\ #,##0.00", + 484: "[$GTQ]\\ #,##0.00", + 485: "[$GYD]\\ #,##0.00", + 486: "[$HKD]\\ #,##0.00", + 487: "[$HNL]\\ #,##0.00", + 488: "[$HRK]\\ #,##0.00", + 489: "[$HTG]\\ #,##0.00", + 490: "[$HUF]\\ #,##0.00", + 491: "[$IDR]\\ #,##0.00", + 492: "[$IEP]\\ #,##0.00", + 493: "[$ILS]\\ #,##0.00", + 494: "[$INR]\\ #,##0.00", + 495: "[$IQD]\\ #,##0.00", + 496: "[$IRR]\\ #,##0.00", + 497: "[$ISK]\\ #,##0.00", + 498: "[$ITL]\\ #,##0.00", + 499: "[$JMD]\\ #,##0.00", + 500: "[$JOD]\\ #,##0.00", + 501: "[$JPY]\\ #,##0.00", + 502: "[$KAF]\\ #,##0.00", + 503: "[$KES]\\ #,##0.00", + 504: "[$KGS]\\ #,##0.00", + 505: "[$KHR]\\ #,##0.00", + 506: "[$KMF]\\ #,##0.00", + 507: "[$KPW]\\ #,##0.00", + 508: "[$KRW]\\ #,##0.00", + 509: "[$KWD]\\ #,##0.00", + 510: "[$KYD]\\ #,##0.00", + 511: "[$KZT]\\ #,##0.00", + 512: "[$LAK]\\ #,##0.00", + 513: "[$LBP]\\ #,##0.00", + 514: "[$LKR]\\ #,##0.00", + 515: "[$LRD]\\ #,##0.00", + 516: "[$LSL]\\ #,##0.00", + 517: "[$LTL]\\ #,##0.00", + 518: "[$LUF]\\ #,##0.00", + 519: "[$LVL]\\ #,##0.00", + 520: "[$LYD]\\ #,##0.00", + 521: "[$MAD]\\ #,##0.00", + 522: "[$MDL]\\ #,##0.00", + 523: "[$MGA]\\ #,##0.00", + 524: "[$MGF]\\ #,##0.00", + 525: "[$MKD]\\ #,##0.00", + 526: "[$MMK]\\ #,##0.00", + 527: "[$MNT]\\ #,##0.00", + 528: "[$MOP]\\ #,##0.00", + 529: "[$MRO]\\ #,##0.00", + 530: "[$MTL]\\ #,##0.00", + 531: "[$MUR]\\ #,##0.00", + 532: "[$MVR]\\ #,##0.00", + 533: "[$MWK]\\ #,##0.00", + 534: "[$MXN]\\ #,##0.00", + 535: "[$MXV]\\ #,##0.00", + 536: "[$MYR]\\ #,##0.00", + 537: "[$MZM]\\ #,##0.00", + 538: "[$MZN]\\ #,##0.00", + 539: "[$NAD]\\ #,##0.00", + 540: "[$NGN]\\ #,##0.00", + 541: "[$NIO]\\ #,##0.00", + 542: "[$NLG]\\ #,##0.00", + 543: "[$NOK]\\ #,##0.00", + 544: "[$NPR]\\ #,##0.00", + 545: "[$NTD]\\ #,##0.00", + 546: "[$NZD]\\ #,##0.00", + 547: "[$OMR]\\ #,##0.00", + 548: "[$PAB]\\ #,##0.00", + 549: "[$PEN]\\ #,##0.00", + 550: "[$PGK]\\ #,##0.00", + 551: "[$PHP]\\ #,##0.00", + 552: "[$PKR]\\ #,##0.00", + 553: "[$PLN]\\ #,##0.00", + 554: "[$PTE]\\ #,##0.00", + 555: "[$PYG]\\ #,##0.00", + 556: "[$QAR]\\ #,##0.00", + 557: "[$ROL]\\ #,##0.00", + 558: "[$RON]\\ #,##0.00", + 559: "[$RSD]\\ #,##0.00", + 560: "[$RUB]\\ #,##0.00", + 561: "[$RUR]\\ #,##0.00", + 562: "[$RWF]\\ #,##0.00", + 563: "[$SAR]\\ #,##0.00", + 564: "[$SBD]\\ #,##0.00", + 565: "[$SCR]\\ #,##0.00", + 566: "[$SDD]\\ #,##0.00", + 567: "[$SDG]\\ #,##0.00", + 568: "[$SDP]\\ #,##0.00", + 569: "[$SEK]\\ #,##0.00", + 570: "[$SGD]\\ #,##0.00", + 571: "[$SHP]\\ #,##0.00", + 572: "[$SIT]\\ #,##0.00", + 573: "[$SKK]\\ #,##0.00", + 574: "[$SLL]\\ #,##0.00", + 575: "[$SOS]\\ #,##0.00", + 576: "[$SPL]\\ #,##0.00", + 577: "[$SRD]\\ #,##0.00", + 578: "[$SRG]\\ #,##0.00", + 579: "[$STD]\\ #,##0.00", + 580: "[$SVC]\\ #,##0.00", + 581: "[$SYP]\\ #,##0.00", + 582: "[$SZL]\\ #,##0.00", + 583: "[$THB]\\ #,##0.00", + 584: "[$TJR]\\ #,##0.00", + 585: "[$TJS]\\ #,##0.00", + 586: "[$TMM]\\ #,##0.00", + 587: "[$TMT]\\ #,##0.00", + 588: "[$TND]\\ #,##0.00", + 589: "[$TOP]\\ #,##0.00", + 590: "[$TRL]\\ #,##0.00", + 591: "[$TRY]\\ #,##0.00", + 592: "[$TTD]\\ #,##0.00", + 593: "[$TWD]\\ #,##0.00", + 594: "[$TZS]\\ #,##0.00", + 595: "[$UAH]\\ #,##0.00", + 596: "[$UGX]\\ #,##0.00", + 597: "[$USD]\\ #,##0.00", + 598: "[$USN]\\ #,##0.00", + 599: "[$USS]\\ #,##0.00", + 600: "[$UYI]\\ #,##0.00", + 601: "[$UYU]\\ #,##0.00", + 602: "[$UZS]\\ #,##0.00", + 603: "[$VEB]\\ #,##0.00", + 604: "[$VEF]\\ #,##0.00", + 605: "[$VND]\\ #,##0.00", + 606: "[$VUV]\\ #,##0.00", + 607: "[$WST]\\ #,##0.00", + 608: "[$XAF]\\ #,##0.00", + 609: "[$XAG]\\ #,##0.00", + 610: "[$XAU]\\ #,##0.00", + 611: "[$XB5]\\ #,##0.00", + 612: "[$XBA]\\ #,##0.00", + 613: "[$XBB]\\ #,##0.00", + 614: "[$XBC]\\ #,##0.00", + 615: "[$XBD]\\ #,##0.00", + 616: "[$XCD]\\ #,##0.00", + 617: "[$XDR]\\ #,##0.00", + 618: "[$XFO]\\ #,##0.00", + 619: "[$XFU]\\ #,##0.00", + 620: "[$XOF]\\ #,##0.00", + 621: "[$XPD]\\ #,##0.00", + 622: "[$XPF]\\ #,##0.00", + 623: "[$XPT]\\ #,##0.00", + 624: "[$XTS]\\ #,##0.00", + 625: "[$XXX]\\ #,##0.00", + 626: "[$YER]\\ #,##0.00", + 627: "[$YUM]\\ #,##0.00", + 628: "[$ZAR]\\ #,##0.00", + 629: "[$ZMK]\\ #,##0.00", + 630: "[$ZMW]\\ #,##0.00", + 631: "[$ZWD]\\ #,##0.00", + 632: "[$ZWL]\\ #,##0.00", + 633: "[$ZWN]\\ #,##0.00", + 634: "[$ZWR]\\ #,##0.00", + } // supportedTokenTypes list the supported number format token types currently. supportedTokenTypes = []string{ nfp.TokenSubTypeCurrencyString, @@ -383,6 +1015,78 @@ var ( } ) +// applyBuiltInNumFmt provides a function to returns a value after formatted +// with built-in number format code, or specified sort date format code. +func (f *File) applyBuiltInNumFmt(c *xlsxC, fmtCode string, numFmtID int, date1904 bool, cellType CellType) string { + if numFmtID == 14 && f.options != nil && f.options.ShortDatePattern != "" { + fmtCode = f.options.ShortDatePattern + } + return format(c.V, fmtCode, date1904, cellType, f.options) +} + +// langNumFmtFuncEnUS returns number format code by given date and time pattern +// for country code en-us. +func (f *File) langNumFmtFuncEnUS(numFmtID int) string { + shortDatePattern, longTimePattern := "M/d/yy", "h:mm:ss" + if f.options.ShortDatePattern != "" { + shortDatePattern = f.options.ShortDatePattern + } + if f.options.LongTimePattern != "" { + longTimePattern = f.options.LongTimePattern + } + if 32 <= numFmtID && numFmtID <= 35 { + return longTimePattern + } + if (27 <= numFmtID && numFmtID <= 31) || (50 <= numFmtID && numFmtID <= 58) { + return shortDatePattern + } + return "" +} + +// checkDateTimePattern check and validate date and time options field value. +func (f *File) checkDateTimePattern() error { + for _, pattern := range []string{f.options.LongDatePattern, f.options.LongTimePattern, f.options.ShortDatePattern} { + p := nfp.NumberFormatParser() + for _, section := range p.Parse(pattern) { + for _, token := range section.Items { + if inStrSlice(supportedNumberTokenTypes, token.TType, false) == -1 || inStrSlice(supportedNumberTokenTypes, token.TType, false) != -1 { + return ErrUnsupportedNumberFormat + } + } + } + } + return nil +} + +// langNumFmtFuncZhCN returns number format code by given date and time pattern +// for country code zh-cn. +func (f *File) langNumFmtFuncZhCN(numFmtID int) string { + if numFmtID == 30 && f.options.ShortDatePattern != "" { + return f.options.ShortDatePattern + } + if (32 <= numFmtID && numFmtID <= 33) && f.options.LongTimePattern != "" { + return f.options.LongTimePattern + } + return langNumFmt["zh-cn"][numFmtID] +} + +// getBuiltInNumFmtCode convert number format index to number format code with +// specified locale and language. +func (f *File) getBuiltInNumFmtCode(numFmtID int) (string, bool) { + if fmtCode, ok := builtInNumFmt[numFmtID]; ok { + return fmtCode, true + } + if (27 <= numFmtID && numFmtID <= 36) || (50 <= numFmtID && numFmtID <= 81) { + if f.options.CultureInfo == CultureNameEnUS { + return f.langNumFmtFuncEnUS(numFmtID), true + } + if f.options.CultureInfo == CultureNameZhCN { + return f.langNumFmtFuncZhCN(numFmtID), true + } + } + return "", false +} + // prepareNumberic split the number into two before and after parts by a // decimal point. func (nf *numberFormat) prepareNumberic(value string) { @@ -695,15 +1399,15 @@ func (nf *numberFormat) currencyLanguageHandler(i int, token nfp.Token) (error, } if part.Token.TType == nfp.TokenSubTypeLanguageInfo { if strings.EqualFold(part.Token.TValue, "F800") { // [$-x-sysdate] - if nf.opts != nil && nf.opts.LongDateFmtCode != "" { - nf.value = format(nf.value, nf.opts.LongDateFmtCode, nf.date1904, nf.cellType, nf.opts) + if nf.opts != nil && nf.opts.LongDatePattern != "" { + nf.value = format(nf.value, nf.opts.LongDatePattern, nf.date1904, nf.cellType, nf.opts) return nil, true } part.Token.TValue = "409" } if strings.EqualFold(part.Token.TValue, "F400") { // [$-x-systime] - if nf.opts != nil && nf.opts.LongTimeFmtCode != "" { - nf.value = format(nf.value, nf.opts.LongTimeFmtCode, nf.date1904, nf.cellType, nf.opts) + if nf.opts != nil && nf.opts.LongTimePattern != "" { + nf.value = format(nf.value, nf.opts.LongTimePattern, nf.date1904, nf.cellType, nf.opts) return nil, true } part.Token.TValue = "409" @@ -1091,8 +1795,13 @@ func (nf *numberFormat) hoursHandler(i int, token nfp.Token) { h -= 12 } } - if nf.ap != "" && nf.hoursNext(i) == -1 && h > 12 { - h -= 12 + if nf.ap != "" { + if nf.hoursNext(i) == -1 && h > 12 { + h -= 12 + } + if h == 0 { + h = 12 + } } switch len(token.TValue) { case 1: diff --git a/numfmt_test.go b/numfmt_test.go index 21a657f6..c41fd940 100644 --- a/numfmt_test.go +++ b/numfmt_test.go @@ -1072,9 +1072,9 @@ func TestNumFmt(t *testing.T) { {"43543.503206018519", "[$-F400]h:mm:ss AM/PM", "12:04:37"}, } { result := format(item[0], item[1], false, CellTypeNumber, &Options{ - ShortDateFmtCode: "yyyy/m/d", - LongDateFmtCode: "yyyy\"年\"M\"月\"d\"日\"", - LongTimeFmtCode: "H:mm:ss", + ShortDatePattern: "yyyy/m/d", + LongDatePattern: "yyyy\"年\"M\"月\"d\"日\"", + LongTimePattern: "H:mm:ss", }) assert.Equal(t, item[2], result, item) } diff --git a/rows_test.go b/rows_test.go index f836cc05..f94adbd0 100644 --- a/rows_test.go +++ b/rows_test.go @@ -1118,7 +1118,7 @@ func TestNumberFormats(t *testing.T) { } assert.NoError(t, f.SaveAs(filepath.Join("test", "TestNumberFormats.xlsx"))) - f = NewFile(Options{ShortDateFmtCode: "yyyy/m/d"}) + f = NewFile(Options{ShortDatePattern: "yyyy/m/d"}) assert.NoError(t, f.SetCellValue("Sheet1", "A1", 43543.503206018519)) numFmt14, err := f.NewStyle(&Style{NumFmt: 14}) assert.NoError(t, err) diff --git a/styles.go b/styles.go index bfef6a96..960aa89e 100644 --- a/styles.go +++ b/styles.go @@ -23,734 +23,6 @@ import ( "strings" ) -// Excel styles can reference number formats that are built-in, all of which -// have an id less than 164. Note that this number format code list is under -// English localization. -var builtInNumFmt = map[int]string{ - 0: "general", - 1: "0", - 2: "0.00", - 3: "#,##0", - 4: "#,##0.00", - 9: "0%", - 10: "0.00%", - 11: "0.00E+00", - 12: "# ?/?", - 13: "# ??/??", - 14: "mm-dd-yy", - 15: "d-mmm-yy", - 16: "d-mmm", - 17: "mmm-yy", - 18: "h:mm AM/PM", - 19: "h:mm:ss AM/PM", - 20: "hh:mm", - 21: "hh:mm:ss", - 22: "m/d/yy hh:mm", - 37: "#,##0 ;(#,##0)", - 38: "#,##0 ;[red](#,##0)", - 39: "#,##0.00 ;(#,##0.00)", - 40: "#,##0.00 ;[red](#,##0.00)", - 41: `_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)`, - 42: `_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)`, - 43: `_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)`, - 44: `_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)`, - 45: "mm:ss", - 46: "[h]:mm:ss", - 47: "mm:ss.0", - 48: "##0.0E+0", - 49: "@", -} - -// langNumFmt defined number format code (with unicode values provided for -// language glyphs where they occur) in different language. -var langNumFmt = map[string]map[int]string{ - "zh-tw": { - 27: "[$-404]e/m/d", - 28: `[$-404]e"年"m"月"d"日"`, - 29: `[$-404]e"年"m"月"d"日"`, - 30: "m/d/yy", - 31: `yyyy"年"m"月"d"日"`, - 32: `hh"時"mm"分"`, - 33: `hh"時"mm"分"ss"秒"`, - 34: `上午/下午 hh"時"mm"分"`, - 35: `上午/下午 hh"時"mm"分"ss"秒"`, - 36: "[$-404]e/m/d", - 50: "[$-404]e/m/d", - 51: `[$-404]e"年"m"月"d"日"`, - 52: `上午/下午 hh"時"mm"分"`, - 53: `上午/下午 hh"時"mm"分"ss"秒"`, - 54: `[$-404]e"年"m"月"d"日"`, - 55: `上午/下午 hh"時"mm"分"`, - 56: `上午/下午 hh"時"mm"分"ss"秒"`, - 57: "[$-404]e/m/d", - 58: `[$-404]e"年"m"月"d"日"`, - }, - "zh-cn": { - 27: `yyyy"年"m"月"`, - 28: `m"月"d"日"`, - 29: `m"月"d"日"`, - 30: "m-d-yy", - 31: `yyyy"年"m"月"d"日"`, - 32: `h"时"mm"分"`, - 33: `h"时"mm"分"ss"秒"`, - 34: `上午/下午 h"时"mm"分"`, - 35: `上午/下午 h"时"mm"分"ss"秒"`, - 36: `yyyy"年"m"月"`, - 50: `yyyy"年"m"月"`, - 51: `m"月"d"日"`, - 52: `yyyy"年"m"月"`, - 53: `m"月"d"日"`, - 54: `m"月"d"日"`, - 55: `上午/下午 h"时"mm"分"`, - 56: `上午/下午 h"时"mm"分"ss"秒"`, - 57: `yyyy"年"m"月"`, - 58: `m"月"d"日"`, - }, - "zh-tw_unicode": { - 27: "[$-404]e/m/d", - 28: `[$-404]e"5E74"m"6708"d"65E5"`, - 29: `[$-404]e"5E74"m"6708"d"65E5"`, - 30: "m/d/yy", - 31: `yyyy"5E74"m"6708"d"65E5"`, - 32: `hh"6642"mm"5206"`, - 33: `hh"6642"mm"5206"ss"79D2"`, - 34: `4E0A5348/4E0B5348hh"6642"mm"5206"`, - 35: `4E0A5348/4E0B5348hh"6642"mm"5206"ss"79D2"`, - 36: "[$-404]e/m/d", - 50: "[$-404]e/m/d", - 51: `[$-404]e"5E74"m"6708"d"65E5"`, - 52: `4E0A5348/4E0B5348hh"6642"mm"5206"`, - 53: `4E0A5348/4E0B5348hh"6642"mm"5206"ss"79D2"`, - 54: `[$-404]e"5E74"m"6708"d"65E5"`, - 55: `4E0A5348/4E0B5348hh"6642"mm"5206"`, - 56: `4E0A5348/4E0B5348hh"6642"mm"5206"ss"79D2"`, - 57: "[$-404]e/m/d", - 58: `[$-404]e"5E74"m"6708"d"65E5"`, - }, - "zh-cn_unicode": { - 27: `yyyy"5E74"m"6708"`, - 28: `m"6708"d"65E5"`, - 29: `m"6708"d"65E5"`, - 30: "m-d-yy", - 31: `yyyy"5E74"m"6708"d"65E5"`, - 32: `h"65F6"mm"5206"`, - 33: `h"65F6"mm"5206"ss"79D2"`, - 34: `4E0A5348/4E0B5348h"65F6"mm"5206"`, - 35: `4E0A5348/4E0B5348h"65F6"mm"5206"ss"79D2"`, - 36: `yyyy"5E74"m"6708"`, - 50: `yyyy"5E74"m"6708"`, - 51: `m"6708"d"65E5"`, - 52: `yyyy"5E74"m"6708"`, - 53: `m"6708"d"65E5"`, - 54: `m"6708"d"65E5"`, - 55: `4E0A5348/4E0B5348h"65F6"mm"5206"`, - 56: `4E0A5348/4E0B5348h"65F6"mm"5206"ss"79D2"`, - 57: `yyyy"5E74"m"6708"`, - 58: `m"6708"d"65E5"`, - }, - "ja-jp": { - 27: "[$-411]ge.m.d", - 28: `[$-411]ggge"年"m"月"d"日"`, - 29: `[$-411]ggge"年"m"月"d"日"`, - 30: "m/d/yy", - 31: `yyyy"年"m"月"d"日"`, - 32: `h"時"mm"分"`, - 33: `h"時"mm"分"ss"秒"`, - 34: `yyyy"年"m"月"`, - 35: `m"月"d"日"`, - 36: "[$-411]ge.m.d", - 50: "[$-411]ge.m.d", - 51: `[$-411]ggge"年"m"月"d"日"`, - 52: `yyyy"年"m"月"`, - 53: `m"月"d"日"`, - 54: `[$-411]ggge"年"m"月"d"日"`, - 55: `yyyy"年"m"月"`, - 56: `m"月"d"日"`, - 57: "[$-411]ge.m.d", - 58: `[$-411]ggge"年"m"月"d"日"`, - }, - "ko-kr": { - 27: `yyyy"年" mm"月" dd"日"`, - 28: "mm-dd", - 29: "mm-dd", - 30: "mm-dd-yy", - 31: `yyyy"년" mm"월" dd"일"`, - 32: `h"시" mm"분"`, - 33: `h"시" mm"분" ss"초"`, - 34: `yyyy-mm-dd`, - 35: `yyyy-mm-dd`, - 36: `yyyy"年" mm"月" dd"日"`, - 50: `yyyy"年" mm"月" dd"日"`, - 51: "mm-dd", - 52: "yyyy-mm-dd", - 53: "yyyy-mm-dd", - 54: "mm-dd", - 55: "yyyy-mm-dd", - 56: "yyyy-mm-dd", - 57: `yyyy"年" mm"月" dd"日"`, - 58: "mm-dd", - }, - "ja-jp_unicode": { - 27: "[$-411]ge.m.d", - 28: `[$-411]ggge"5E74"m"6708"d"65E5"`, - 29: `[$-411]ggge"5E74"m"6708"d"65E5"`, - 30: "m/d/yy", - 31: `yyyy"5E74"m"6708"d"65E5"`, - 32: `h"6642"mm"5206"`, - 33: `h"6642"mm"5206"ss"79D2"`, - 34: `yyyy"5E74"m"6708"`, - 35: `m"6708"d"65E5"`, - 36: "[$-411]ge.m.d", - 50: "[$-411]ge.m.d", - 51: `[$-411]ggge"5E74"m"6708"d"65E5"`, - 52: `yyyy"5E74"m"6708"`, - 53: `m"6708"d"65E5"`, - 54: `[$-411]ggge"5E74"m"6708"d"65E5"`, - 55: `yyyy"5E74"m"6708"`, - 56: `m"6708"d"65E5"`, - 57: "[$-411]ge.m.d", - 58: `[$-411]ggge"5E74"m"6708"d"65E5"`, - }, - "ko-kr_unicode": { - 27: `yyyy"5E74" mm"6708" dd"65E5"`, - 28: "mm-dd", - 29: "mm-dd", - 30: "mm-dd-yy", - 31: `yyyy"B144" mm"C6D4" dd"C77C"`, - 32: `h"C2DC" mm"BD84"`, - 33: `h"C2DC" mm"BD84" ss"CD08"`, - 34: "yyyy-mm-dd", - 35: "yyyy-mm-dd", - 36: `yyyy"5E74" mm"6708" dd"65E5"`, - 50: `yyyy"5E74" mm"6708" dd"65E5"`, - 51: "mm-dd", - 52: "yyyy-mm-dd", - 53: "yyyy-mm-dd", - 54: "mm-dd", - 55: "yyyy-mm-dd", - 56: "yyyy-mm-dd", - 57: `yyyy"5E74" mm"6708" dd"65E5"`, - 58: "mm-dd", - }, - "th-th": { - 59: "t0", - 60: "t0.00", - 61: "t#,##0", - 62: "t#,##0.00", - 67: "t0%", - 68: "t0.00%", - 69: "t# ?/?", - 70: "t# ??/??", - 71: "ว/ด/ปปปป", - 72: "ว-ดดด-ปป", - 73: "ว-ดดด", - 74: "ดดด-ปป", - 75: "ช:นน", - 76: "ช:นน:ทท", - 77: "ว/ด/ปปปป ช:นน", - 78: "นน:ทท", - 79: "[ช]:นน:ทท", - 80: "นน:ทท.0", - 81: "d/m/bb", - }, - "th-th_unicode": { - 59: "t0", - 60: "t0.00", - 61: "t#,##0", - 62: "t#,##0.00", - 67: "t0%", - 68: "t0.00%", - 69: "t# ?/?", - 70: "t# ??/??", - 71: "0E27/0E14/0E1B0E1B0E1B0E1B", - 72: "0E27-0E140E140E14-0E1B0E1B", - 73: "0E27-0E140E140E14", - 74: "0E140E140E14-0E1B0E1B", - 75: "0E0A:0E190E19", - 76: "0E0A:0E190E19:0E170E17", - 77: "0E27/0E14/0E1B0E1B0E1B0E1B 0E0A:0E190E19", - 78: "0E190E19:0E170E17", - 79: "[0E0A]:0E190E19:0E170E17", - 80: "0E190E19:0E170E17.0", - 81: "d/m/bb", - }, -} - -// currencyNumFmt defined the currency number format map. -var currencyNumFmt = map[int]string{ - 164: `"¥"#,##0.00`, - 165: "[$$-409]#,##0.00", - 166: "[$$-45C]#,##0.00", - 167: "[$$-1004]#,##0.00", - 168: "[$$-404]#,##0.00", - 169: "[$$-C09]#,##0.00", - 170: "[$$-2809]#,##0.00", - 171: "[$$-1009]#,##0.00", - 172: "[$$-2009]#,##0.00", - 173: "[$$-1409]#,##0.00", - 174: "[$$-4809]#,##0.00", - 175: "[$$-2C09]#,##0.00", - 176: "[$$-2409]#,##0.00", - 177: "[$$-1000]#,##0.00", - 178: `#,##0.00\ [$$-C0C]`, - 179: "[$$-475]#,##0.00", - 180: "[$$-83E]#,##0.00", - 181: `[$$-86B]\ #,##0.00`, - 182: `[$$-340A]\ #,##0.00`, - 183: "[$$-240A]#,##0.00", - 184: `[$$-300A]\ #,##0.00`, - 185: "[$$-440A]#,##0.00", - 186: "[$$-80A]#,##0.00", - 187: "[$$-500A]#,##0.00", - 188: "[$$-540A]#,##0.00", - 189: `[$$-380A]\ #,##0.00`, - 190: "[$£-809]#,##0.00", - 191: "[$£-491]#,##0.00", - 192: "[$£-452]#,##0.00", - 193: "[$¥-804]#,##0.00", - 194: "[$¥-411]#,##0.00", - 195: "[$¥-478]#,##0.00", - 196: "[$¥-451]#,##0.00", - 197: "[$¥-480]#,##0.00", - 198: "#,##0.00\\ [$\u058F-42B]", - 199: "[$\u060B-463]#,##0.00", - 200: "[$\u060B-48C]#,##0.00", - 201: "[$\u09F3-845]\\ #,##0.00", - 202: "#,##0.00[$\u17DB-453]", - 203: "[$\u20A1-140A]#,##0.00", - 204: "[$\u20A6-468]\\ #,##0.00", - 205: "[$\u20A6-470]\\ #,##0.00", - 206: "[$\u20A9-412]#,##0.00", - 207: "[$\u20AA-40D]\\ #,##0.00", - 208: "#,##0.00\\ [$\u20AB-42A]", - 209: "#,##0.00\\ [$\u20AC-42D]", - 210: "#,##0.00\\ [$\u20AC-47E]", - 211: "#,##0.00\\ [$\u20AC-403]", - 212: "#,##0.00\\ [$\u20AC-483]", - 213: "[$\u20AC-813]\\ #,##0.00", - 214: "[$\u20AC-413]\\ #,##0.00", - 215: "[$\u20AC-1809]#,##0.00", - 216: "#,##0.00\\ [$\u20AC-425]", - 217: "[$\u20AC-2]\\ #,##0.00", - 218: "#,##0.00\\ [$\u20AC-1]", - 219: "#,##0.00\\ [$\u20AC-40B]", - 220: "#,##0.00\\ [$\u20AC-80C]", - 221: "#,##0.00\\ [$\u20AC-40C]", - 222: "#,##0.00\\ [$\u20AC-140C]", - 223: "#,##0.00\\ [$\u20AC-180C]", - 224: "[$\u20AC-200C]#,##0.00", - 225: "#,##0.00\\ [$\u20AC-456]", - 226: "#,##0.00\\ [$\u20AC-C07]", - 227: "#,##0.00\\ [$\u20AC-407]", - 228: "#,##0.00\\ [$\u20AC-1007]", - 229: "#,##0.00\\ [$\u20AC-408]", - 230: "#,##0.00\\ [$\u20AC-243B]", - 231: "[$\u20AC-83C]#,##0.00", - 232: "[$\u20AC-410]\\ #,##0.00", - 233: "[$\u20AC-476]#,##0.00", - 234: "#,##0.00\\ [$\u20AC-2C1A]", - 235: "[$\u20AC-426]\\ #,##0.00", - 236: "#,##0.00\\ [$\u20AC-427]", - 237: "#,##0.00\\ [$\u20AC-82E]", - 238: "#,##0.00\\ [$\u20AC-46E]", - 239: "[$\u20AC-43A]#,##0.00", - 240: "#,##0.00\\ [$\u20AC-C3B]", - 241: "#,##0.00\\ [$\u20AC-482]", - 242: "#,##0.00\\ [$\u20AC-816]", - 243: "#,##0.00\\ [$\u20AC-301A]", - 244: "#,##0.00\\ [$\u20AC-203B]", - 245: "#,##0.00\\ [$\u20AC-41B]", - 246: "#,##0.00\\ [$\u20AC-424]", - 247: "#,##0.00\\ [$\u20AC-C0A]", - 248: "#,##0.00\\ [$\u20AC-81D]", - 249: "#,##0.00\\ [$\u20AC-484]", - 250: "#,##0.00\\ [$\u20AC-42E]", - 251: "[$\u20AC-462]\\ #,##0.00", - 252: "#,##0.00\\ [$₭-454]", - 253: "#,##0.00\\ [$₮-450]", - 254: "[$\u20AE-C50]#,##0.00", - 255: "[$\u20B1-3409]#,##0.00", - 256: "[$\u20B1-464]#,##0.00", - 257: "#,##0.00[$\u20B4-422]", - 258: "[$\u20B8-43F]#,##0.00", - 259: "[$\u20B9-460]#,##0.00", - 260: "[$\u20B9-4009]\\ #,##0.00", - 261: "[$\u20B9-447]\\ #,##0.00", - 262: "[$\u20B9-439]\\ #,##0.00", - 263: "[$\u20B9-44B]\\ #,##0.00", - 264: "[$\u20B9-860]#,##0.00", - 265: "[$\u20B9-457]\\ #,##0.00", - 266: "[$\u20B9-458]#,##0.00", - 267: "[$\u20B9-44E]\\ #,##0.00", - 268: "[$\u20B9-861]#,##0.00", - 269: "[$\u20B9-448]\\ #,##0.00", - 270: "[$\u20B9-446]\\ #,##0.00", - 271: "[$\u20B9-44F]\\ #,##0.00", - 272: "[$\u20B9-459]#,##0.00", - 273: "[$\u20B9-449]\\ #,##0.00", - 274: "[$\u20B9-820]#,##0.00", - 275: "#,##0.00\\ [$\u20BA-41F]", - 276: "#,##0.00\\ [$\u20BC-42C]", - 277: "#,##0.00\\ [$\u20BC-82C]", - 278: "#,##0.00\\ [$\u20BD-419]", - 279: "#,##0.00[$\u20BD-485]", - 280: "#,##0.00\\ [$\u20BE-437]", - 281: "[$B/.-180A]\\ #,##0.00", - 282: "[$Br-472]#,##0.00", - 283: "[$Br-477]#,##0.00", - 284: "#,##0.00[$Br-473]", - 285: "[$Bs-46B]\\ #,##0.00", - 286: "[$Bs-400A]\\ #,##0.00", - 287: "[$Bs.-200A]\\ #,##0.00", - 288: "[$BWP-832]\\ #,##0.00", - 289: "[$C$-4C0A]#,##0.00", - 290: "[$CA$-85D]#,##0.00", - 291: "[$CA$-47C]#,##0.00", - 292: "[$CA$-45D]#,##0.00", - 293: "[$CFA-340C]#,##0.00", - 294: "[$CFA-280C]#,##0.00", - 295: "#,##0.00\\ [$CFA-867]", - 296: "#,##0.00\\ [$CFA-488]", - 297: "#,##0.00\\ [$CHF-100C]", - 298: "[$CHF-1407]\\ #,##0.00", - 299: "[$CHF-807]\\ #,##0.00", - 300: "[$CHF-810]\\ #,##0.00", - 301: "[$CHF-417]\\ #,##0.00", - 302: "[$CLP-47A]\\ #,##0.00", - 303: "[$CN¥-850]#,##0.00", - 304: "#,##0.00\\ [$DZD-85F]", - 305: "[$FCFA-2C0C]#,##0.00", - 306: "#,##0.00\\ [$Ft-40E]", - 307: "[$G-3C0C]#,##0.00", - 308: "[$Gs.-3C0A]\\ #,##0.00", - 309: "[$GTQ-486]#,##0.00", - 310: "[$HK$-C04]#,##0.00", - 311: "[$HK$-3C09]#,##0.00", - 312: "#,##0.00\\ [$HRK-41A]", - 313: "[$IDR-3809]#,##0.00", - 314: "[$IQD-492]#,##0.00", - 315: "#,##0.00\\ [$ISK-40F]", - 316: "[$K-455]#,##0.00", - 317: "#,##0.00\\ [$K\u010D-405]", - 318: "#,##0.00\\ [$KM-141A]", - 319: "#,##0.00\\ [$KM-101A]", - 320: "#,##0.00\\ [$KM-181A]", - 321: "[$kr-438]\\ #,##0.00", - 322: "[$kr-43B]\\ #,##0.00", - 323: "#,##0.00\\ [$kr-83B]", - 324: "[$kr-414]\\ #,##0.00", - 325: "[$kr-814]\\ #,##0.00", - 326: "#,##0.00\\ [$kr-41D]", - 327: "[$kr.-406]\\ #,##0.00", - 328: "[$kr.-46F]\\ #,##0.00", - 329: "[$Ksh-441]#,##0.00", - 330: "[$L-818]#,##0.00", - 331: "[$L-819]#,##0.00", - 332: "[$L-480A]\\ #,##0.00", - 333: "#,##0.00\\ [$Lek\u00EB-41C]", - 334: "[$MAD-45F]#,##0.00", - 335: "[$MAD-380C]#,##0.00", - 336: "#,##0.00\\ [$MAD-105F]", - 337: "[$MOP$-1404]#,##0.00", - 338: "#,##0.00\\ [$MVR-465]_-", - 339: "#,##0.00[$Nfk-873]", - 340: "[$NGN-466]#,##0.00", - 341: "[$NGN-467]#,##0.00", - 342: "[$NGN-469]#,##0.00", - 343: "[$NGN-471]#,##0.00", - 344: "[$NOK-103B]\\ #,##0.00", - 345: "[$NOK-183B]\\ #,##0.00", - 346: "[$NZ$-481]#,##0.00", - 347: "[$PKR-859]\\ #,##0.00", - 348: "[$PYG-474]#,##0.00", - 349: "[$Q-100A]#,##0.00", - 350: "[$R-436]\\ #,##0.00", - 351: "[$R-1C09]\\ #,##0.00", - 352: "[$R-435]\\ #,##0.00", - 353: "[$R$-416]\\ #,##0.00", - 354: "[$RD$-1C0A]#,##0.00", - 355: "#,##0.00\\ [$RF-487]", - 356: "[$RM-4409]#,##0.00", - 357: "[$RM-43E]#,##0.00", - 358: "#,##0.00\\ [$RON-418]", - 359: "[$Rp-421]#,##0.00", - 360: "[$Rs-420]#,##0.00_-", - 361: "[$Rs.-849]\\ #,##0.00", - 362: "#,##0.00\\ [$RSD-81A]", - 363: "#,##0.00\\ [$RSD-C1A]", - 364: "#,##0.00\\ [$RUB-46D]", - 365: "#,##0.00\\ [$RUB-444]", - 366: "[$S/.-C6B]\\ #,##0.00", - 367: "[$S/.-280A]\\ #,##0.00", - 368: "#,##0.00\\ [$SEK-143B]", - 369: "#,##0.00\\ [$SEK-1C3B]", - 370: "#,##0.00\\ [$so\u02BBm-443]", - 371: "#,##0.00\\ [$so\u02BBm-843]", - 372: "#,##0.00\\ [$SYP-45A]", - 373: "[$THB-41E]#,##0.00", - 374: "#,##0.00[$TMT-442]", - 375: "[$US$-3009]#,##0.00", - 376: "[$ZAR-46C]\\ #,##0.00", - 377: "[$ZAR-430]#,##0.00", - 378: "[$ZAR-431]#,##0.00", - 379: "[$ZAR-432]\\ #,##0.00", - 380: "[$ZAR-433]#,##0.00", - 381: "[$ZAR-434]\\ #,##0.00", - 382: "#,##0.00\\ [$z\u0142-415]", - 383: "#,##0.00\\ [$\u0434\u0435\u043D-42F]", - 384: "#,##0.00\\ [$КМ-201A]", - 385: "#,##0.00\\ [$КМ-1C1A]", - 386: "#,##0.00\\ [$\u043B\u0432.-402]", - 387: "#,##0.00\\ [$р.-423]", - 388: "#,##0.00\\ [$\u0441\u043E\u043C-440]", - 389: "#,##0.00\\ [$\u0441\u043E\u043C-428]", - 390: "[$\u062C.\u0645.-C01]\\ #,##0.00_-", - 391: "[$\u062F.\u0623.-2C01]\\ #,##0.00_-", - 392: "[$\u062F.\u0625.-3801]\\ #,##0.00_-", - 393: "[$\u062F.\u0628.-3C01]\\ #,##0.00_-", - 394: "[$\u062F.\u062A.-1C01]\\ #,##0.00_-", - 395: "[$\u062F.\u062C.-1401]\\ #,##0.00_-", - 396: "[$\u062F.\u0639.-801]\\ #,##0.00_-", - 397: "[$\u062F.\u0643.-3401]\\ #,##0.00_-", - 398: "[$\u062F.\u0644.-1001]#,##0.00_-", - 399: "[$\u062F.\u0645.-1801]\\ #,##0.00_-", - 400: "[$\u0631-846]\\ #,##0.00", - 401: "[$\u0631.\u0633.-401]\\ #,##0.00_-", - 402: "[$\u0631.\u0639.-2001]\\ #,##0.00_-", - 403: "[$\u0631.\u0642.-4001]\\ #,##0.00_-", - 404: "[$\u0631.\u064A.-2401]\\ #,##0.00_-", - 405: "[$\u0631\u06CC\u0627\u0644-429]#,##0.00_-", - 406: "[$\u0644.\u0633.-2801]\\ #,##0.00_-", - 407: "[$\u0644.\u0644.-3001]\\ #,##0.00_-", - 408: "[$\u1265\u122D-45E]#,##0.00", - 409: "[$\u0930\u0942-461]#,##0.00", - 410: "[$\u0DBB\u0DD4.-45B]\\ #,##0.00", - 411: "[$ADP]\\ #,##0.00", - 412: "[$AED]\\ #,##0.00", - 413: "[$AFA]\\ #,##0.00", - 414: "[$AFN]\\ #,##0.00", - 415: "[$ALL]\\ #,##0.00", - 416: "[$AMD]\\ #,##0.00", - 417: "[$ANG]\\ #,##0.00", - 418: "[$AOA]\\ #,##0.00", - 419: "[$ARS]\\ #,##0.00", - 420: "[$ATS]\\ #,##0.00", - 421: "[$AUD]\\ #,##0.00", - 422: "[$AWG]\\ #,##0.00", - 423: "[$AZM]\\ #,##0.00", - 424: "[$AZN]\\ #,##0.00", - 425: "[$BAM]\\ #,##0.00", - 426: "[$BBD]\\ #,##0.00", - 427: "[$BDT]\\ #,##0.00", - 428: "[$BEF]\\ #,##0.00", - 429: "[$BGL]\\ #,##0.00", - 430: "[$BGN]\\ #,##0.00", - 431: "[$BHD]\\ #,##0.00", - 432: "[$BIF]\\ #,##0.00", - 433: "[$BMD]\\ #,##0.00", - 434: "[$BND]\\ #,##0.00", - 435: "[$BOB]\\ #,##0.00", - 436: "[$BOV]\\ #,##0.00", - 437: "[$BRL]\\ #,##0.00", - 438: "[$BSD]\\ #,##0.00", - 439: "[$BTN]\\ #,##0.00", - 440: "[$BWP]\\ #,##0.00", - 441: "[$BYR]\\ #,##0.00", - 442: "[$BZD]\\ #,##0.00", - 443: "[$CAD]\\ #,##0.00", - 444: "[$CDF]\\ #,##0.00", - 445: "[$CHE]\\ #,##0.00", - 446: "[$CHF]\\ #,##0.00", - 447: "[$CHW]\\ #,##0.00", - 448: "[$CLF]\\ #,##0.00", - 449: "[$CLP]\\ #,##0.00", - 450: "[$CNY]\\ #,##0.00", - 451: "[$COP]\\ #,##0.00", - 452: "[$COU]\\ #,##0.00", - 453: "[$CRC]\\ #,##0.00", - 454: "[$CSD]\\ #,##0.00", - 455: "[$CUC]\\ #,##0.00", - 456: "[$CVE]\\ #,##0.00", - 457: "[$CYP]\\ #,##0.00", - 458: "[$CZK]\\ #,##0.00", - 459: "[$DEM]\\ #,##0.00", - 460: "[$DJF]\\ #,##0.00", - 461: "[$DKK]\\ #,##0.00", - 462: "[$DOP]\\ #,##0.00", - 463: "[$DZD]\\ #,##0.00", - 464: "[$ECS]\\ #,##0.00", - 465: "[$ECV]\\ #,##0.00", - 466: "[$EEK]\\ #,##0.00", - 467: "[$EGP]\\ #,##0.00", - 468: "[$ERN]\\ #,##0.00", - 469: "[$ESP]\\ #,##0.00", - 470: "[$ETB]\\ #,##0.00", - 471: "[$EUR]\\ #,##0.00", - 472: "[$FIM]\\ #,##0.00", - 473: "[$FJD]\\ #,##0.00", - 474: "[$FKP]\\ #,##0.00", - 475: "[$FRF]\\ #,##0.00", - 476: "[$GBP]\\ #,##0.00", - 477: "[$GEL]\\ #,##0.00", - 478: "[$GHC]\\ #,##0.00", - 479: "[$GHS]\\ #,##0.00", - 480: "[$GIP]\\ #,##0.00", - 481: "[$GMD]\\ #,##0.00", - 482: "[$GNF]\\ #,##0.00", - 483: "[$GRD]\\ #,##0.00", - 484: "[$GTQ]\\ #,##0.00", - 485: "[$GYD]\\ #,##0.00", - 486: "[$HKD]\\ #,##0.00", - 487: "[$HNL]\\ #,##0.00", - 488: "[$HRK]\\ #,##0.00", - 489: "[$HTG]\\ #,##0.00", - 490: "[$HUF]\\ #,##0.00", - 491: "[$IDR]\\ #,##0.00", - 492: "[$IEP]\\ #,##0.00", - 493: "[$ILS]\\ #,##0.00", - 494: "[$INR]\\ #,##0.00", - 495: "[$IQD]\\ #,##0.00", - 496: "[$IRR]\\ #,##0.00", - 497: "[$ISK]\\ #,##0.00", - 498: "[$ITL]\\ #,##0.00", - 499: "[$JMD]\\ #,##0.00", - 500: "[$JOD]\\ #,##0.00", - 501: "[$JPY]\\ #,##0.00", - 502: "[$KAF]\\ #,##0.00", - 503: "[$KES]\\ #,##0.00", - 504: "[$KGS]\\ #,##0.00", - 505: "[$KHR]\\ #,##0.00", - 506: "[$KMF]\\ #,##0.00", - 507: "[$KPW]\\ #,##0.00", - 508: "[$KRW]\\ #,##0.00", - 509: "[$KWD]\\ #,##0.00", - 510: "[$KYD]\\ #,##0.00", - 511: "[$KZT]\\ #,##0.00", - 512: "[$LAK]\\ #,##0.00", - 513: "[$LBP]\\ #,##0.00", - 514: "[$LKR]\\ #,##0.00", - 515: "[$LRD]\\ #,##0.00", - 516: "[$LSL]\\ #,##0.00", - 517: "[$LTL]\\ #,##0.00", - 518: "[$LUF]\\ #,##0.00", - 519: "[$LVL]\\ #,##0.00", - 520: "[$LYD]\\ #,##0.00", - 521: "[$MAD]\\ #,##0.00", - 522: "[$MDL]\\ #,##0.00", - 523: "[$MGA]\\ #,##0.00", - 524: "[$MGF]\\ #,##0.00", - 525: "[$MKD]\\ #,##0.00", - 526: "[$MMK]\\ #,##0.00", - 527: "[$MNT]\\ #,##0.00", - 528: "[$MOP]\\ #,##0.00", - 529: "[$MRO]\\ #,##0.00", - 530: "[$MTL]\\ #,##0.00", - 531: "[$MUR]\\ #,##0.00", - 532: "[$MVR]\\ #,##0.00", - 533: "[$MWK]\\ #,##0.00", - 534: "[$MXN]\\ #,##0.00", - 535: "[$MXV]\\ #,##0.00", - 536: "[$MYR]\\ #,##0.00", - 537: "[$MZM]\\ #,##0.00", - 538: "[$MZN]\\ #,##0.00", - 539: "[$NAD]\\ #,##0.00", - 540: "[$NGN]\\ #,##0.00", - 541: "[$NIO]\\ #,##0.00", - 542: "[$NLG]\\ #,##0.00", - 543: "[$NOK]\\ #,##0.00", - 544: "[$NPR]\\ #,##0.00", - 545: "[$NTD]\\ #,##0.00", - 546: "[$NZD]\\ #,##0.00", - 547: "[$OMR]\\ #,##0.00", - 548: "[$PAB]\\ #,##0.00", - 549: "[$PEN]\\ #,##0.00", - 550: "[$PGK]\\ #,##0.00", - 551: "[$PHP]\\ #,##0.00", - 552: "[$PKR]\\ #,##0.00", - 553: "[$PLN]\\ #,##0.00", - 554: "[$PTE]\\ #,##0.00", - 555: "[$PYG]\\ #,##0.00", - 556: "[$QAR]\\ #,##0.00", - 557: "[$ROL]\\ #,##0.00", - 558: "[$RON]\\ #,##0.00", - 559: "[$RSD]\\ #,##0.00", - 560: "[$RUB]\\ #,##0.00", - 561: "[$RUR]\\ #,##0.00", - 562: "[$RWF]\\ #,##0.00", - 563: "[$SAR]\\ #,##0.00", - 564: "[$SBD]\\ #,##0.00", - 565: "[$SCR]\\ #,##0.00", - 566: "[$SDD]\\ #,##0.00", - 567: "[$SDG]\\ #,##0.00", - 568: "[$SDP]\\ #,##0.00", - 569: "[$SEK]\\ #,##0.00", - 570: "[$SGD]\\ #,##0.00", - 571: "[$SHP]\\ #,##0.00", - 572: "[$SIT]\\ #,##0.00", - 573: "[$SKK]\\ #,##0.00", - 574: "[$SLL]\\ #,##0.00", - 575: "[$SOS]\\ #,##0.00", - 576: "[$SPL]\\ #,##0.00", - 577: "[$SRD]\\ #,##0.00", - 578: "[$SRG]\\ #,##0.00", - 579: "[$STD]\\ #,##0.00", - 580: "[$SVC]\\ #,##0.00", - 581: "[$SYP]\\ #,##0.00", - 582: "[$SZL]\\ #,##0.00", - 583: "[$THB]\\ #,##0.00", - 584: "[$TJR]\\ #,##0.00", - 585: "[$TJS]\\ #,##0.00", - 586: "[$TMM]\\ #,##0.00", - 587: "[$TMT]\\ #,##0.00", - 588: "[$TND]\\ #,##0.00", - 589: "[$TOP]\\ #,##0.00", - 590: "[$TRL]\\ #,##0.00", - 591: "[$TRY]\\ #,##0.00", - 592: "[$TTD]\\ #,##0.00", - 593: "[$TWD]\\ #,##0.00", - 594: "[$TZS]\\ #,##0.00", - 595: "[$UAH]\\ #,##0.00", - 596: "[$UGX]\\ #,##0.00", - 597: "[$USD]\\ #,##0.00", - 598: "[$USN]\\ #,##0.00", - 599: "[$USS]\\ #,##0.00", - 600: "[$UYI]\\ #,##0.00", - 601: "[$UYU]\\ #,##0.00", - 602: "[$UZS]\\ #,##0.00", - 603: "[$VEB]\\ #,##0.00", - 604: "[$VEF]\\ #,##0.00", - 605: "[$VND]\\ #,##0.00", - 606: "[$VUV]\\ #,##0.00", - 607: "[$WST]\\ #,##0.00", - 608: "[$XAF]\\ #,##0.00", - 609: "[$XAG]\\ #,##0.00", - 610: "[$XAU]\\ #,##0.00", - 611: "[$XB5]\\ #,##0.00", - 612: "[$XBA]\\ #,##0.00", - 613: "[$XBB]\\ #,##0.00", - 614: "[$XBC]\\ #,##0.00", - 615: "[$XBD]\\ #,##0.00", - 616: "[$XCD]\\ #,##0.00", - 617: "[$XDR]\\ #,##0.00", - 618: "[$XFO]\\ #,##0.00", - 619: "[$XFU]\\ #,##0.00", - 620: "[$XOF]\\ #,##0.00", - 621: "[$XPD]\\ #,##0.00", - 622: "[$XPF]\\ #,##0.00", - 623: "[$XPT]\\ #,##0.00", - 624: "[$XTS]\\ #,##0.00", - 625: "[$XXX]\\ #,##0.00", - 626: "[$YER]\\ #,##0.00", - 627: "[$YUM]\\ #,##0.00", - 628: "[$ZAR]\\ #,##0.00", - 629: "[$ZMK]\\ #,##0.00", - 630: "[$ZMW]\\ #,##0.00", - 631: "[$ZWD]\\ #,##0.00", - 632: "[$ZWL]\\ #,##0.00", - 633: "[$ZWN]\\ #,##0.00", - 634: "[$ZWR]\\ #,##0.00", -} - // validType defined the list of valid validation types. var validType = map[string]string{ "cell": "cellIs", @@ -1086,56 +358,6 @@ func parseFormatStyleSet(style *Style) (*Style, error) { // 57 | yyyy"年"m"月 // 58 | m"月"d"日" // -// Number format code with unicode values provided for language glyphs where -// they occur in zh-tw language: -// -// Index | Symbol -// -------+------------------------------------------- -// 27 | [$-404]e/m/ -// 28 | [$-404]e"5E74"m"6708"d"65E5 -// 29 | [$-404]e"5E74"m"6708"d"65E5 -// 30 | m/d/y -// 31 | yyyy"5E74"m"6708"d"65E5 -// 32 | hh"6642"mm"5206 -// 33 | hh"6642"mm"5206"ss"79D2 -// 34 | 4E0A5348/4E0B5348hh"6642"mm"5206 -// 35 | 4E0A5348/4E0B5348hh"6642"mm"5206"ss"79D2 -// 36 | [$-404]e/m/ -// 50 | [$-404]e/m/ -// 51 | [$-404]e"5E74"m"6708"d"65E5 -// 52 | 4E0A5348/4E0B5348hh"6642"mm"5206 -// 53 | 4E0A5348/4E0B5348hh"6642"mm"5206"ss"79D2 -// 54 | [$-404]e"5E74"m"6708"d"65E5 -// 55 | 4E0A5348/4E0B5348hh"6642"mm"5206 -// 56 | 4E0A5348/4E0B5348hh"6642"mm"5206"ss"79D2 -// 57 | [$-404]e/m/ -// 58 | [$-404]e"5E74"m"6708"d"65E5" -// -// Number format code with unicode values provided for language glyphs where -// they occur in zh-cn language: -// -// Index | Symbol -// -------+------------------------------------------- -// 27 | yyyy"5E74"m"6708 -// 28 | m"6708"d"65E5 -// 29 | m"6708"d"65E5 -// 30 | m-d-y -// 31 | yyyy"5E74"m"6708"d"65E5 -// 32 | h"65F6"mm"5206 -// 33 | h"65F6"mm"5206"ss"79D2 -// 34 | 4E0A5348/4E0B5348h"65F6"mm"5206 -// 35 | 4E0A5348/4E0B5348h"65F6"mm"5206"ss"79D2 -// 36 | yyyy"5E74"m"6708 -// 50 | yyyy"5E74"m"6708 -// 51 | m"6708"d"65E5 -// 52 | yyyy"5E74"m"6708 -// 53 | m"6708"d"65E5 -// 54 | m"6708"d"65E5 -// 55 | 4E0A5348/4E0B5348h"65F6"mm"5206 -// 56 | 4E0A5348/4E0B5348h"65F6"mm"5206"ss"79D2 -// 57 | yyyy"5E74"m"6708 -// 58 | m"6708"d"65E5" -// // Number format code in ja-jp language: // // Index | Symbol @@ -1184,56 +406,6 @@ func parseFormatStyleSet(style *Style) (*Style, error) { // 57 | yyyy"年" mm"月" dd"日 // 58 | mm-dd // -// Number format code with unicode values provided for language glyphs where -// they occur in ja-jp language: -// -// Index | Symbol -// -------+------------------------------------------- -// 27 | [$-411]ge.m.d -// 28 | [$-411]ggge"5E74"m"6708"d"65E5 -// 29 | [$-411]ggge"5E74"m"6708"d"65E5 -// 30 | m/d/y -// 31 | yyyy"5E74"m"6708"d"65E5 -// 32 | h"6642"mm"5206 -// 33 | h"6642"mm"5206"ss"79D2 -// 34 | yyyy"5E74"m"6708 -// 35 | m"6708"d"65E5 -// 36 | [$-411]ge.m.d -// 50 | [$-411]ge.m.d -// 51 | [$-411]ggge"5E74"m"6708"d"65E5 -// 52 | yyyy"5E74"m"6708 -// 53 | m"6708"d"65E5 -// 54 | [$-411]ggge"5E74"m"6708"d"65E5 -// 55 | yyyy"5E74"m"6708 -// 56 | m"6708"d"65E5 -// 57 | [$-411]ge.m.d -// 58 | [$-411]ggge"5E74"m"6708"d"65E5" -// -// Number format code with unicode values provided for language glyphs where -// they occur in ko-kr language: -// -// Index | Symbol -// -------+------------------------------------------- -// 27 | yyyy"5E74" mm"6708" dd"65E5 -// 28 | mm-d -// 29 | mm-d -// 30 | mm-dd-y -// 31 | yyyy"B144" mm"C6D4" dd"C77C -// 32 | h"C2DC" mm"BD84 -// 33 | h"C2DC" mm"BD84" ss"CD08 -// 34 | yyyy-mm-d -// 35 | yyyy-mm-d -// 36 | yyyy"5E74" mm"6708" dd"65E5 -// 50 | yyyy"5E74" mm"6708" dd"65E5 -// 51 | mm-d -// 52 | yyyy-mm-d -// 53 | yyyy-mm-d -// 54 | mm-d -// 55 | yyyy-mm-d -// 56 | yyyy-mm-d -// 57 | yyyy"5E74" mm"6708" dd"65E5 -// 58 | mm-dd -// // Number format code in th-th language: // // Index | Symbol @@ -1258,31 +430,6 @@ func parseFormatStyleSet(style *Style) (*Style, error) { // 80 | นน:ทท. // 81 | d/m/bb // -// Number format code with unicode values provided for language glyphs where -// they occur in th-th language: -// -// Index | Symbol -// -------+------------------------------------------- -// 59 | t -// 60 | t0.0 -// 61 | t#,## -// 62 | t#,##0.0 -// 67 | t0 -// 68 | t0.00 -// 69 | t# ?/ -// 70 | t# ??/? -// 71 | 0E27/0E14/0E1B0E1B0E1B0E1 -// 72 | 0E27-0E140E140E14-0E1B0E1 -// 73 | 0E27-0E140E140E1 -// 74 | 0E140E140E14-0E1B0E1 -// 75 | 0E0A:0E190E1 -// 76 | 0E0A:0E190E19:0E170E1 -// 77 | 0E27/0E14/0E1B0E1B0E1B0E1B 0E0A:0E190E1 -// 78 | 0E190E19:0E170E1 -// 79 | [0E0A]:0E190E19:0E170E1 -// 80 | 0E190E19:0E170E17. -// 81 | d/m/bb -// // Excelize built-in currency formats are shown in the following table, only // support these types in the following table (Index number is used only for // markup and is not used inside an Excel file and you can't get formatted value @@ -1858,7 +1005,7 @@ var getXfIDFuncs = map[string]func(int, xlsxXf, *Style) bool{ if style.CustomNumFmt == nil && numFmtID == -1 { return xf.NumFmtID != nil && *xf.NumFmtID == 0 } - if style.NegRed || style.Lang != "" || style.DecimalPlaces != 2 { + if style.NegRed || style.DecimalPlaces != 2 { return false } return xf.NumFmtID != nil && *xf.NumFmtID == numFmtID @@ -2091,11 +1238,9 @@ func getNumFmtID(styleSheet *xlsxStyleSheet, style *Style) (numFmtID int) { if _, ok := builtInNumFmt[style.NumFmt]; ok { return style.NumFmt } - for lang, numFmt := range langNumFmt { - if _, ok := numFmt[style.NumFmt]; ok && lang == style.Lang { - numFmtID = style.NumFmt - return - } + if (27 <= style.NumFmt && style.NumFmt <= 36) || (50 <= style.NumFmt && style.NumFmt <= 81) { + numFmtID = style.NumFmt + return } if fmtCode, ok := currencyNumFmt[style.NumFmt]; ok { numFmtID = style.NumFmt @@ -2199,29 +1344,10 @@ func getCustomNumFmtID(styleSheet *xlsxStyleSheet, style *Style) (customNumFmtID // setLangNumFmt provides a function to set number format code with language. func setLangNumFmt(styleSheet *xlsxStyleSheet, style *Style) int { - numFmts, ok := langNumFmt[style.Lang] - if !ok { - return 0 + if (27 <= style.NumFmt && style.NumFmt <= 36) || (50 <= style.NumFmt && style.NumFmt <= 81) { + return style.NumFmt } - var fc string - fc, ok = numFmts[style.NumFmt] - if !ok { - return 0 - } - nf := xlsxNumFmt{FormatCode: fc} - if styleSheet.NumFmts != nil { - nf.NumFmtID = styleSheet.NumFmts.NumFmt[len(styleSheet.NumFmts.NumFmt)-1].NumFmtID + 1 - styleSheet.NumFmts.NumFmt = append(styleSheet.NumFmts.NumFmt, &nf) - styleSheet.NumFmts.Count++ - } else { - nf.NumFmtID = style.NumFmt - numFmts := xlsxNumFmts{ - NumFmt: []*xlsxNumFmt{&nf}, - Count: 1, - } - styleSheet.NumFmts = &numFmts - } - return nf.NumFmtID + return 0 } // getFillID provides a function to get fill ID. If given fill is not diff --git a/styles_test.go b/styles_test.go index f8ca15e0..af9654fb 100644 --- a/styles_test.go +++ b/styles_test.go @@ -291,9 +291,7 @@ func TestNewStyle(t *testing.T) { // Test create currency custom style f.Styles.NumFmts = nil styleID, err = f.NewStyle(&Style{ - Lang: "ko-kr", NumFmt: 32, // must not be in currencyNumFmt - }) assert.NoError(t, err) assert.Equal(t, 3, styleID) @@ -330,14 +328,14 @@ func TestNewStyle(t *testing.T) { f = NewFile() f.Styles.NumFmts = nil f.Styles.CellXfs.Xf = nil - style4, err := f.NewStyle(&Style{NumFmt: 160, Lang: "unknown"}) + style4, err := f.NewStyle(&Style{NumFmt: 160}) assert.NoError(t, err) assert.Equal(t, 0, style4) f = NewFile() f.Styles.NumFmts = nil f.Styles.CellXfs.Xf = nil - style5, err := f.NewStyle(&Style{NumFmt: 160, Lang: "zh-cn"}) + style5, err := f.NewStyle(&Style{NumFmt: 160}) assert.NoError(t, err) assert.Equal(t, 0, style5) diff --git a/xmlStyles.go b/xmlStyles.go index 437446eb..9700919a 100644 --- a/xmlStyles.go +++ b/xmlStyles.go @@ -371,6 +371,5 @@ type Style struct { NumFmt int DecimalPlaces int CustomNumFmt *string - Lang string NegRed bool }