mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-25 13:48:53 +08:00
spreadsheet: initial shared formula support
This commit is contained in:
parent
d0820f1553
commit
d7515808d8
36
_examples/spreadsheet/shared-formula/main.go
Normal file
36
_examples/spreadsheet/shared-formula/main.go
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2017 Baliance. All rights reserved.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"baliance.com/gooxml/spreadsheet"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ss := spreadsheet.New()
|
||||
sheet := ss.AddSheet()
|
||||
|
||||
sheet.Cell("A1").SetNumber(1)
|
||||
sheet.Cell("B1").SetNumber(2)
|
||||
sheet.Cell("C1").SetNumber(3)
|
||||
sheet.Cell("D1").SetNumber(4)
|
||||
sheet.Cell("A2").SetNumber(5)
|
||||
sheet.Cell("B2").SetNumber(6)
|
||||
sheet.Cell("C2").SetNumber(7)
|
||||
sheet.Cell("D2").SetNumber(8)
|
||||
sheet.Cell("A3").SetNumber(9)
|
||||
sheet.Cell("B3").SetNumber(10)
|
||||
sheet.Cell("C3").SetNumber(11)
|
||||
sheet.Cell("D3").SetNumber(12)
|
||||
|
||||
sheet.Cell("A5").SetFormulaShared("=A1+1", 2, 3)
|
||||
sheet.Cell("A9").SetFormulaShared("=$A1+1", 2, 3)
|
||||
sheet.Cell("A13").SetFormulaShared("=$A$1+1", 2, 3)
|
||||
|
||||
ss.RecalculateFormulas()
|
||||
if err := ss.Validate(); err != nil {
|
||||
log.Fatalf("error validating: %s", err)
|
||||
}
|
||||
ss.SaveToFile("shared-formula.xlsx")
|
||||
}
|
@ -9,6 +9,7 @@ package spreadsheet
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"strconv"
|
||||
@ -93,6 +94,50 @@ func (c Cell) SetFormulaArray(s string) {
|
||||
c.x.F.Content = s
|
||||
}
|
||||
|
||||
// SetFormulaShared sets the cell type to formula shared, and the raw formula to
|
||||
// the given string. The range is the range of cells that the formula applies
|
||||
// to, and is used to conserve disk space.
|
||||
func (c Cell) SetFormulaShared(formula string, rows, cols uint32) error {
|
||||
c.clearValue()
|
||||
c.x.TAttr = sml.ST_CellTypeStr
|
||||
c.x.F = sml.NewCT_CellFormula()
|
||||
c.x.F.TAttr = sml.ST_CellFormulaTypeShared
|
||||
c.x.F.Content = formula
|
||||
col, rowIdx, err := ParseCellReference(c.Reference())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
colIdx := ColumnToIndex(col)
|
||||
|
||||
sid := uint32(0)
|
||||
for _, r := range c.s.SheetData.Row {
|
||||
for _, c := range r.C {
|
||||
if c.F != nil && c.F.SiAttr != nil && *c.F.SiAttr >= sid {
|
||||
sid = *c.F.SiAttr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ref := fmt.Sprintf("%s%d:%s%d", col, rowIdx, IndexToColumn(colIdx+cols), rowIdx+rows)
|
||||
fmt.Println("REF IS", ref)
|
||||
c.x.F.RefAttr = gooxml.String(ref)
|
||||
c.x.F.SiAttr = gooxml.Uint32(sid)
|
||||
sheet := Sheet{c.w, nil, c.s}
|
||||
for row := rowIdx; row <= rowIdx+rows; row++ {
|
||||
for col := colIdx; col <= colIdx+cols; col++ {
|
||||
if row == rowIdx && col == colIdx {
|
||||
continue
|
||||
}
|
||||
ref := fmt.Sprintf("%s%d", IndexToColumn(col), row)
|
||||
sheet.Cell(ref).Clear()
|
||||
sheet.Cell(ref).X().F = sml.NewCT_CellFormula()
|
||||
sheet.Cell(ref).X().F.TAttr = sml.ST_CellFormulaTypeShared
|
||||
sheet.Cell(ref).X().F.SiAttr = gooxml.Uint32(sid)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetString sets the cell type to string, and the value to the given string,
|
||||
// returning an ID from the shared strings table. To reuse a string, call
|
||||
// SetStringByID with the ID returned.
|
||||
|
@ -628,6 +628,9 @@ func (s *Sheet) RecalculateFormulas() {
|
||||
// array we need to expand the array out into cells
|
||||
if c.X().F.TAttr == sml.ST_CellFormulaTypeArray && res.Type == formula.ResultTypeArray {
|
||||
s.setArray(c.Reference(), res)
|
||||
} else if c.X().F.TAttr == sml.ST_CellFormulaTypeShared {
|
||||
// shared formula
|
||||
// s.setShared(c.X().F.RefAttr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user