mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-29 13:49:10 +08:00
spreadsheet: add fast paths for appending rows/cells
This commit is contained in:
parent
382c157c11
commit
9b89ae1f12
@ -61,10 +61,22 @@ func (r Row) SetHidden(hidden bool) {
|
|||||||
|
|
||||||
// AddCell adds a cell to a spreadsheet.
|
// AddCell adds a cell to a spreadsheet.
|
||||||
func (r Row) AddCell() Cell {
|
func (r Row) AddCell() Cell {
|
||||||
|
numCells := uint32(len(r.x.C))
|
||||||
|
var nextCellID *string
|
||||||
|
if numCells > 0 {
|
||||||
|
prevCellName := gooxml.Stringf("%s%d", IndexToColumn(numCells-1), r.RowNumber())
|
||||||
|
// previous cell has an expected name
|
||||||
|
if r.x.C[numCells-1].RAttr != nil && *r.x.C[numCells-1].RAttr == *prevCellName {
|
||||||
|
nextCellID = gooxml.Stringf("%s%d", IndexToColumn(numCells), r.RowNumber())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c := spreadsheetml.NewCT_Cell()
|
c := spreadsheetml.NewCT_Cell()
|
||||||
c.TAttr = spreadsheetml.ST_CellTypeN
|
c.TAttr = spreadsheetml.ST_CellTypeN
|
||||||
|
|
||||||
r.x.C = append(r.x.C, c)
|
r.x.C = append(r.x.C, c)
|
||||||
|
|
||||||
|
// fast path failed, so find the last cell and add another
|
||||||
|
if nextCellID == nil {
|
||||||
nextIdx := uint32(0)
|
nextIdx := uint32(0)
|
||||||
for _, c := range r.x.C {
|
for _, c := range r.x.C {
|
||||||
if c.RAttr != nil {
|
if c.RAttr != nil {
|
||||||
@ -74,7 +86,9 @@ func (r Row) AddCell() Cell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.RAttr = gooxml.Stringf("%s%d", IndexToColumn(nextIdx), r.RowNumber())
|
nextCellID = gooxml.Stringf("%s%d", IndexToColumn(nextIdx), r.RowNumber())
|
||||||
|
}
|
||||||
|
c.RAttr = nextCellID
|
||||||
return Cell{r.w, r.s, r.x, c}
|
return Cell{r.w, r.s, r.x, c}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,11 +80,27 @@ func (s Sheet) AddNumberedRow(rowNum uint32) Row {
|
|||||||
return Row{s.w, s.x, r}
|
return Row{s.w, s.x, r}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addNumberedRowFast is a fast path that can be used when adding consecutive
|
||||||
|
// rows and not skipping any.
|
||||||
|
func (s Sheet) addNumberedRowFast(rowNum uint32) Row {
|
||||||
|
r := sml.NewCT_Row()
|
||||||
|
r.RAttr = gooxml.Uint32(rowNum)
|
||||||
|
s.x.SheetData.Row = append(s.x.SheetData.Row, r)
|
||||||
|
return Row{s.w, s.x, r}
|
||||||
|
}
|
||||||
|
|
||||||
// AddRow adds a new row to a sheet. You can mix this with numbered rows,
|
// AddRow adds a new row to a sheet. You can mix this with numbered rows,
|
||||||
// however it will get confusing. You should prefer to use either automatically
|
// however it will get confusing. You should prefer to use either automatically
|
||||||
// numbered rows with AddRow or manually numbered rows with Row/AddNumberedRow
|
// numbered rows with AddRow or manually numbered rows with Row/AddNumberedRow
|
||||||
func (s Sheet) AddRow() Row {
|
func (s Sheet) AddRow() Row {
|
||||||
maxRowID := uint32(0)
|
maxRowID := uint32(0)
|
||||||
|
|
||||||
|
numRows := uint32(len(s.x.SheetData.Row))
|
||||||
|
// fast path, adding consecutive rows
|
||||||
|
if numRows > 0 && s.x.SheetData.Row[numRows-1].RAttr != nil && *s.x.SheetData.Row[numRows-1].RAttr == numRows {
|
||||||
|
return s.addNumberedRowFast(numRows + 1)
|
||||||
|
}
|
||||||
|
|
||||||
// find the max row number
|
// find the max row number
|
||||||
for _, r := range s.x.SheetData.Row {
|
for _, r := range s.x.SheetData.Row {
|
||||||
if r.RAttr != nil && *r.RAttr > maxRowID {
|
if r.RAttr != nil && *r.RAttr > maxRowID {
|
||||||
|
25
spreadsheet/sheet_bench_test.go
Normal file
25
spreadsheet/sheet_bench_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package spreadsheet_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"baliance.com/gooxml/spreadsheet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkAddRow(b *testing.B) {
|
||||||
|
ss := spreadsheet.New()
|
||||||
|
sheet := ss.AddSheet()
|
||||||
|
for r := 0; r < b.N; r++ {
|
||||||
|
sheet.AddRow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAddCell(b *testing.B) {
|
||||||
|
ss := spreadsheet.New()
|
||||||
|
sheet := ss.AddSheet()
|
||||||
|
row := sheet.AddRow()
|
||||||
|
|
||||||
|
for c := 0; c < b.N; c++ {
|
||||||
|
row.AddCell()
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user