// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
worksheet.SheetData.Row[rowIdx].C[colIdx].R, _ = CoordinatesToCellName(newCol, cellRow)
}
}
- if err := f.adjustFormula(sheet, sheetN, worksheet.SheetData.Row[rowIdx].C[colIdx].F, columns, col, offset, false); err != nil {
+ if err := f.adjustFormula(sheet, sheetN, &worksheet.SheetData.Row[rowIdx].C[colIdx], columns, col, offset, false); err != nil {
return err
}
}
// adjustSingleRowFormulas provides a function to adjust single row formulas.
func (f *File) adjustSingleRowFormulas(sheet, sheetN string, r *xlsxRow, num, offset int, si bool) error {
- for _, col := range r.C {
- if err := f.adjustFormula(sheet, sheetN, col.F, rows, num, offset, si); err != nil {
+ for i := 0; i < len(r.C); i++ {
+ if err := f.adjustFormula(sheet, sheetN, &r.C[i], rows, num, offset, si); err != nil {
return err
}
}
// adjustFormula provides a function to adjust formula reference and shared
// formula reference.
-func (f *File) adjustFormula(sheet, sheetN string, formula *xlsxF, dir adjustDirection, num, offset int, si bool) error {
- if formula == nil {
+func (f *File) adjustFormula(sheet, sheetN string, cell *xlsxC, dir adjustDirection, num, offset int, si bool) error {
+ var err error
+ if cell.f != "" {
+ if cell.f, err = f.adjustFormulaRef(sheet, sheetN, cell.f, false, dir, num, offset); err != nil {
+ return err
+ }
+ }
+ if cell.F == nil {
return nil
}
- var err error
- if formula.Ref != "" && sheet == sheetN {
- if formula.Ref, _, err = f.adjustCellRef(formula.Ref, dir, num, offset); err != nil {
+ if cell.F.Ref != "" && sheet == sheetN {
+ if cell.F.Ref, _, err = f.adjustCellRef(cell.F.Ref, dir, num, offset); err != nil {
return err
}
- if si && formula.Si != nil {
- formula.Si = intPtr(*formula.Si + 1)
+ if si && cell.F.Si != nil {
+ cell.F.Si = intPtr(*cell.F.Si + 1)
}
}
- if formula.Content != "" {
- if formula.Content, err = f.adjustFormulaRef(sheet, sheetN, formula.Content, false, dir, num, offset); err != nil {
+ if cell.F.Content != "" {
+ if cell.F.Content, err = f.adjustFormulaRef(sheet, sheetN, cell.F.Content, false, dir, num, offset); err != nil {
return err
}
}
return nil
}
-// isFunctionStop provides a function to check if token is a function stop.
-func isFunctionStop(token efp.Token) bool {
- return token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStop
-}
-
-// isFunctionStart provides a function to check if token is a function start.
-func isFunctionStart(token efp.Token) bool {
- return token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStart
-}
-
// escapeSheetName enclose sheet name in single quotation marks if the giving
// worksheet name includes spaces or non-alphabetical characters.
func escapeSheetName(name string) string {
val += operand
continue
}
- if isFunctionStart(token) {
+ if isFunctionStartToken(token) {
val += token.TValue + string(efp.ParenOpen)
continue
}
- if isFunctionStop(token) {
+ if isFunctionStopToken(token) {
val += token.TValue + string(efp.ParenClose)
continue
}
return val, nil
}
+// arrayFormulaOperandToken defines meta fields for transforming the array
+// formula to the normal formula.
+type arrayFormulaOperandToken struct {
+ operandTokenIndex, topLeftCol, topLeftRow, bottomRightCol, bottomRightRow int
+ sheetName, sourceCellRef, targetCellRef string
+}
+
+// setCoordinates convert each corner cell reference in the array formula cell
+// range to the coordinate number.
+func (af *arrayFormulaOperandToken) setCoordinates() error {
+ for i, ref := range strings.Split(af.sourceCellRef, ":") {
+ cellRef, col, row, err := parseRef(ref)
+ if err != nil {
+ return err
+ }
+ var c, r int
+ if col {
+ if cellRef.Row = TotalRows; i == 1 {
+ cellRef.Row = 1
+ }
+ }
+ if row {
+ if cellRef.Col = MaxColumns; i == 1 {
+ cellRef.Col = 1
+ }
+ }
+ if c, r = cellRef.Col, cellRef.Row; cellRef.Sheet != "" {
+ af.sheetName = cellRef.Sheet + "!"
+ }
+ if af.topLeftCol == 0 || c < af.topLeftCol {
+ af.topLeftCol = c
+ }
+ if af.topLeftRow == 0 || r < af.topLeftRow {
+ af.topLeftRow = r
+ }
+ if c > af.bottomRightCol {
+ af.bottomRightCol = c
+ }
+ if r > af.bottomRightRow {
+ af.bottomRightRow = r
+ }
+ }
+ return nil
+}
+
+// transformArrayFormula transforms an array formula to the normal formula by
+// giving a formula tokens list and formula operand tokens list.
+func transformArrayFormula(tokens []efp.Token, afs []arrayFormulaOperandToken) string {
+ var val string
+ for i, token := range tokens {
+ var skip bool
+ for _, af := range afs {
+ if af.operandTokenIndex == i {
+ val += af.sheetName + af.targetCellRef
+ skip = true
+ break
+ }
+ }
+ if skip {
+ continue
+ }
+ if isFunctionStartToken(token) {
+ val += token.TValue + string(efp.ParenOpen)
+ continue
+ }
+ if isFunctionStopToken(token) {
+ val += token.TValue + string(efp.ParenClose)
+ continue
+ }
+ if token.TType == efp.TokenTypeOperand && token.TSubType == efp.TokenSubTypeText {
+ val += string(efp.QuoteDouble) + strings.ReplaceAll(token.TValue, "\"", "\"\"") + string(efp.QuoteDouble)
+ continue
+ }
+ val += token.TValue
+ }
+ return val
+}
+
+// getArrayFormulaTokens returns parsed formula token and operand related token
+// list for in array formula.
+func getArrayFormulaTokens(sheet, formula string, definedNames []DefinedName) ([]efp.Token, []arrayFormulaOperandToken, error) {
+ var (
+ ps = efp.ExcelParser()
+ tokens = ps.Parse(formula)
+ arrayFormulaOperandTokens []arrayFormulaOperandToken
+ )
+ for i, token := range tokens {
+ if token.TSubType == efp.TokenSubTypeRange && token.TType == efp.TokenTypeOperand {
+ tokenVal := token.TValue
+ for _, definedName := range definedNames {
+ if (definedName.Scope == "Workbook" || definedName.Scope == sheet) && definedName.Name == tokenVal {
+ tokenVal = definedName.RefersTo
+ }
+ }
+ if len(strings.Split(tokenVal, ":")) > 1 {
+ arrayFormulaOperandToken := arrayFormulaOperandToken{
+ operandTokenIndex: i,
+ sourceCellRef: tokenVal,
+ }
+ if err := arrayFormulaOperandToken.setCoordinates(); err != nil {
+ return tokens, arrayFormulaOperandTokens, err
+ }
+ arrayFormulaOperandTokens = append(arrayFormulaOperandTokens, arrayFormulaOperandToken)
+ }
+ }
+ }
+ return tokens, arrayFormulaOperandTokens, nil
+}
+
// adjustHyperlinks provides a function to update hyperlinks when inserting or
// deleting rows or columns.
func (f *File) adjustHyperlinks(ws *xlsxWorksheet, sheet string, dir adjustDirection, num, offset int) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAdjustFormula.xlsx")))
assert.NoError(t, f.Close())
- assert.NoError(t, f.adjustFormula("Sheet1", "Sheet1", nil, rows, 0, 0, false))
- assert.Equal(t, newCellNameToCoordinatesError("-", newInvalidCellNameError("-")), f.adjustFormula("Sheet1", "Sheet1", &xlsxF{Ref: "-"}, rows, 0, 0, false))
- assert.Equal(t, ErrColumnNumber, f.adjustFormula("Sheet1", "Sheet1", &xlsxF{Ref: "XFD1:XFD1"}, columns, 0, 1, false))
+ assert.NoError(t, f.adjustFormula("Sheet1", "Sheet1", &xlsxC{}, rows, 0, 0, false))
+ assert.Equal(t, newCellNameToCoordinatesError("-", newInvalidCellNameError("-")), f.adjustFormula("Sheet1", "Sheet1", &xlsxC{F: &xlsxF{Ref: "-"}}, rows, 0, 0, false))
+ assert.Equal(t, ErrColumnNumber, f.adjustFormula("Sheet1", "Sheet1", &xlsxC{F: &xlsxF{Ref: "XFD1:XFD1"}}, columns, 0, 1, false))
_, err := f.adjustFormulaRef("Sheet1", "Sheet1", "XFE1", false, columns, 0, 1)
assert.Equal(t, ErrColumnNumber, err)
assert.NoError(t, f.InsertRows("Sheet1", 2, 1))
assert.NoError(t, f.InsertCols("Sheet1", "A", 1))
})
+ t.Run("for_array_formula_cell", func(t *testing.T) {
+ f := NewFile()
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A1", &[]int{1, 2}))
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A2", &[]int{3, 4}))
+ formulaType, ref := STCellFormulaTypeArray, "C1:C2"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "A1:A2*B1:B2", FormulaOpts{Ref: &ref, Type: &formulaType}))
+ assert.NoError(t, f.InsertRows("Sheet1", 1, 1))
+ assert.NoError(t, f.InsertCols("Sheet1", "A", 1))
+ result, err := f.CalcCellValue("Sheet1", "D2")
+ assert.NoError(t, err)
+ assert.Equal(t, "2", result)
+ result, err = f.CalcCellValue("Sheet1", "D3")
+ assert.NoError(t, err)
+ assert.Equal(t, "12", result)
+
+ // Test adjust array formula with invalid range reference
+ formulaType, ref = STCellFormulaTypeArray, "E1:E2"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "E1", "XFD1:XFD1", FormulaOpts{Ref: &ref, Type: &formulaType}))
+ assert.EqualError(t, f.InsertCols("Sheet1", "A", 1), "the column number must be greater than or equal to 1 and less than or equal to 16384")
+ })
}
func TestAdjustVolatileDeps(t *testing.T) {
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// reference.
func (f *File) calcCellValue(ctx *calcContext, sheet, cell string) (result formulaArg, err error) {
var formula string
- if formula, err = f.GetCellFormula(sheet, cell); err != nil {
+ if formula, err = f.getCellFormula(sheet, cell, true); err != nil {
return
}
ps := efp.ExcelParser()
}
// parseRef parse reference for a cell, column name or row number.
-func (f *File) parseRef(ref string) (cellRef, bool, bool, error) {
+func parseRef(ref string) (cellRef, bool, bool, error) {
var (
err, colErr, rowErr error
cr cellRef
if len(ranges) > 1 {
var cr cellRange
for i, ref := range ranges {
- cellRef, col, row, err := f.parseRef(ref)
+ cellRef, col, row, err := parseRef(ref)
if err != nil {
return newErrorFormulaArg(formulaErrorNAME, "invalid reference"), errors.New("invalid reference")
}
cellRanges.PushBack(cr)
return f.rangeResolver(ctx, cellRefs, cellRanges)
}
- cellRef, _, _, err := f.parseRef(reference)
+ cellRef, _, _, err := parseRef(reference)
if err != nil {
return newErrorFormulaArg(formulaErrorNAME, "invalid reference"), errors.New("invalid reference")
}
err error
)
ref := fmt.Sprintf("%s!%s", sheet, cell)
- if formula, _ := f.GetCellFormula(sheet, cell); len(formula) != 0 {
+ if formula, _ := f.getCellFormula(sheet, cell, true); len(formula) != 0 {
ctx.mu.Lock()
if ctx.entry != ref {
if ctx.iterations[ref] <= f.options.MaxCalcIterations {
return newStringFormulaArg(fmt.Sprintf("%s%s", sheetText, addr))
}
+// ANCHORARRAY function returns the entire spilled range for the dynamic array
+// in cell. The syntax of the function is:
+//
+// ANCHORARRAY(cell)
+func (fn *formulaFuncs) ANCHORARRAY(argsList *list.List) formulaArg {
+ if argsList.Len() != 1 {
+ return newErrorFormulaArg(formulaErrorVALUE, "ANCHORARRAY requires 1 numeric argument")
+ }
+ ws, err := fn.f.workSheetReader(fn.sheet)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorVALUE, err.Error())
+ }
+ ref := argsList.Front().Value.(formulaArg).cellRefs.Front().Value.(cellRef)
+ cell := ws.SheetData.Row[ref.Row-1].C[ref.Col-1]
+ if cell.F == nil {
+ return newEmptyFormulaArg()
+ }
+ coordinates, err := rangeRefToCoordinates(cell.F.Ref)
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorVALUE, err.Error())
+ }
+ _ = sortCoordinates(coordinates)
+ var mtx [][]formulaArg
+ for c := coordinates[0]; c <= coordinates[2]; c++ {
+ var row []formulaArg
+ for r := coordinates[1]; r <= coordinates[3]; r++ {
+ cellName, _ := CoordinatesToCellName(c, r)
+ result, err := fn.f.CalcCellValue(ref.Sheet, cellName, Options{RawCellValue: true})
+ if err != nil {
+ return newErrorFormulaArg(formulaErrorVALUE, err.Error())
+ }
+ arg := newStringFormulaArg(result)
+ if num := arg.ToNumber(); num.Type == ArgNumber {
+ arg = num
+ }
+ row = append(row, arg)
+ }
+ mtx = append(mtx, row)
+ }
+ return newMatrixFormulaArg(mtx)
+}
+
// CHOOSE function returns a value from an array, that corresponds to a
// supplied index number (position). The syntax of the function is:
//
assert.EqualError(t, err, "sheet SheetN does not exist")
// Test get calculated cell value with invalid sheet name
_, err = f.CalcCellValue("Sheet:1", "A1")
- assert.EqualError(t, err, ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, err)
// Test get calculated cell value with not support formula
f = prepareCalcData(cellData)
assert.NoError(t, f.SetCellFormula("Sheet1", "A1", "=UNSUPPORT(A1)"))
assert.Equal(t, compareFormulaArgMatrix(lhs, rhs, newNumberFormulaArg(matchModeMaxLess), false), criteriaG)
}
+func TestCalcANCHORARRAY(t *testing.T) {
+ f := NewFile()
+ assert.NoError(t, f.SetCellValue("Sheet1", "A1", 1))
+ assert.NoError(t, f.SetCellValue("Sheet1", "A2", 2))
+ formulaType, ref := STCellFormulaTypeArray, "B1:B2"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "B1", "A1:A2",
+ FormulaOpts{Ref: &ref, Type: &formulaType}))
+ assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "SUM(_xlfn.ANCHORARRAY($B$1))"))
+ result, err := f.CalcCellValue("Sheet1", "C1")
+ assert.NoError(t, err)
+ assert.Equal(t, "3", result)
+
+ assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "SUM(_xlfn.ANCHORARRAY(\"\",\"\"))"))
+ result, err = f.CalcCellValue("Sheet1", "C1")
+ assert.EqualError(t, err, "ANCHORARRAY requires 1 numeric argument")
+ assert.Equal(t, "#VALUE!", result)
+
+ fn := &formulaFuncs{f: f, sheet: "SheetN"}
+ argsList := list.New()
+ argsList.PushBack(newStringFormulaArg("$B$1"))
+ formulaArg := fn.ANCHORARRAY(argsList)
+ assert.Equal(t, "sheet SheetN does not exist", formulaArg.Value())
+
+ fn.sheet = "Sheet1"
+ argsList = argsList.Init()
+ arg := newStringFormulaArg("$A$1")
+ arg.cellRefs = list.New()
+ arg.cellRefs.PushBack(cellRef{Row: 1, Col: 1})
+ argsList.PushBack(arg)
+ formulaArg = fn.ANCHORARRAY(argsList)
+ assert.Equal(t, ArgEmpty, formulaArg.Type)
+
+ ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
+ assert.True(t, ok)
+ ws.(*xlsxWorksheet).SheetData.Row[0].C[0].F = &xlsxF{}
+ formulaArg = fn.ANCHORARRAY(argsList)
+ assert.Equal(t, ArgError, formulaArg.Type)
+ assert.Equal(t, ErrParameterInvalid.Error(), formulaArg.Value())
+
+ argsList = argsList.Init()
+ arg = newStringFormulaArg("$B$1")
+ arg.cellRefs = list.New()
+ arg.cellRefs.PushBack(cellRef{Row: 1, Col: 1, Sheet: "SheetN"})
+ argsList.PushBack(arg)
+ ws.(*xlsxWorksheet).SheetData.Row[0].C[0].F = &xlsxF{Ref: "A1:A1"}
+ formulaArg = fn.ANCHORARRAY(argsList)
+ assert.Equal(t, ArgError, formulaArg.Type)
+ assert.Equal(t, "sheet SheetN does not exist", formulaArg.Value())
+}
+
+func TestCalcArrayFormula(t *testing.T) {
+ t.Run("matrix_multiplication", func(t *testing.T) {
+ f := NewFile()
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A1", &[]int{1, 2}))
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A2", &[]int{3, 4}))
+ formulaType, ref := STCellFormulaTypeArray, "C1:C2"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "A1:A2*B1:B2",
+ FormulaOpts{Ref: &ref, Type: &formulaType}))
+ result, err := f.CalcCellValue("Sheet1", "C1")
+ assert.NoError(t, err)
+ assert.Equal(t, "2", result)
+ result, err = f.CalcCellValue("Sheet1", "C2")
+ assert.NoError(t, err)
+ assert.Equal(t, "12", result)
+ })
+ t.Run("matrix_multiplication_with_defined_name", func(t *testing.T) {
+ f := NewFile()
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A1", &[]int{1, 2}))
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A2", &[]int{3, 4}))
+ assert.NoError(t, f.SetDefinedName(&DefinedName{
+ Name: "matrix",
+ RefersTo: "Sheet1!$A$1:$A$2",
+ }))
+ formulaType, ref := STCellFormulaTypeArray, "C1:C2"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "matrix*B1:B2+\"1\"",
+ FormulaOpts{Ref: &ref, Type: &formulaType}))
+ result, err := f.CalcCellValue("Sheet1", "C1")
+ assert.NoError(t, err)
+ assert.Equal(t, "3", result)
+ result, err = f.CalcCellValue("Sheet1", "C2")
+ assert.NoError(t, err)
+ assert.Equal(t, "13", result)
+ })
+ t.Run("columm_multiplication", func(t *testing.T) {
+ f := NewFile()
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A1", &[]int{1, 2}))
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A2", &[]int{3, 4}))
+ formulaType, ref := STCellFormulaTypeArray, "C1:C1048576"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "A:A*B:B",
+ FormulaOpts{Ref: &ref, Type: &formulaType}))
+ result, err := f.CalcCellValue("Sheet1", "C1")
+ assert.NoError(t, err)
+ assert.Equal(t, "2", result)
+ result, err = f.CalcCellValue("Sheet1", "C2")
+ assert.NoError(t, err)
+ assert.Equal(t, "12", result)
+ })
+ t.Run("row_multiplication", func(t *testing.T) {
+ f := NewFile()
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A1", &[]int{1, 2}))
+ assert.NoError(t, f.SetSheetRow("Sheet1", "A2", &[]int{3, 4}))
+ formulaType, ref := STCellFormulaTypeArray, "A3:XFD3"
+ assert.NoError(t, f.SetCellFormula("Sheet1", "A3", "1:1*2:2",
+ FormulaOpts{Ref: &ref, Type: &formulaType}))
+ result, err := f.CalcCellValue("Sheet1", "A3")
+ assert.NoError(t, err)
+ assert.Equal(t, "3", result)
+ result, err = f.CalcCellValue("Sheet1", "B3")
+ assert.NoError(t, err)
+ assert.Equal(t, "8", result)
+ })
+}
+
func TestCalcTRANSPOSE(t *testing.T) {
cellData := [][]interface{}{
{"a", "d"},
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// GetCellFormula provides a function to get formula from cell by given
// worksheet name and cell reference in spreadsheet.
func (f *File) GetCellFormula(sheet, cell string) (string, error) {
+ return f.getCellFormula(sheet, cell, false)
+}
+
+// getCellFormula provides a function to get transformed formula from cell by
+// given worksheet name and cell reference in spreadsheet.
+func (f *File) getCellFormula(sheet, cell string, transformed bool) (string, error) {
return f.getCellStringFunc(sheet, cell, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
+ if transformed && !f.formulaChecked {
+ if err := f.setArrayFormulaCells(); err != nil {
+ return "", false, err
+ }
+ f.formulaChecked = true
+ }
+ if transformed && c.f != "" {
+ return c.f, true, nil
+ }
if c.F == nil {
return "", false, nil
}
return err
}
c.F.T = *opt.Type
+ if c.F.T == STCellFormulaTypeArray && opt.Ref != nil {
+ if err = ws.setArrayFormula(sheet, &xlsxF{Ref: *opt.Ref, Content: formula}, f.GetDefinedName()); err != nil {
+ return err
+ }
+ }
if c.F.T == STCellFormulaTypeShared {
if err = ws.setSharedFormula(*opt.Ref); err != nil {
return err
return err
}
+// setArrayFormula transform the array formula in an array formula range to the
+// normal formula and set cells in this range to the formula as the normal
+// formula.
+func (ws *xlsxWorksheet) setArrayFormula(sheet string, formula *xlsxF, definedNames []DefinedName) error {
+ if len(strings.Split(formula.Ref, ":")) < 2 {
+ return nil
+ }
+ coordinates, err := rangeRefToCoordinates(formula.Ref)
+ if err != nil {
+ return err
+ }
+ _ = sortCoordinates(coordinates)
+ tokens, arrayFormulaOperandTokens, err := getArrayFormulaTokens(sheet, formula.Content, definedNames)
+ if err != nil {
+ return err
+ }
+ topLeftCol, topLeftRow := coordinates[0], coordinates[1]
+ for c := coordinates[0]; c <= coordinates[2]; c++ {
+ for r := coordinates[1]; r <= coordinates[3]; r++ {
+ colOffset, rowOffset := c-topLeftCol, r-topLeftRow
+ for i, af := range arrayFormulaOperandTokens {
+ colNum, rowNum := af.topLeftCol+colOffset, af.topLeftRow+rowOffset
+ if colNum <= af.bottomRightCol && rowNum <= af.bottomRightRow {
+ arrayFormulaOperandTokens[i].targetCellRef, _ = CoordinatesToCellName(colNum, rowNum)
+ }
+ }
+ ws.prepareSheetXML(c, r)
+ if cell := &ws.SheetData.Row[r-1].C[c-1]; cell.f == "" {
+ cell.f = transformArrayFormula(tokens, arrayFormulaOperandTokens)
+ }
+ }
+ }
+ return err
+}
+
+// setArrayFormulaCells transform the array formula in all worksheets to the
+// normal formula and set cells in the array formula reference range to the
+// formula as the normal formula.
+func (f *File) setArrayFormulaCells() error {
+ definedNames := f.GetDefinedName()
+ for _, sheetN := range f.GetSheetList() {
+ ws, err := f.workSheetReader(sheetN)
+ if err != nil {
+ if err.Error() == newNotWorksheetError(sheetN).Error() {
+ continue
+ }
+ return err
+ }
+ for _, row := range ws.SheetData.Row {
+ for _, cell := range row.C {
+ if cell.F != nil && cell.F.T == STCellFormulaTypeArray {
+ if err = ws.setArrayFormula(sheetN, cell.F, definedNames); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ }
+ return nil
+}
+
// setSharedFormula set shared formula for the cells.
func (ws *xlsxWorksheet) setSharedFormula(ref string) error {
coordinates, err := rangeRefToCoordinates(ref)
}
ok, err := f.checkCellInRangeRef("A1", "A:B")
- assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), err)
assert.False(t, ok)
ok, err = f.checkCellInRangeRef("AA0", "Z0:AB1")
- assert.EqualError(t, err, newCellNameToCoordinatesError("AA0", newInvalidCellNameError("AA0")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("AA0", newInvalidCellNameError("AA0")), err)
assert.False(t, ok)
}
assert.Equal(t, "123.42", val, "A1 should be 123.42")
})
f := NewFile()
- assert.EqualError(t, f.SetCellFloat(sheet, "A", 123.42, -1, 64), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.SetCellFloat(sheet, "A", 123.42, -1, 64))
// Test set cell float data type value with invalid sheet name
- assert.EqualError(t, f.SetCellFloat("Sheet:1", "A1", 123.42, -1, 64), ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, f.SetCellFloat("Sheet:1", "A1", 123.42, -1, 64))
}
func TestSetCellUint(t *testing.T) {
func TestSetCellValue(t *testing.T) {
f := NewFile()
- assert.EqualError(t, f.SetCellValue("Sheet1", "A", time.Now().UTC()), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
- assert.EqualError(t, f.SetCellValue("Sheet1", "A", time.Duration(1e13)), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.SetCellValue("Sheet1", "A", time.Now().UTC()))
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.SetCellValue("Sheet1", "A", time.Duration(1e13)))
// Test set cell value with column and row style inherit
style1, err := f.NewStyle(&Style{NumFmt: 2})
assert.NoError(t, err)
assert.Equal(t, "0.50", B2)
// Test set cell value with invalid sheet name
- assert.EqualError(t, f.SetCellValue("Sheet:1", "A1", "A1"), ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, f.SetCellValue("Sheet:1", "A1", "A1"))
// Test set cell value with unsupported charset shared strings table
f.SharedStrings = nil
f.Pkg.Store(defaultXMLPathSharedStrings, MacintoshCyrillicCharset)
func TestSetCellBool(t *testing.T) {
f := NewFile()
- assert.EqualError(t, f.SetCellBool("Sheet1", "A", true), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.SetCellBool("Sheet1", "A", true))
// Test set cell boolean data type value with invalid sheet name
- assert.EqualError(t, f.SetCellBool("Sheet:1", "A1", true), ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, f.SetCellBool("Sheet:1", "A1", true))
}
func TestSetCellTime(t *testing.T) {
assert.EqualError(t, value, "XML syntax error on line 1: invalid UTF-8")
// Test get cell value with invalid sheet name
_, err = f.GetCellValue("Sheet:1", "A1")
- assert.EqualError(t, err, ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, err)
}
func TestGetCellType(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, CellTypeSharedString, cellType)
_, err = f.GetCellType("Sheet1", "A")
- assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), err)
// Test get cell type with invalid sheet name
_, err = f.GetCellType("Sheet:1", "A1")
- assert.EqualError(t, err, ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, err)
}
func TestGetValueFrom(t *testing.T) {
// Test get cell formula with invalid sheet name
_, err = f.GetCellFormula("Sheet:1", "A1")
- assert.EqualError(t, err, ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, err)
// Test get cell formula on no formula cell
assert.NoError(t, f.SetCellValue("Sheet1", "A1", true))
formula, err := f.GetCellFormula("Sheet1", "B2")
assert.NoError(t, err)
assert.Equal(t, "", formula)
+
+ // Test get array formula with invalid cell range reference
+ f = NewFile()
+ assert.NoError(t, f.AddChartSheet("Chart1", &Chart{Type: Line}))
+ _, err = f.NewSheet("Sheet2")
+ assert.NoError(t, err)
+ formulaType, ref := STCellFormulaTypeArray, "B1:B2"
+ assert.NoError(t, f.SetCellFormula("Sheet2", "B1", "A1:B2", FormulaOpts{Ref: &ref, Type: &formulaType}))
+ ws, ok := f.Sheet.Load("xl/worksheets/sheet3.xml")
+ assert.True(t, ok)
+ ws.(*xlsxWorksheet).SheetData.Row[0].C[1].F.Ref = ":"
+ _, err = f.getCellFormula("Sheet2", "A1", true)
+ assert.Equal(t, newCellNameToCoordinatesError("", newInvalidCellNameError("")), err)
+
+ // Test set formula for the cells in array formula range with unsupported charset
+ f = NewFile()
+ f.Sheet.Delete("xl/worksheets/sheet1.xml")
+ f.Pkg.Store("xl/worksheets/sheet1.xml", MacintoshCyrillicCharset)
+ assert.EqualError(t, f.setArrayFormulaCells(), "XML syntax error on line 1: invalid UTF-8")
}
func ExampleFile_SetCellFloat() {
assert.NoError(t, f.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)"))
// Test set cell formula with invalid sheet name
- assert.EqualError(t, f.SetCellFormula("Sheet:1", "A1", "SUM(1,2)"), ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, f.SetCellFormula("Sheet:1", "A1", "SUM(1,2)"))
// Test set cell formula with illegal rows number
- assert.EqualError(t, f.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)"), newCellNameToCoordinatesError("C", newInvalidCellNameError("C")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("C", newInvalidCellNameError("C")), f.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)"))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellFormula1.xlsx")))
assert.NoError(t, f.Close())
ref = "D1:D5"
assert.NoError(t, f.SetCellFormula("Sheet1", "D1", "=A1+C1", FormulaOpts{Ref: &ref, Type: &formulaType}))
ref = ""
- assert.EqualError(t, f.SetCellFormula("Sheet1", "D1", "=A1+C1", FormulaOpts{Ref: &ref, Type: &formulaType}), ErrParameterInvalid.Error())
+ assert.Equal(t, ErrParameterInvalid, f.SetCellFormula("Sheet1", "D1", "=A1+C1", FormulaOpts{Ref: &ref, Type: &formulaType}))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellFormula5.xlsx")))
// Test set table formula for the cells
formulaType = STCellFormulaTypeDataTable
assert.NoError(t, f.SetCellFormula("Sheet1", "C2", "=SUM(Table1[[A]:[B]])", FormulaOpts{Type: &formulaType}))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellFormula6.xlsx")))
+
+ // Test set array formula with invalid cell range reference
+ formulaType, ref = STCellFormulaTypeArray, ":"
+ assert.Equal(t, newCellNameToCoordinatesError("", newInvalidCellNameError("")), f.SetCellFormula("Sheet1", "B1", "A1:A2", FormulaOpts{Ref: &ref, Type: &formulaType}))
+
+ // Test set array formula with invalid cell reference
+ formulaType, ref = STCellFormulaTypeArray, "A1:A2"
+ assert.Equal(t, ErrColumnNumber, f.SetCellFormula("Sheet1", "A1", "SUM(XFE1:XFE2)", FormulaOpts{Ref: &ref, Type: &formulaType}))
}
func TestGetCellRichText(t *testing.T) {
assert.EqualError(t, err, "sheet SheetN does not exist")
// Test set cell rich text with illegal cell reference
_, err = f.GetCellRichText("Sheet1", "A")
- assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), err)
// Test set rich text color theme without tint
assert.NoError(t, f.SetCellRichText("Sheet1", "A1", []RichTextRun{{Font: &Font{ColorTheme: &theme}}}))
// Test set rich text color tint without theme
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
// Test get cell rich text with invalid sheet name
_, err = f.GetCellRichText("Sheet:1", "A1")
- assert.EqualError(t, err, ErrSheetNameInvalid.Error())
+ assert.Equal(t, ErrSheetNameInvalid, err)
}
func TestSetCellRichText(t *testing.T) {
// Test set cell rich text with invalid sheet name
assert.EqualError(t, f.SetCellRichText("Sheet:1", "A1", richTextRun), ErrSheetNameInvalid.Error())
// Test set cell rich text with illegal cell reference
- assert.EqualError(t, f.SetCellRichText("Sheet1", "A", richTextRun), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.SetCellRichText("Sheet1", "A", richTextRun))
richTextRun = []RichTextRun{{Text: strings.Repeat("s", TotalCellChars+1)}}
// Test set cell rich text with characters over the maximum limit
assert.EqualError(t, f.SetCellRichText("Sheet1", "A1", richTextRun), ErrCellCharsLength.Error())
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
assert.NoError(t, err)
raw[2050] = 3
_, err = Decrypt(raw, &Options{Password: "password"})
- assert.EqualError(t, err, ErrUnsupportedEncryptMechanism.Error())
+ assert.Equal(t, ErrUnsupportedEncryptMechanism, err)
// Test encrypt spreadsheet with invalid password
assert.EqualError(t, f.SaveAs(filepath.Join("test", "Encryption.xlsx"), Options{Password: strings.Repeat("*", MaxFieldLength+1)}), ErrPasswordLengthInvalid.Error())
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
//
// See https://xuri.me/excelize for more information about this package.
package excelize
type File struct {
mu sync.Mutex
checked sync.Map
+ formulaChecked bool
options *Options
sharedStringItem [][]uint
sharedStringsMap map[string]int
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// Test add picture to worksheet from bytes
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}))
// Test add picture to worksheet from bytes with illegal cell reference
- assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.AddPictureFromBytes("Sheet1", "A", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}))
for _, preset := range [][]string{{"Q8", "gif"}, {"Q15", "jpg"}, {"Q22", "tif"}, {"Q28", "bmp"}} {
assert.NoError(t, f.AddPicture("Sheet1", preset[0], filepath.Join("test", "images", fmt.Sprintf("excel.%s", preset[1])), nil))
// Try to get picture from a worksheet with illegal cell reference
_, err = f.GetPictures("Sheet1", "A")
- assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), err)
// Try to get picture from a worksheet that doesn't contain any images
pics, err = f.GetPictures("Sheet3", "I9")
assert.EqualError(t, err, "sheet SheetN does not exist")
// Test calculate drawing resize with invalid coordinates
_, _, _, _, err = f.drawingResize("Sheet1", "", 1, 1, nil)
- assert.EqualError(t, err, newCellNameToCoordinatesError("", newInvalidCellNameError("")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("", newInvalidCellNameError("")), err)
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
assert.True(t, ok)
ws.(*xlsxWorksheet).MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
- assert.EqualError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
}
func TestSetContentTypePartRelsExtensions(t *testing.T) {
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="1"><c r="A" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
assert.True(t, rows.Next())
_, err = rows.Columns()
- assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), err)
// Test token is nil
rows.decoder = f.xmlNewDecoder(bytes.NewReader(nil))
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(`<worksheet><sheetData><row r="2"><c r="A" t="inlineStr"><is><t>A</t></is></c></row></sheetData></worksheet>`))
result, err = f.SearchSheet("Sheet1", "A")
- assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), err)
assert.Equal(t, []string(nil), result)
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(`<worksheet><sheetData><row r="0"><c r="A1" t="inlineStr"><is><t>A</t></is></c></row></sheetData></worksheet>`))
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
//
// This file contains default templates for XML files we don't yet populated
// based on content.
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of
-// data. This library needs Go version 1.16 or later.
+// data. This library needs Go version 1.18 or later.
package excelize
F *xlsxF `xml:"f"` // Formula
V string `xml:"v,omitempty"` // Value
IS *xlsxSI `xml:"is"`
+ f string
}
// xlsxF represents a formula for the cell. The formula expression is