From 688808b2b4f7bb1f338991c810cd2ee6a7bb1451 Mon Sep 17 00:00:00 2001 From: xuri Date: Mon, 26 Feb 2024 02:22:51 +0800 Subject: [PATCH] This closes #1819, formula calculation engine support array formulas - Improve the defined name and table name validation rules - Rename internal variable names to avoid the same with Go 1.21's built-in min and max functions - Simplify data type conversion in internal code - Update GitHub Actions workflow configuration, test on Go 1.22.x, and disable Go module cache - Update dependencies module --- .github/workflows/go.yml | 3 +- calc.go | 220 +++++++++++++++++++++------------------ col.go | 12 +-- date_test.go | 8 +- drawing.go | 44 ++++---- excelize.go | 14 +-- go.mod | 4 +- go.sum | 8 +- hsl.go | 16 +-- numfmt.go | 176 +++++++++++++++---------------- rows.go | 6 +- stream.go | 12 +-- table.go | 21 ++-- templates.go | 159 +++++++++++++++++++++++++++- 14 files changed, 443 insertions(+), 260 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2743d60..c56feda 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,7 @@ jobs: test: strategy: matrix: - go-version: [1.18.x, 1.19.x, 1.20.x, '>=1.21.1'] + go-version: [1.18.x, 1.19.x, 1.20.x, '>=1.21.1', 1.22.x] os: [ubuntu-latest, macos-latest, windows-latest] targetplatform: [x86, x64] @@ -17,6 +17,7 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} + cache: false - name: Checkout code uses: actions/checkout@v4 diff --git a/calc.go b/calc.go index f03c573..496ecd4 100644 --- a/calc.go +++ b/calc.go @@ -281,6 +281,10 @@ func (fa formulaArg) Value() (value string) { return fmt.Sprintf("%g", fa.Number) case ArgString: return fa.String + case ArgMatrix: + if args := fa.ToList(); len(args) > 0 { + return args[0].Value() + } case ArgError: return fa.Error } @@ -299,6 +303,10 @@ func (fa formulaArg) ToNumber() formulaArg { } case ArgNumber: n = fa.Number + case ArgMatrix: + if args := fa.ToList(); len(args) > 0 { + return args[0].ToNumber() + } } return newNumberFormulaArg(n) } @@ -920,9 +928,14 @@ func newEmptyFormulaArg() formulaArg { // // TODO: handle subtypes: Nothing, Text, Logical, Error, Concatenation, Intersection, Union func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.Token) (formulaArg, error) { - var err error - opdStack, optStack, opfStack, opfdStack, opftStack, argsStack := NewStack(), NewStack(), NewStack(), NewStack(), NewStack(), NewStack() - var inArray, inArrayRow bool + var ( + err error + inArray, inArrayRow bool + formulaArray [][]formulaArg + formulaArrayRow []formulaArg + opdStack, optStack, opfStack = NewStack(), NewStack(), NewStack() + opfdStack, opftStack, argsStack = NewStack(), NewStack(), NewStack() + ) for i := 0; i < len(tokens); i++ { token := tokens[i] @@ -936,11 +949,11 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T // function start if isFunctionStartToken(token) { if token.TValue == "ARRAY" { - inArray = true + inArray, formulaArray = true, [][]formulaArg{} continue } if token.TValue == "ARRAYROW" { - inArrayRow = true + inArrayRow, formulaArrayRow = true, []formulaArg{} continue } opfStack.Push(token) @@ -1021,14 +1034,16 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T } if inArrayRow && isOperand(token) { + formulaArrayRow = append(formulaArrayRow, opfdStack.Pop().(formulaArg)) continue } if inArrayRow && isFunctionStopToken(token) { + formulaArray = append(formulaArray, formulaArrayRow) inArrayRow = false continue } if inArray && isFunctionStopToken(token) { - argsStack.Peek().(*list.List).PushBack(opfdStack.Pop()) + argsStack.Peek().(*list.List).PushBack(newMatrixFormulaArg(formulaArray)) inArray = false continue } @@ -1825,13 +1840,13 @@ func (fn *formulaFuncs) bassel(argsList *list.List, modfied bool) formulaArg { if n.Type != ArgNumber { return n } - max, x1 := 100, x.Number*0.5 + maxVal, x1 := 100, x.Number*0.5 x2 := x1 * x1 x1 = math.Pow(x1, n.Number) n1, n2, n3, n4, add := fact(n.Number), 1.0, 0.0, n.Number, false result := x1 / n1 t := result * 0.9 - for result != t && max != 0 { + for result != t && maxVal != 0 { x1 *= x2 n3++ n1 *= n3 @@ -1844,7 +1859,7 @@ func (fn *formulaFuncs) bassel(argsList *list.List, modfied bool) formulaArg { } else { result -= r } - max-- + maxVal-- add = !add } return newNumberFormulaArg(result) @@ -2151,8 +2166,8 @@ func (fn *formulaFuncs) bitwise(name string, argsList *list.List) formulaArg { if num1.Type != ArgNumber || num2.Type != ArgNumber { return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) } - max := math.Pow(2, 48) - 1 - if num1.Number < 0 || num1.Number > max || num2.Number < 0 || num2.Number > max { + maxVal := math.Pow(2, 48) - 1 + if num1.Number < 0 || num1.Number > maxVal || num2.Number < 0 || num2.Number > maxVal { return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) } bitwiseFuncMap := map[string]func(a, b int) int{ @@ -6958,9 +6973,9 @@ func (fn *formulaFuncs) BETAdotINV(argsList *list.List) formulaArg { // incompleteGamma is an implementation of the incomplete gamma function. func incompleteGamma(a, x float64) float64 { - max := 32 + maxVal := 32 summer := 0.0 - for n := 0; n <= max; n++ { + for n := 0; n <= maxVal; n++ { divisor := a for i := 1; i <= n; i++ { divisor *= a + float64(i) @@ -7079,7 +7094,7 @@ func (fn *formulaFuncs) BINOMdotDISTdotRANGE(argsList *list.List) formulaArg { // binominv implement inverse of the binomial distribution calculation. func binominv(n, p, alpha float64) float64 { - q, i, sum, max := 1-p, 0.0, 0.0, 0.0 + q, i, sum, maxVal := 1-p, 0.0, 0.0, 0.0 n = math.Floor(n) if q > p { factor := math.Pow(q, n) @@ -7091,8 +7106,8 @@ func binominv(n, p, alpha float64) float64 { return i } factor := math.Pow(p, n) - sum, max = 1-factor, n - for i = 0; i < max && sum >= alpha; i++ { + sum, maxVal = 1-factor, n + for i = 0; i < maxVal && sum >= alpha; i++ { factor *= (n - i) / (i + 1) * q / p sum -= factor } @@ -8078,10 +8093,13 @@ func (fn *formulaFuncs) FORECASTdotLINEAR(argsList *list.List) formulaArg { return fn.pearsonProduct("FORECAST.LINEAR", 3, argsList) } -// maritxToSortedColumnList convert matrix formula arguments to a ascending +// matrixToSortedColumnList convert matrix formula arguments to a ascending // order list by column. -func maritxToSortedColumnList(arg formulaArg) formulaArg { - mtx, cols := []formulaArg{}, len(arg.Matrix[0]) +func matrixToSortedColumnList(arg formulaArg) formulaArg { + var ( + mtx []formulaArg + cols = len(arg.Matrix[0]) + ) for colIdx := 0; colIdx < cols; colIdx++ { for _, row := range arg.Matrix { cell := row[colIdx] @@ -8120,14 +8138,14 @@ func (fn *formulaFuncs) FREQUENCY(argsList *list.List) formulaArg { c [][]formulaArg i, j int ) - if dataMtx = maritxToSortedColumnList(data); dataMtx.Type != ArgList { + if dataMtx = matrixToSortedColumnList(data); dataMtx.Type != ArgList { return dataMtx } - if binsMtx = maritxToSortedColumnList(bins); binsMtx.Type != ArgList { + if binsMtx = matrixToSortedColumnList(bins); binsMtx.Type != ArgList { return binsMtx } for row := 0; row < len(binsMtx.List)+1; row++ { - rows := []formulaArg{} + var rows []formulaArg for col := 0; col < 1; col++ { rows = append(rows, newNumberFormulaArg(0)) } @@ -8349,8 +8367,8 @@ func (fn *formulaFuncs) GEOMEAN(argsList *list.List) formulaArg { return product } count := fn.COUNT(argsList) - min := fn.MIN(argsList) - if product.Number > 0 && min.Number > 0 { + minVal := fn.MIN(argsList) + if product.Number > 0 && minVal.Number > 0 { return newNumberFormulaArg(math.Pow(product.Number, 1/count.Number)) } return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) @@ -9055,7 +9073,7 @@ func (fn *formulaFuncs) HARMEAN(argsList *list.List) formulaArg { if argsList.Len() < 1 { return newErrorFormulaArg(formulaErrorVALUE, "HARMEAN requires at least 1 argument") } - if min := fn.MIN(argsList); min.Number < 0 { + if minVal := fn.MIN(argsList); minVal.Number < 0 { return newErrorFormulaArg(formulaErrorNA, formulaErrorNA) } number, val, cnt := 0.0, 0.0, 0.0 @@ -10002,7 +10020,7 @@ func (fn *formulaFuncs) MAX(argsList *list.List) formulaArg { if argsList.Len() == 0 { return newErrorFormulaArg(formulaErrorVALUE, "MAX requires at least 1 argument") } - return fn.max(false, argsList) + return fn.maxValue(false, argsList) } // MAXA function returns the largest value from a supplied set of numeric @@ -10015,7 +10033,7 @@ func (fn *formulaFuncs) MAXA(argsList *list.List) formulaArg { if argsList.Len() == 0 { return newErrorFormulaArg(formulaErrorVALUE, "MAXA requires at least 1 argument") } - return fn.max(true, argsList) + return fn.maxValue(true, argsList) } // MAXIFS function returns the maximum value from a subset of values that are @@ -10031,36 +10049,36 @@ func (fn *formulaFuncs) MAXIFS(argsList *list.List) formulaArg { return newErrorFormulaArg(formulaErrorNA, formulaErrorNA) } var args []formulaArg - max, maxRange := -math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix + maxVal, maxRange := -math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() { args = append(args, arg.Value.(formulaArg)) } for _, ref := range formulaIfsMatch(args) { - if num := maxRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && max < num.Number { - max = num.Number + if num := maxRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && maxVal < num.Number { + maxVal = num.Number } } - if max == -math.MaxFloat64 { - max = 0 + if maxVal == -math.MaxFloat64 { + maxVal = 0 } - return newNumberFormulaArg(max) + return newNumberFormulaArg(maxVal) } // calcListMatrixMax is part of the implementation max. -func calcListMatrixMax(maxa bool, max float64, arg formulaArg) float64 { +func calcListMatrixMax(maxa bool, maxVal float64, arg formulaArg) float64 { for _, cell := range arg.ToList() { - if cell.Type == ArgNumber && cell.Number > max { + if cell.Type == ArgNumber && cell.Number > maxVal { if maxa && cell.Boolean || !cell.Boolean { - max = cell.Number + maxVal = cell.Number } } } - return max + return maxVal } -// max is an implementation of the formula functions MAX and MAXA. -func (fn *formulaFuncs) max(maxa bool, argsList *list.List) formulaArg { - max := -math.MaxFloat64 +// maxValue is an implementation of the formula functions MAX and MAXA. +func (fn *formulaFuncs) maxValue(maxa bool, argsList *list.List) formulaArg { + maxVal := -math.MaxFloat64 for token := argsList.Front(); token != nil; token = token.Next() { arg := token.Value.(formulaArg) switch arg.Type { @@ -10069,29 +10087,29 @@ func (fn *formulaFuncs) max(maxa bool, argsList *list.List) formulaArg { continue } else { num := arg.ToBool() - if num.Type == ArgNumber && num.Number > max { - max = num.Number + if num.Type == ArgNumber && num.Number > maxVal { + maxVal = num.Number continue } } num := arg.ToNumber() - if num.Type != ArgError && num.Number > max { - max = num.Number + if num.Type != ArgError && num.Number > maxVal { + maxVal = num.Number } case ArgNumber: - if arg.Number > max { - max = arg.Number + if arg.Number > maxVal { + maxVal = arg.Number } case ArgList, ArgMatrix: - max = calcListMatrixMax(maxa, max, arg) + maxVal = calcListMatrixMax(maxa, maxVal, arg) case ArgError: return arg } } - if max == -math.MaxFloat64 { - max = 0 + if maxVal == -math.MaxFloat64 { + maxVal = 0 } - return newNumberFormulaArg(max) + return newNumberFormulaArg(maxVal) } // MEDIAN function returns the statistical median (the middle value) of a list @@ -10145,7 +10163,7 @@ func (fn *formulaFuncs) MIN(argsList *list.List) formulaArg { if argsList.Len() == 0 { return newErrorFormulaArg(formulaErrorVALUE, "MIN requires at least 1 argument") } - return fn.min(false, argsList) + return fn.minValue(false, argsList) } // MINA function returns the smallest value from a supplied set of numeric @@ -10158,7 +10176,7 @@ func (fn *formulaFuncs) MINA(argsList *list.List) formulaArg { if argsList.Len() == 0 { return newErrorFormulaArg(formulaErrorVALUE, "MINA requires at least 1 argument") } - return fn.min(true, argsList) + return fn.minValue(true, argsList) } // MINIFS function returns the minimum value from a subset of values that are @@ -10174,36 +10192,36 @@ func (fn *formulaFuncs) MINIFS(argsList *list.List) formulaArg { return newErrorFormulaArg(formulaErrorNA, formulaErrorNA) } var args []formulaArg - min, minRange := math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix + minVal, minRange := math.MaxFloat64, argsList.Front().Value.(formulaArg).Matrix for arg := argsList.Front().Next(); arg != nil; arg = arg.Next() { args = append(args, arg.Value.(formulaArg)) } for _, ref := range formulaIfsMatch(args) { - if num := minRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && min > num.Number { - min = num.Number + if num := minRange[ref.Row][ref.Col].ToNumber(); num.Type == ArgNumber && minVal > num.Number { + minVal = num.Number } } - if min == math.MaxFloat64 { - min = 0 + if minVal == math.MaxFloat64 { + minVal = 0 } - return newNumberFormulaArg(min) + return newNumberFormulaArg(minVal) } // calcListMatrixMin is part of the implementation min. -func calcListMatrixMin(mina bool, min float64, arg formulaArg) float64 { +func calcListMatrixMin(mina bool, minVal float64, arg formulaArg) float64 { for _, cell := range arg.ToList() { - if cell.Type == ArgNumber && cell.Number < min { + if cell.Type == ArgNumber && cell.Number < minVal { if mina && cell.Boolean || !cell.Boolean { - min = cell.Number + minVal = cell.Number } } } - return min + return minVal } -// min is an implementation of the formula functions MIN and MINA. -func (fn *formulaFuncs) min(mina bool, argsList *list.List) formulaArg { - min := math.MaxFloat64 +// minValue is an implementation of the formula functions MIN and MINA. +func (fn *formulaFuncs) minValue(mina bool, argsList *list.List) formulaArg { + minVal := math.MaxFloat64 for token := argsList.Front(); token != nil; token = token.Next() { arg := token.Value.(formulaArg) switch arg.Type { @@ -10212,29 +10230,29 @@ func (fn *formulaFuncs) min(mina bool, argsList *list.List) formulaArg { continue } else { num := arg.ToBool() - if num.Type == ArgNumber && num.Number < min { - min = num.Number + if num.Type == ArgNumber && num.Number < minVal { + minVal = num.Number continue } } num := arg.ToNumber() - if num.Type != ArgError && num.Number < min { - min = num.Number + if num.Type != ArgError && num.Number < minVal { + minVal = num.Number } case ArgNumber: - if arg.Number < min { - min = arg.Number + if arg.Number < minVal { + minVal = arg.Number } case ArgList, ArgMatrix: - min = calcListMatrixMin(mina, min, arg) + minVal = calcListMatrixMin(mina, minVal, arg) case ArgError: return arg } } - if min == math.MaxFloat64 { - min = 0 + if minVal == math.MaxFloat64 { + minVal = 0 } - return newNumberFormulaArg(min) + return newNumberFormulaArg(minVal) } // pearsonProduct is an implementation of the formula functions FORECAST, @@ -13554,7 +13572,7 @@ func (fn *formulaFuncs) code(name string, argsList *list.List) formulaArg { // // CONCAT(text1,[text2],...) func (fn *formulaFuncs) CONCAT(argsList *list.List) formulaArg { - return fn.concat("CONCAT", argsList) + return fn.concat(argsList) } // CONCATENATE function joins together a series of supplied text strings into @@ -13562,12 +13580,12 @@ func (fn *formulaFuncs) CONCAT(argsList *list.List) formulaArg { // // CONCATENATE(text1,[text2],...) func (fn *formulaFuncs) CONCATENATE(argsList *list.List) formulaArg { - return fn.concat("CONCATENATE", argsList) + return fn.concat(argsList) } // concat is an implementation of the formula functions CONCAT and // CONCATENATE. -func (fn *formulaFuncs) concat(name string, argsList *list.List) formulaArg { +func (fn *formulaFuncs) concat(argsList *list.List) formulaArg { var buf bytes.Buffer for arg := argsList.Front(); arg != nil; arg = arg.Next() { for _, cell := range arg.Value.(formulaArg).ToList() { @@ -13831,16 +13849,16 @@ func (fn *formulaFuncs) LENB(argsList *list.List) formulaArg { if argsList.Len() != 1 { return newErrorFormulaArg(formulaErrorVALUE, "LENB requires 1 string argument") } - bytes := 0 + result := 0 for _, r := range argsList.Front().Value.(formulaArg).Value() { b := utf8.RuneLen(r) if b == 1 { - bytes++ + result++ } else if b > 1 { - bytes += 2 + result += 2 } } - return newNumberFormulaArg(float64(bytes)) + return newNumberFormulaArg(float64(result)) } // LOWER converts all characters in a supplied text string to lower case. The @@ -14774,7 +14792,7 @@ func (fn *formulaFuncs) COLUMN(argsList *list.List) formulaArg { // calcColsRowsMinMax calculation min and max value for given formula arguments // sequence of the formula functions COLUMNS and ROWS. -func calcColsRowsMinMax(cols bool, argsList *list.List) (min, max int) { +func calcColsRowsMinMax(cols bool, argsList *list.List) (minVal, maxVal int) { getVal := func(cols bool, cell cellRef) int { if cols { return cell.Col @@ -14784,22 +14802,22 @@ func calcColsRowsMinMax(cols bool, argsList *list.List) (min, max int) { if argsList.Front().Value.(formulaArg).cellRanges != nil && argsList.Front().Value.(formulaArg).cellRanges.Len() > 0 { crs := argsList.Front().Value.(formulaArg).cellRanges for cr := crs.Front(); cr != nil; cr = cr.Next() { - if min == 0 { - min = getVal(cols, cr.Value.(cellRange).From) + if minVal == 0 { + minVal = getVal(cols, cr.Value.(cellRange).From) } - if max < getVal(cols, cr.Value.(cellRange).To) { - max = getVal(cols, cr.Value.(cellRange).To) + if maxVal < getVal(cols, cr.Value.(cellRange).To) { + maxVal = getVal(cols, cr.Value.(cellRange).To) } } } if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 { cr := argsList.Front().Value.(formulaArg).cellRefs for refs := cr.Front(); refs != nil; refs = refs.Next() { - if min == 0 { - min = getVal(cols, refs.Value.(cellRef)) + if minVal == 0 { + minVal = getVal(cols, refs.Value.(cellRef)) } - if max < getVal(cols, refs.Value.(cellRef)) { - max = getVal(cols, refs.Value.(cellRef)) + if maxVal < getVal(cols, refs.Value.(cellRef)) { + maxVal = getVal(cols, refs.Value.(cellRef)) } } } @@ -14814,13 +14832,13 @@ func (fn *formulaFuncs) COLUMNS(argsList *list.List) formulaArg { if argsList.Len() != 1 { return newErrorFormulaArg(formulaErrorVALUE, "COLUMNS requires 1 argument") } - min, max := calcColsRowsMinMax(true, argsList) - if max == MaxColumns { + minVal, maxVal := calcColsRowsMinMax(true, argsList) + if maxVal == MaxColumns { return newNumberFormulaArg(float64(MaxColumns)) } - result := max - min + 1 - if max == min { - if min == 0 { + result := maxVal - minVal + 1 + if maxVal == minVal { + if minVal == 0 { return newErrorFormulaArg(formulaErrorVALUE, "invalid reference") } return newNumberFormulaArg(float64(1)) @@ -15555,13 +15573,13 @@ func (fn *formulaFuncs) ROWS(argsList *list.List) formulaArg { if argsList.Len() != 1 { return newErrorFormulaArg(formulaErrorVALUE, "ROWS requires 1 argument") } - min, max := calcColsRowsMinMax(false, argsList) - if max == TotalRows { + minVal, maxVal := calcColsRowsMinMax(false, argsList) + if maxVal == TotalRows { return newNumberFormulaArg(TotalRows) } - result := max - min + 1 - if max == min { - if min == 0 { + result := maxVal - minVal + 1 + if maxVal == minVal { + if minVal == 0 { return newErrorFormulaArg(formulaErrorVALUE, "invalid reference") } return newNumberFormulaArg(float64(1)) diff --git a/col.go b/col.go index c51fdad..b1b9c0d 100644 --- a/col.go +++ b/col.go @@ -354,20 +354,20 @@ func (f *File) GetColOutlineLevel(sheet, col string) (uint8, error) { } // parseColRange parse and convert column range with column name to the column number. -func (f *File) parseColRange(columns string) (min, max int, err error) { +func (f *File) parseColRange(columns string) (minVal, maxVal int, err error) { colsTab := strings.Split(columns, ":") - min, err = ColumnNameToNumber(colsTab[0]) + minVal, err = ColumnNameToNumber(colsTab[0]) if err != nil { return } - max = min + maxVal = minVal if len(colsTab) == 2 { - if max, err = ColumnNameToNumber(colsTab[1]); err != nil { + if maxVal, err = ColumnNameToNumber(colsTab[1]); err != nil { return } } - if max < min { - min, max = max, min + if maxVal < minVal { + minVal, maxVal = maxVal, minVal } return } diff --git a/date_test.go b/date_test.go index 4091e37..11011cf 100644 --- a/date_test.go +++ b/date_test.go @@ -68,22 +68,22 @@ func TestTimeFromExcelTime(t *testing.T) { }) } for hour := 0; hour < 24; hour++ { - for min := 0; min < 60; min++ { + for minVal := 0; minVal < 60; minVal++ { for sec := 0; sec < 60; sec++ { - date := time.Date(2021, time.December, 30, hour, min, sec, 0, time.UTC) + date := time.Date(2021, time.December, 30, hour, minVal, sec, 0, time.UTC) // Test use 1900 date system excel1900Time, err := timeToExcelTime(date, false) assert.NoError(t, err) date1900Out := timeFromExcelTime(excel1900Time, false) assert.EqualValues(t, hour, date1900Out.Hour()) - assert.EqualValues(t, min, date1900Out.Minute()) + assert.EqualValues(t, minVal, date1900Out.Minute()) assert.EqualValues(t, sec, date1900Out.Second()) // Test use 1904 date system excel1904Time, err := timeToExcelTime(date, true) assert.NoError(t, err) date1904Out := timeFromExcelTime(excel1904Time, true) assert.EqualValues(t, hour, date1904Out.Hour()) - assert.EqualValues(t, min, date1904Out.Minute()) + assert.EqualValues(t, minVal, date1904Out.Minute()) assert.EqualValues(t, sec, date1904Out.Second()) } } diff --git a/drawing.go b/drawing.go index bc7b8a4..3c2da06 100644 --- a/drawing.go +++ b/drawing.go @@ -980,21 +980,21 @@ func (f *File) drawChartSeriesDLbls(i int, opts *Chart) *cDLbls { // drawPlotAreaCatAx provides a function to draw the c:catAx element. func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs { - max := &attrValFloat{Val: opts.XAxis.Maximum} - min := &attrValFloat{Val: opts.XAxis.Minimum} + maxVal := &attrValFloat{Val: opts.XAxis.Maximum} + minVal := &attrValFloat{Val: opts.XAxis.Minimum} if opts.XAxis.Maximum == nil { - max = nil + maxVal = nil } if opts.XAxis.Minimum == nil { - min = nil + minVal = nil } axs := []*cAxs{ { AxID: &attrValInt{Val: intPtr(100000000)}, Scaling: &cScaling{ Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])}, - Max: max, - Min: min, + Max: maxVal, + Min: minVal, }, Delete: &attrValBool{Val: boolPtr(opts.XAxis.None)}, AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])}, @@ -1030,8 +1030,8 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs { AxID: &attrValInt{Val: intPtr(opts.XAxis.axID)}, Scaling: &cScaling{ Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])}, - Max: max, - Min: min, + Max: maxVal, + Min: minVal, }, Delete: &attrValBool{Val: boolPtr(true)}, AxPos: &attrValString{Val: stringPtr("b")}, @@ -1052,13 +1052,13 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs { // drawPlotAreaValAx provides a function to draw the c:valAx element. func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { - max := &attrValFloat{Val: opts.YAxis.Maximum} - min := &attrValFloat{Val: opts.YAxis.Minimum} + maxVal := &attrValFloat{Val: opts.YAxis.Maximum} + minVal := &attrValFloat{Val: opts.YAxis.Minimum} if opts.YAxis.Maximum == nil { - max = nil + maxVal = nil } if opts.YAxis.Minimum == nil { - min = nil + minVal = nil } var logBase *attrValFloat if opts.YAxis.LogBase >= 2 && opts.YAxis.LogBase <= 1000 { @@ -1070,8 +1070,8 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { Scaling: &cScaling{ LogBase: logBase, Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])}, - Max: max, - Min: min, + Max: maxVal, + Min: minVal, }, Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)}, AxPos: &attrValString{Val: stringPtr(valAxPos[opts.YAxis.ReverseOrder])}, @@ -1109,8 +1109,8 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { AxID: &attrValInt{Val: intPtr(opts.YAxis.axID)}, Scaling: &cScaling{ Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])}, - Max: max, - Min: min, + Max: maxVal, + Min: minVal, }, Delete: &attrValBool{Val: boolPtr(false)}, AxPos: &attrValString{Val: stringPtr("r")}, @@ -1129,21 +1129,21 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { // drawPlotAreaSerAx provides a function to draw the c:serAx element. func (f *File) drawPlotAreaSerAx(opts *Chart) []*cAxs { - max := &attrValFloat{Val: opts.YAxis.Maximum} - min := &attrValFloat{Val: opts.YAxis.Minimum} + maxVal := &attrValFloat{Val: opts.YAxis.Maximum} + minVal := &attrValFloat{Val: opts.YAxis.Minimum} if opts.YAxis.Maximum == nil { - max = nil + maxVal = nil } if opts.YAxis.Minimum == nil { - min = nil + minVal = nil } return []*cAxs{ { AxID: &attrValInt{Val: intPtr(100000005)}, Scaling: &cScaling{ Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])}, - Max: max, - Min: min, + Max: maxVal, + Min: minVal, }, Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)}, AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])}, diff --git a/excelize.go b/excelize.go index 152e212..87ef22d 100644 --- a/excelize.go +++ b/excelize.go @@ -334,9 +334,9 @@ func (ws *xlsxWorksheet) checkSheet() { // with r="0" attribute. func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) { var ( - row, max int - r0 []xlsxRow - maxRowNum = func(num int, c []xlsxC) int { + row, maxVal int + r0 []xlsxRow + maxRowNum = func(num int, c []xlsxC) int { for _, cell := range c { if _, n, err := CellNameToCoordinates(cell.R); err == nil && n > num { num = n @@ -351,8 +351,8 @@ func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) { continue } if i == 0 && *r.R == 0 { - if num := maxRowNum(row, r.C); num > max { - max = num + if num := maxRowNum(row, r.C); num > maxVal { + maxVal = num } r0 = append(r0, r) continue @@ -361,8 +361,8 @@ func (ws *xlsxWorksheet) checkSheetRows() (int, []xlsxRow) { row = *r.R } } - if max > row { - row = max + if maxVal > row { + row = maxVal } return row, r0 } diff --git a/go.mod b/go.mod index 958af04..357b84e 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,9 @@ require ( github.com/stretchr/testify v1.8.4 github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 - golang.org/x/crypto v0.18.0 + golang.org/x/crypto v0.19.0 golang.org/x/image v0.14.0 - golang.org/x/net v0.20.0 + golang.org/x/net v0.21.0 golang.org/x/text v0.14.0 ) diff --git a/go.sum b/go.sum index 9928182..64de49a 100644 --- a/go.sum +++ b/go.sum @@ -15,12 +15,12 @@ github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1 github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/hsl.go b/hsl.go index 68ddf21..b8fb77b 100644 --- a/hsl.go +++ b/hsl.go @@ -65,21 +65,21 @@ func RGBToHSL(r, g, b uint8) (h, s, l float64) { fR := float64(r) / 255 fG := float64(g) / 255 fB := float64(b) / 255 - max := math.Max(math.Max(fR, fG), fB) - min := math.Min(math.Min(fR, fG), fB) - l = (max + min) / 2 - if max == min { + maxVal := math.Max(math.Max(fR, fG), fB) + minVal := math.Min(math.Min(fR, fG), fB) + l = (maxVal + minVal) / 2 + if maxVal == minVal { // Achromatic. h, s = 0, 0 } else { // Chromatic. - d := max - min + d := maxVal - minVal if l > 0.5 { - s = d / (2.0 - max - min) + s = d / (2.0 - maxVal - minVal) } else { - s = d / (max + min) + s = d / (maxVal + minVal) } - switch max { + switch maxVal { case fR: h = (fG - fB) / d if fG < fB { diff --git a/numfmt.go b/numfmt.go index c4022ba..d37130b 100644 --- a/numfmt.go +++ b/numfmt.go @@ -5776,7 +5776,7 @@ func localMonthsNameKiche(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesKiche[int(t.Month())-1] } - return string([]rune(monthNamesKicheAbbr[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesKicheAbbr[(t.Month() - 1)])[:1]) } // localMonthsNameKinyarwanda returns the Kinyarwanda name of the month. @@ -5787,7 +5787,7 @@ func localMonthsNameKinyarwanda(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesKinyarwanda[int(t.Month())-1] } - return string([]rune(monthNamesKinyarwanda[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesKinyarwanda[(t.Month() - 1)])[:1]) } // localMonthsNameKiswahili returns the Kiswahili name of the month. @@ -5798,7 +5798,7 @@ func localMonthsNameKiswahili(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesKiswahili[int(t.Month())-1] } - return string([]rune(monthNamesKiswahili[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesKiswahili[(t.Month() - 1)])[:1]) } // localMonthsNameKonkani returns the Konkani name of the month. @@ -5809,7 +5809,7 @@ func localMonthsNameKonkani(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesKonkani[int(t.Month())-1] } - return string([]rune(monthNamesKonkani[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesKonkani[(t.Month() - 1)])[:1]) } // localMonthsNameKorean returns the Korean name of the month. @@ -5828,7 +5828,7 @@ func localMonthsNameKyrgyz(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesKyrgyz[int(t.Month())-1] } - return string([]rune(monthNamesKyrgyz[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesKyrgyz[(t.Month() - 1)])[:1]) } // localMonthsNameLao returns the Lao name of the month. @@ -5839,7 +5839,7 @@ func localMonthsNameLao(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesLao[int(t.Month())-1] } - return string([]rune(monthNamesLao[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesLao[(t.Month() - 1)])[:1]) } // localMonthsNameLatin returns the Latin name of the month. @@ -5850,7 +5850,7 @@ func localMonthsNameLatin(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesLatin[int(t.Month())-1] } - return string([]rune(monthNamesLatin[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesLatin[(t.Month() - 1)])[:1]) } // localMonthsNameLatvian returns the Latvian name of the month. @@ -5861,7 +5861,7 @@ func localMonthsNameLatvian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesLatvian[int(t.Month())-1] } - return string([]rune(monthNamesLatvian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesLatvian[(t.Month() - 1)])[:1]) } // localMonthsNameLithuanian returns the Lithuanian name of the month. @@ -5872,7 +5872,7 @@ func localMonthsNameLithuanian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesLithuanian[int(t.Month())-1] } - return string([]rune(monthNamesLithuanian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesLithuanian[(t.Month() - 1)])[:1]) } // localMonthsNameLowerSorbian returns the LowerSorbian name of the month. @@ -5883,7 +5883,7 @@ func localMonthsNameLowerSorbian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesLowerSorbian[int(t.Month())-1] } - return string([]rune(monthNamesLowerSorbian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesLowerSorbian[(t.Month() - 1)])[:1]) } // localMonthsNameLuxembourgish returns the Luxembourgish name of the month. @@ -5894,7 +5894,7 @@ func localMonthsNameLuxembourgish(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesLuxembourgish[int(t.Month())-1] } - return string([]rune(monthNamesLuxembourgish[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesLuxembourgish[(t.Month() - 1)])[:1]) } // localMonthsNameMacedonian returns the Macedonian name of the month. @@ -5905,7 +5905,7 @@ func localMonthsNameMacedonian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMacedonian[int(t.Month())-1] } - return string([]rune(monthNamesMacedonian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMacedonian[(t.Month() - 1)])[:1]) } // localMonthsNameMalay returns the Malay name of the month. @@ -5916,7 +5916,7 @@ func localMonthsNameMalay(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMalay[int(t.Month())-1] } - return string([]rune(monthNamesMalay[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMalay[(t.Month() - 1)])[:1]) } // localMonthsNameMalayalam returns the Malayalam name of the month. @@ -5927,7 +5927,7 @@ func localMonthsNameMalayalam(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMalayalam[int(t.Month())-1] } - return string([]rune(monthNamesMalayalam[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMalayalam[(t.Month() - 1)])[:1]) } // localMonthsNameMaltese returns the Maltese name of the month. @@ -5938,7 +5938,7 @@ func localMonthsNameMaltese(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMaltese[int(t.Month())-1] } - return string([]rune(monthNamesMaltese[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMaltese[(t.Month() - 1)])[:1]) } // localMonthsNameMaori returns the Maori name of the month. @@ -5949,13 +5949,13 @@ func localMonthsNameMaori(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMaori[int(t.Month())-1] } - return string([]rune(monthNamesMaori[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMaori[(t.Month() - 1)])[:1]) } // localMonthsNameMapudungun returns the Mapudungun name of the month. func localMonthsNameMapudungun(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesMapudungun[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMapudungun[(t.Month() - 1)])[:1]) } return monthNamesMapudungun[int(t.Month())-1] } @@ -5968,7 +5968,7 @@ func localMonthsNameMarathi(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMarathi[int(t.Month())-1] } - return string([]rune(monthNamesMarathi[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMarathi[(t.Month() - 1)])[:1]) } // localMonthsNameMohawk returns the Mohawk name of the month. @@ -5979,7 +5979,7 @@ func localMonthsNameMohawk(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMohawk[int(t.Month())-1] } - return string([]rune(monthNamesMohawk[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMohawk[(t.Month() - 1)])[:1]) } // localMonthsNameMongolian returns the Mongolian name of the month. @@ -5990,7 +5990,7 @@ func localMonthsNameMongolian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesMongolian[int(t.Month())-1] } - return string([]rune(monthNamesMongolian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesMongolian[(t.Month() - 1)])[:1]) } // localMonthsNameMorocco returns the Morocco name of the month. @@ -6012,7 +6012,7 @@ func localMonthsNameNepali(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesNepali[int(t.Month())-1] } - return string([]rune(monthNamesNepali[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesNepali[(t.Month() - 1)])[:1]) } // localMonthsNameNepaliIN returns the India Nepali name of the month. @@ -6023,7 +6023,7 @@ func localMonthsNameNepaliIN(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesNepaliIN[int(t.Month())-1] } - return string([]rune(monthNamesNepaliIN[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesNepaliIN[(t.Month() - 1)])[:1]) } // localMonthsNameNigeria returns the Nigeria name of the month. @@ -6045,7 +6045,7 @@ func localMonthsNameNorwegian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesNorwegian[int(t.Month())-1] } - return string([]rune(monthNamesNorwegian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesNorwegian[(t.Month() - 1)])[:1]) } // localMonthsNameOccitan returns the Occitan name of the month. @@ -6056,13 +6056,13 @@ func localMonthsNameOccitan(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesOccitan[int(t.Month())-1] } - return string([]rune(monthNamesOccitan[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesOccitan[(t.Month() - 1)])[:1]) } // localMonthsNameOdia returns the Odia name of the month. func localMonthsNameOdia(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesOdia[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesOdia[(t.Month() - 1)])[:1]) } return monthNamesOdia[int(t.Month())-1] } @@ -6075,7 +6075,7 @@ func localMonthsNameOromo(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesOromo[int(t.Month())-1] } - return string([]rune(monthNamesOromo[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesOromo[(t.Month() - 1)])[:1]) } // localMonthsNamePashto returns the Pashto name of the month. @@ -6094,7 +6094,7 @@ func localMonthsNamePashto(t time.Time, abbr int) string { // localMonthsNamePersian returns the Persian name of the month. func localMonthsNamePersian(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesPersian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesPersian[(t.Month() - 1)])[:1]) } return monthNamesPersian[int(t.Month())-1] } @@ -6102,29 +6102,29 @@ func localMonthsNamePersian(t time.Time, abbr int) string { // localMonthsNamePolish returns the Polish name of the month. func localMonthsNamePolish(t time.Time, abbr int) string { if abbr == 3 { - return string([]rune(monthNamesPolish[int(t.Month()-1)])[:3]) + return string([]rune(monthNamesPolish[(t.Month() - 1)])[:3]) } if abbr == 4 || abbr > 6 { return monthNamesPolish[int(t.Month())-1] } - return string([]rune(monthNamesPolish[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesPolish[(t.Month() - 1)])[:1]) } // localMonthsNamePortuguese returns the Portuguese name of the month. func localMonthsNamePortuguese(t time.Time, abbr int) string { if abbr == 3 { - return string([]rune(monthNamesPortuguese[int(t.Month()-1)])[:3]) + return string([]rune(monthNamesPortuguese[(t.Month() - 1)])[:3]) } if abbr == 4 || abbr > 6 { return monthNamesPortuguese[int(t.Month())-1] } - return string([]rune(monthNamesPortuguese[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesPortuguese[(t.Month() - 1)])[:1]) } // localMonthsNamePunjabi returns the Punjabi name of the month. func localMonthsNamePunjabi(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesPunjabi[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesPunjabi[(t.Month() - 1)])[:1]) } return monthNamesPunjabi[int(t.Month())-1] } @@ -6132,7 +6132,7 @@ func localMonthsNamePunjabi(t time.Time, abbr int) string { // localMonthsNamePunjabiArab returns the Punjabi Arab name of the month. func localMonthsNamePunjabiArab(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesPunjabiArab[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesPunjabiArab[(t.Month() - 1)])[:1]) } return monthNamesPunjabiArab[int(t.Month())-1] } @@ -6140,26 +6140,26 @@ func localMonthsNamePunjabiArab(t time.Time, abbr int) string { // localMonthsNameQuechua returns the Quechua name of the month. func localMonthsNameQuechua(t time.Time, abbr int) string { if abbr == 3 { - return string([]rune(monthNamesQuechua[int(t.Month()-1)])[:3]) + return string([]rune(monthNamesQuechua[(t.Month() - 1)])[:3]) } if abbr == 4 || abbr > 6 { return monthNamesQuechua[int(t.Month())-1] } - return string([]rune(monthNamesQuechua[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesQuechua[(t.Month() - 1)])[:1]) } // localMonthsNameQuechuaEcuador returns the QuechuaEcuador name of the month. func localMonthsNameQuechuaEcuador(t time.Time, abbr int) string { if abbr == 3 { if int(t.Month()) == 1 { - return string([]rune(monthNamesQuechuaEcuador[int(t.Month()-1)])[:4]) + return string([]rune(monthNamesQuechuaEcuador[(t.Month() - 1)])[:4]) } - return string([]rune(monthNamesQuechuaEcuador[int(t.Month()-1)])[:3]) + return string([]rune(monthNamesQuechuaEcuador[(t.Month() - 1)])[:3]) } if abbr == 4 || abbr > 6 { return monthNamesQuechuaEcuador[int(t.Month())-1] } - return string([]rune(monthNamesQuechuaEcuador[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesQuechuaEcuador[(t.Month() - 1)])[:1]) } // localMonthsNameRomanian returns the Romanian name of the month. @@ -6170,7 +6170,7 @@ func localMonthsNameRomanian(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesRomanian[int(t.Month())-1] } - return string([]rune(monthNamesRomanian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesRomanian[(t.Month() - 1)])[:1]) } // localMonthsNameRomansh returns the Romansh name of the month. @@ -6181,7 +6181,7 @@ func localMonthsNameRomansh(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesRomansh[int(t.Month())-1] } - return string([]rune(monthNamesRomansh[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesRomansh[(t.Month() - 1)])[:1]) } // localMonthsNameRussian returns the Russian name of the month. @@ -6207,7 +6207,7 @@ func localMonthsNameSakha(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesSakha[int(t.Month())-1] } - return string([]rune(monthNamesSakha[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSakha[(t.Month() - 1)])[:1]) } // localMonthsNameSami returns the Sami name of the month. @@ -6218,7 +6218,7 @@ func localMonthsNameSami(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesSami[int(t.Month())-1] } - return string([]rune(monthNamesSami[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSami[(t.Month() - 1)])[:1]) } // localMonthsNameSamiLule returns the Sami (Lule) name of the month. @@ -6229,25 +6229,25 @@ func localMonthsNameSamiLule(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesSamiLule[int(t.Month())-1] } - return string([]rune(monthNamesSamiLule[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSamiLule[(t.Month() - 1)])[:1]) } // localMonthsNameSamiNorthern returns the Sami (Northern) name of the month. func localMonthsNameSamiNorthern(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSamiNorthernAbbr[int(t.Month()-1)] + return monthNamesSamiNorthernAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSamiNorthern[int(t.Month())-1] } - return string([]rune(monthNamesSamiNorthern[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSamiNorthern[(t.Month() - 1)])[:1]) } // localMonthsNameSamiNorthernFI returns the Sami (Northern) Finland name of the // month. func localMonthsNameSamiNorthernFI(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSamiNorthernAbbr[int(t.Month()-1)] + return monthNamesSamiNorthernAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { if int(t.Month()) == 1 { @@ -6255,13 +6255,13 @@ func localMonthsNameSamiNorthernFI(t time.Time, abbr int) string { } return monthNamesSamiNorthern[int(t.Month())-1] } - return string([]rune(monthNamesSamiNorthern[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSamiNorthern[(t.Month() - 1)])[:1]) } // localMonthsNameSamiSkolt returns the Sami (Skolt) name of the month. func localMonthsNameSamiSkolt(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesSamiSkolt[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSamiSkolt[(t.Month() - 1)])[:1]) } return monthNamesSamiSkolt[int(t.Month())-1] } @@ -6269,18 +6269,18 @@ func localMonthsNameSamiSkolt(t time.Time, abbr int) string { // localMonthsNameSamiSouthern returns the Sami (Southern) name of the month. func localMonthsNameSamiSouthern(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSamiSouthernAbbr[int(t.Month()-1)] + return monthNamesSamiSouthernAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSamiSouthern[int(t.Month())-1] } - return string([]rune(monthNamesSamiSouthern[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSamiSouthern[(t.Month() - 1)])[:1]) } // localMonthsNameSanskrit returns the Sanskrit name of the month. func localMonthsNameSanskrit(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesSanskrit[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSanskrit[(t.Month() - 1)])[:1]) } return monthNamesSanskrit[int(t.Month())-1] } @@ -6288,85 +6288,85 @@ func localMonthsNameSanskrit(t time.Time, abbr int) string { // localMonthsNameScottishGaelic returns the Scottish Gaelic name of the month. func localMonthsNameScottishGaelic(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesScottishGaelicAbbr[int(t.Month()-1)] + return monthNamesScottishGaelicAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesScottishGaelic[int(t.Month())-1] } - return string([]rune(monthNamesScottishGaelic[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesScottishGaelic[(t.Month() - 1)])[:1]) } // localMonthsNameSerbian returns the Serbian (Cyrillic) name of the month. func localMonthsNameSerbian(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSerbianAbbr[int(t.Month()-1)] + return monthNamesSerbianAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSerbian[int(t.Month())-1] } - return string([]rune(monthNamesSerbian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSerbian[(t.Month() - 1)])[:1]) } // localMonthsNameSerbianBA returns the Serbian (Cyrillic) Bosnia and // Herzegovina name of the month. func localMonthsNameSerbianBA(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSerbianBAAbbr[int(t.Month()-1)] + return monthNamesSerbianBAAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSerbianBA[int(t.Month())-1] } - return string([]rune(monthNamesSerbianBA[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSerbianBA[(t.Month() - 1)])[:1]) } // localMonthsNameSerbianLatin returns the Serbian (Latin) name of the month. func localMonthsNameSerbianLatin(t time.Time, abbr int) string { if abbr == 3 { - return string([]rune(monthNamesSerbianLatin[int(t.Month()-1)])[:3]) + return string([]rune(monthNamesSerbianLatin[(t.Month() - 1)])[:3]) } if abbr == 4 || abbr > 6 { return monthNamesSerbianLatin[int(t.Month())-1] } - return string([]rune(monthNamesSerbianLatin[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSerbianLatin[(t.Month() - 1)])[:1]) } // localMonthsNameSerbianLatinCS returns the Serbian (Latin) name of the month. func localMonthsNameSerbianLatinCS(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSerbianLatinAbbr[int(t.Month()-1)] + return monthNamesSerbianLatinAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSerbianLatin[int(t.Month())-1] } - return string([]rune(monthNamesSerbianLatin[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSerbianLatin[(t.Month() - 1)])[:1]) } // localMonthsNameSesothoSaLeboa returns the Sesotho sa Leboa name of the month. func localMonthsNameSesothoSaLeboa(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSesothoSaLeboaAbbr[int(t.Month()-1)] + return monthNamesSesothoSaLeboaAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSesothoSaLeboa[int(t.Month())-1] } - return string([]rune(monthNamesSesothoSaLeboa[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSesothoSaLeboa[(t.Month() - 1)])[:1]) } // localMonthsNameSetswana returns the Setswana name of the month. func localMonthsNameSetswana(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSetswanaAbbr[int(t.Month()-1)] + return monthNamesSetswanaAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSetswana[int(t.Month())-1] } - return string([]rune(monthNamesSetswana[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSetswana[(t.Month() - 1)])[:1]) } // localMonthsNameSindhi returns the Sindhi name of the month. func localMonthsNameSindhi(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesSindhi[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSindhi[(t.Month() - 1)])[:1]) } return monthNamesSindhi[int(t.Month())-1] } @@ -6374,12 +6374,12 @@ func localMonthsNameSindhi(t time.Time, abbr int) string { // localMonthsNameSinhala returns the Sinhala name of the month. func localMonthsNameSinhala(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSinhalaAbbr[int(t.Month()-1)] + return monthNamesSinhalaAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSinhala[int(t.Month())-1] } - return string([]rune(monthNamesSinhala[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSinhala[(t.Month() - 1)])[:1]) } // localMonthsNameSlovak returns the Slovak name of the month. @@ -6390,40 +6390,40 @@ func localMonthsNameSlovak(t time.Time, abbr int) string { if abbr == 4 || abbr > 6 { return monthNamesSlovak[int(t.Month())-1] } - return string([]rune(monthNamesSlovak[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSlovak[(t.Month() - 1)])[:1]) } // localMonthsNameSlovenian returns the Slovenian name of the month. func localMonthsNameSlovenian(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSlovenianAbbr[int(t.Month()-1)] + return monthNamesSlovenianAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSlovenian[int(t.Month())-1] } - return string([]rune(monthNamesSlovenian[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSlovenian[(t.Month() - 1)])[:1]) } // localMonthsNameSomali returns the Somali name of the month. func localMonthsNameSomali(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSomaliAbbr[int(t.Month()-1)] + return monthNamesSomaliAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSomali[int(t.Month())-1] } - return string([]rune(monthNamesSomali[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSomali[(t.Month() - 1)])[:1]) } // localMonthsNameSotho returns the Sotho name of the month. func localMonthsNameSotho(t time.Time, abbr int) string { if abbr == 3 { - return monthNamesSothoAbbr[int(t.Month()-1)] + return monthNamesSothoAbbr[(t.Month() - 1)] } if abbr == 4 || abbr > 6 { return monthNamesSotho[int(t.Month())-1] } - return string([]rune(monthNamesSotho[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSotho[(t.Month() - 1)])[:1]) } // localMonthsNameSpanish returns the Spanish name of the month. @@ -6478,7 +6478,7 @@ func localMonthsNameSyriac(t time.Time, abbr int) string { if abbr == 4 { return monthNamesSyriac[int(t.Month())-1] } - return string([]rune(monthNamesSyriac[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesSyriac[(t.Month() - 1)])[:1]) } // localMonthsNameTajik returns the Tajik name of the month. @@ -6489,7 +6489,7 @@ func localMonthsNameTajik(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTajik[int(t.Month())-1] } - return string([]rune(monthNamesTajik[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTajik[(t.Month() - 1)])[:1]) } // localMonthsNameTamazight returns the Tamazight name of the month. @@ -6500,13 +6500,13 @@ func localMonthsNameTamazight(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTamazight[int(t.Month())-1] } - return string([]rune(monthNamesTamazight[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTamazight[(t.Month() - 1)])[:1]) } // localMonthsNameTamil returns the Tamil name of the month. func localMonthsNameTamil(t time.Time, abbr int) string { if abbr == 5 { - return string([]rune(monthNamesTamil[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTamil[(t.Month() - 1)])[:1]) } return monthNamesTamil[int(t.Month())-1] } @@ -6519,7 +6519,7 @@ func localMonthsNameTamilLK(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTamil[int(t.Month())-1] } - return string([]rune(monthNamesTamil[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTamil[(t.Month() - 1)])[:1]) } // localMonthsNameTatar returns the Tatar name of the month. @@ -6530,7 +6530,7 @@ func localMonthsNameTatar(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTatar[int(t.Month())-1] } - return string([]rune(monthNamesTatar[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTatar[(t.Month() - 1)])[:1]) } // localMonthsNameTelugu returns the Telugu name of the month. @@ -6541,7 +6541,7 @@ func localMonthsNameTelugu(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTelugu[int(t.Month())-1] } - return string([]rune(monthNamesTelugu[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTelugu[(t.Month() - 1)])[:1]) } // localMonthsNameSyllabics returns the Syllabics name of the month. @@ -6589,7 +6589,7 @@ func localMonthsNameTigrinya(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTigrinya[int(t.Month())-1] } - return string([]rune(monthNamesTigrinya[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTigrinya[(t.Month() - 1)])[:1]) } // localMonthsNameTsonga returns the Tsonga name of the month. @@ -6600,7 +6600,7 @@ func localMonthsNameTsonga(t time.Time, abbr int) string { if abbr == 4 { return monthNamesTsonga[int(t.Month())-1] } - return string([]rune(monthNamesTsonga[int(t.Month()-1)])[:1]) + return string([]rune(monthNamesTsonga[(t.Month() - 1)])[:1]) } // localMonthsNameTraditionalMongolian returns the Traditional Mongolian name of @@ -6922,10 +6922,10 @@ func (nf *numberFormat) daysHandler(token nfp.Token) { } if strings.Contains(strings.ToUpper(token.TValue), "A") { if l == 3 { - nf.result += weekdayNamesAbbr[int(nf.t.Weekday())] + nf.result += weekdayNamesAbbr[nf.t.Weekday()] } if l > 3 { - nf.result += weekdayNames[int(nf.t.Weekday())] + nf.result += weekdayNames[nf.t.Weekday()] } return } @@ -6936,9 +6936,9 @@ func (nf *numberFormat) daysHandler(token nfp.Token) { case 2: nf.result += fmt.Sprintf("%02d", nf.t.Day()) case 3: - nf.result += weekdayNamesAbbr[int(nf.t.Weekday())] + nf.result += weekdayNamesAbbr[nf.t.Weekday()] default: - nf.result += weekdayNames[int(nf.t.Weekday())] + nf.result += weekdayNames[nf.t.Weekday()] } } } diff --git a/rows.go b/rows.go index 7541a0b..878c8d8 100644 --- a/rows.go +++ b/rows.go @@ -63,7 +63,7 @@ func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error) { return nil, err } rows, _ := f.Rows(sheet) - results, cur, max := make([][]string, 0, 64), 0, 0 + results, cur, maxVal := make([][]string, 0, 64), 0, 0 for rows.Next() { cur++ row, err := rows.Columns(opts...) @@ -72,10 +72,10 @@ func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error) { } results = append(results, row) if len(row) > 0 { - max = cur + maxVal = cur } } - return results[:max], rows.Close() + return results[:maxVal], rows.Close() } // Rows defines an iterator to a sheet. diff --git a/stream.go b/stream.go index 8fbbcfd..ef7fa13 100644 --- a/stream.go +++ b/stream.go @@ -439,24 +439,24 @@ func (sw *StreamWriter) SetRow(cell string, values []interface{}, opts ...RowOpt // the width column B:C as 20: // // err := sw.SetColWidth(2, 3, 20) -func (sw *StreamWriter) SetColWidth(min, max int, width float64) error { +func (sw *StreamWriter) SetColWidth(minVal, maxVal int, width float64) error { if sw.sheetWritten { return ErrStreamSetColWidth } - if min < MinColumns || min > MaxColumns || max < MinColumns || max > MaxColumns { + if minVal < MinColumns || minVal > MaxColumns || maxVal < MinColumns || maxVal > MaxColumns { return ErrColumnNumber } if width > MaxColumnWidth { return ErrColumnWidth } - if min > max { - min, max = max, min + if minVal > maxVal { + minVal, maxVal = maxVal, minVal } sw.cols.WriteString(``) diff --git a/table.go b/table.go index ea49d3c..c0c1594 100644 --- a/table.go +++ b/table.go @@ -19,7 +19,6 @@ import ( "regexp" "strconv" "strings" - "unicode" "unicode/utf8" ) @@ -316,14 +315,22 @@ func checkDefinedName(name string) error { if utf8.RuneCountInString(name) > MaxFieldLength { return ErrNameLength } + inCodeRange := func(code int, tbl []int) bool { + for i := 0; i < len(tbl); i += 2 { + if tbl[i] <= code && code <= tbl[i+1] { + return true + } + } + return false + } for i, c := range name { - if string(c) == "_" { - continue + if i == 0 { + if inCodeRange(int(c), supportedDefinedNameAtStartCharCodeRange) { + continue + } + return newInvalidNameError(name) } - if unicode.IsLetter(c) { - continue - } - if i > 0 && (unicode.IsDigit(c) || c == '.') { + if inCodeRange(int(c), supportedDefinedNameAfterStartCharCodeRange) { continue } return newInvalidNameError(name) diff --git a/templates.go b/templates.go index d9fb18c..60c895d 100644 --- a/templates.go +++ b/templates.go @@ -302,6 +302,163 @@ var IndexedColorMapping = []string{ "000000", "FFFFFF", } +// supportedDefinedNameAtStartCharCodeRange list the valid first character of a +// defined name ASCII letters. +var supportedDefinedNameAtStartCharCodeRange = []int{ + 65, 90, 92, 92, 95, 95, 97, 122, 161, 161, 164, 164, + 167, 168, 170, 170, 173, 173, 175, 186, 188, 696, 699, 705, + 711, 711, 713, 715, 717, 717, 720, 721, 728, 731, 733, 733, + 736, 740, 750, 750, 880, 883, 886, 887, 890, 893, 902, 902, + 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1315, + 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1610, + 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, + 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, + 2036, 2037, 2042, 2042, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, + 2417, 2418, 2427, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, + 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, + 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, + 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, + 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, + 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, + 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, + 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, + 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, + 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, + 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, + 3261, 3261, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, + 3370, 3385, 3389, 3389, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, + 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3642, 3648, 3662, 3713, 3714, + 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, + 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, + 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, + 3913, 3948, 3976, 3979, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, + 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, + 4304, 4346, 4348, 4348, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4680, + 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, + 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, + 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, + 5743, 5750, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, + 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, + 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6400, 6428, 6480, 6509, + 6512, 6516, 6528, 6569, 6593, 6599, 6656, 6678, 6917, 6963, 6981, 6987, + 7043, 7072, 7086, 7087, 7168, 7203, 7245, 7247, 7258, 7293, 7424, 7615, + 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, + 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, + 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, + 8182, 8188, 8208, 8208, 8211, 8214, 8216, 8216, 8220, 8221, 8224, 8225, + 8229, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8305, 8305, + 8308, 8308, 8319, 8319, 8321, 8324, 8336, 8340, 8450, 8451, 8453, 8453, + 8455, 8455, 8457, 8467, 8469, 8470, 8473, 8477, 8481, 8482, 8484, 8484, + 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, + 8526, 8526, 8531, 8532, 8539, 8542, 8544, 8584, 8592, 8601, 8658, 8658, + 8660, 8660, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, + 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, + 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, + 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, + 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, + 9312, 9397, 9424, 9449, 9472, 9547, 9552, 9588, 9601, 9615, 9618, 9621, + 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, + 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, + 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, + 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 11264, 11310, + 11312, 11358, 11360, 11375, 11377, 11389, 11392, 11492, 11520, 11557, 11568, 11621, + 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, + 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12288, 12291, 12293, 12311, + 12317, 12319, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, + 12449, 12543, 12549, 12589, 12593, 12686, 12704, 12727, 12784, 12828, 12832, 12841, + 12849, 12850, 12857, 12857, 12896, 12923, 12927, 12927, 12963, 12968, 13059, 13059, + 13069, 13069, 13076, 13076, 13080, 13080, 13090, 13091, 13094, 13095, 13099, 13099, + 13110, 13110, 13115, 13115, 13129, 13130, 13133, 13133, 13137, 13137, 13143, 13143, + 13179, 13182, 13184, 13188, 13192, 13258, 13261, 13267, 13269, 13270, 13272, 13272, + 13275, 13277, 13312, 19893, 19968, 40899, 40960, 42124, 42240, 42508, 42512, 42527, + 42538, 42539, 42560, 42591, 42594, 42606, 42624, 42647, 42786, 42887, 42891, 42892, + 43003, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, + 43274, 43301, 43312, 43334, 43520, 43560, 43584, 43586, 43588, 43595, 44032, 55203, + 57344, 63560, 63744, 64045, 64048, 64106, 64112, 64217, 64256, 64262, 64275, 64279, + 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, + 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, + 65072, 65073, 65075, 65092, 65097, 65106, 65108, 65111, 65113, 65126, 65128, 65131, + 65136, 65140, 65142, 65276, 65281, 65374, 65377, 65470, 65474, 65479, 65482, 65487, + 65490, 65495, 65498, 65500, 65504, 65510, +} + +// supportedDefinedNameAfterStartCharCodeRange list the valid after first +// character of a defined name ASCII letters. +var supportedDefinedNameAfterStartCharCodeRange = []int{ + 46, 46, 48, 57, 63, 63, 65, 90, 92, 92, 95, 95, + 97, 122, 161, 161, 164, 164, 167, 168, 170, 170, 173, 173, + 175, 186, 188, 887, 890, 893, 900, 902, 904, 906, 908, 908, + 910, 929, 931, 1315, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, + 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, + 1536, 1539, 1542, 1544, 1547, 1547, 1550, 1562, 1567, 1567, 1569, 1630, + 1632, 1641, 1646, 1747, 1749, 1791, 1807, 1866, 1869, 1969, 1984, 2038, + 2042, 2042, 2305, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, + 2417, 2418, 2427, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, + 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, + 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2554, 2561, 2563, 2565, 2570, + 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, + 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, + 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, + 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, + 2768, 2768, 2784, 2787, 2790, 2799, 2801, 2801, 2817, 2819, 2821, 2828, + 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, + 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2929, + 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, + 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, + 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3066, 3073, 3075, 3077, 3084, + 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, + 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3192, 3199, + 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, + 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, + 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, + 3370, 3385, 3389, 3396, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3427, + 3430, 3445, 3449, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, + 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, + 3570, 3571, 3585, 3642, 3647, 3662, 3664, 3673, 3713, 3714, 3716, 3716, + 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, + 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, + 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3843, 3859, 3897, + 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, + 4030, 4044, 4046, 4047, 4096, 4169, 4176, 4249, 4254, 4293, 4304, 4346, + 4348, 4348, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4680, 4682, 4685, + 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, + 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, + 4882, 4885, 4888, 4954, 4959, 4960, 4969, 4988, 4992, 5017, 5024, 5108, + 5121, 5740, 5743, 5750, 5760, 5786, 5792, 5866, 5870, 5872, 5888, 5900, + 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, + 6016, 6099, 6103, 6103, 6107, 6109, 6112, 6121, 6128, 6137, 6155, 6158, + 6160, 6169, 6176, 6263, 6272, 6314, 6400, 6428, 6432, 6443, 6448, 6459, + 6464, 6464, 6470, 6509, 6512, 6516, 6528, 6569, 6576, 6601, 6608, 6617, + 6624, 6683, 6912, 6987, 6992, 7001, 7009, 7036, 7040, 7082, 7086, 7097, + 7168, 7223, 7232, 7241, 7245, 7293, 7424, 7654, 7678, 7957, 7960, 7965, + 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, + 8031, 8061, 8064, 8116, 8118, 8132, 8134, 8147, 8150, 8155, 8157, 8175, + 8178, 8180, 8182, 8190, 8192, 8208, 8211, 8214, 8216, 8216, 8220, 8221, + 8224, 8225, 8229, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8260, 8260, + 8274, 8274, 8287, 8292, 8298, 8305, 8308, 8316, 8319, 8332, 8336, 8340, + 8352, 8373, 8400, 8432, 8448, 8527, 8531, 8584, 8592, 9000, 9003, 9191, + 9216, 9254, 9280, 9290, 9312, 9885, 9888, 9916, 9920, 9923, 9985, 9988, + 9990, 9993, 9996, 10023, 10025, 10059, 10061, 10061, 10063, 10066, 10070, 10070, + 10072, 10078, 10081, 10087, 10102, 10132, 10136, 10159, 10161, 10174, 10176, 10180, + 10183, 10186, 10188, 10188, 10192, 10213, 10224, 10626, 10649, 10711, 10716, 10747, + 10750, 11084, 11088, 11092, 11264, 11310, 11312, 11358, 11360, 11375, 11377, 11389, + 11392, 11498, 11517, 11517, 11520, 11557, 11568, 11621, 11631, 11631, 11648, 11670, + 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, + 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 11904, 11929, 11931, 12019, + 12032, 12245, 12272, 12283, 12288, 12311, 12317, 12335, 12337, 12348, 12350, 12351, + 12353, 12438, 12441, 12447, 12449, 12543, 12549, 12589, 12593, 12686, 12688, 12727, + 12736, 12771, 12784, 12830, 12832, 12867, 12880, 13054, 13056, 19893, 19904, 40899, + 40960, 42124, 42128, 42182, 42240, 42508, 42512, 42539, 42560, 42591, 42594, 42610, + 42620, 42621, 42623, 42647, 42752, 42892, 43003, 43051, 43072, 43123, 43136, 43204, + 43216, 43225, 43264, 43310, 43312, 43347, 43520, 43574, 43584, 43597, 43600, 43609, + 44032, 55203, 55296, 64045, 64048, 64106, 64112, 64217, 64256, 64262, 64275, 64279, + 64285, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, + 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65021, 65024, 65039, 65056, 65062, + 65072, 65073, 65075, 65092, 65097, 65106, 65108, 65111, 65113, 65126, 65128, 65131, + 65136, 65140, 65142, 65276, 65279, 65279, 65281, 65374, 65377, 65470, 65474, 65479, + 65482, 65487, 65490, 65495, 65498, 65500, 65504, 65510, 65512, 65518, 65529, 65533, +} + // supportedImageTypes defined supported image types. var supportedImageTypes = map[string]string{ ".bmp": ".bmp", ".emf": ".emf", ".emz": ".emz", ".gif": ".gif", @@ -332,7 +489,7 @@ var supportedDrawingUnderlineTypes = []string{ var supportedPositioning = []string{"absolute", "oneCell", "twoCell"} // builtInDefinedNames defined built-in defined names are built with a _xlnm prefix. -var builtInDefinedNames = []string{"_xlnm.Print_Area", "_xlnm.Print_Titles", "_xlnm._FilterDatabase"} +var builtInDefinedNames = []string{"_xlnm.Print_Area", "_xlnm.Print_Titles", "_xlnm.Criteria", "_xlnm._FilterDatabase", "_xlnm.Extract", "_xlnm.Consolidate_Area", "_xlnm.Database", "_xlnm.Sheet_Title"} const templateDocpropsApp = `0Go Excelize`