Skip to content

Commit

Permalink
Enhances the performance of checkCellInRangeRef and merging cells.
Browse files Browse the repository at this point in the history
Enhances the performance of checkCellInRangeRef and merging cells.
  • Loading branch information
xuri committed Mar 19, 2023
1 parent 19fd9bf commit 32154a4
Showing 1 changed file with 19 additions and 47 deletions.
66 changes: 19 additions & 47 deletions cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -1388,77 +1388,49 @@ func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
// given cell reference.
func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error) {
cell = strings.ToUpper(cell)
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return cell, err
}
if ws.MergeCells != nil {
for i := 0; i < len(ws.MergeCells.Cells); i++ {
if ws.MergeCells.Cells[i] == nil {
ws.MergeCells.Cells = append(ws.MergeCells.Cells[:i], ws.MergeCells.Cells[i+1:]...)
i--
continue
}
ok, err := f.checkCellInRangeRef(cell, ws.MergeCells.Cells[i].Ref)
if err != nil {
return cell, err
if ref := ws.MergeCells.Cells[i].Ref; len(ws.MergeCells.Cells[i].rect) == 0 && ref != "" {
if strings.Count(ref, ":") != 1 {
ref += ":" + ref
}
rect, err := rangeRefToCoordinates(ref)
if err != nil {
return cell, err
}
_ = sortCoordinates(rect)
ws.MergeCells.Cells[i].rect = rect
}
if ok {
if cellInRange([]int{col, row}, ws.MergeCells.Cells[i].rect) {
cell = strings.Split(ws.MergeCells.Cells[i].Ref, ":")[0]
break
}
}
}
return cell, nil
}

func CellNameToCoordinatesCacheFunc(capacity int) func(string) (int, int, error) {
cache := make(map[string][2]int, capacity)

return func(cell string) (int, int, error) {
if pos, ok := cache[cell]; ok {
return pos[0], pos[1], nil
}

col, row, err := CellNameToCoordinates(cell)
if err != nil {
return 0, 0, err
}

cache[cell] = [2]int{col, row}
return col, row, nil
}
}

var CellNameToCoordinatesCache = CellNameToCoordinatesCacheFunc(1024)

func rangeRefToCoordinatesCacheFunc(capacity int) func(string) ([]int, error) {
cache := make(map[string][]int, capacity)

return func(rangeRef string) ([]int, error) {
if coords, ok := cache[rangeRef]; ok {
return coords, nil
}

coords, err := rangeRefToCoordinates(rangeRef)
if err != nil {
return nil, err
}

cache[rangeRef] = coords
return coords, nil
}
}

var rangeRefToCoordinatesCache = rangeRefToCoordinatesCacheFunc(1024)

// checkCellInRangeRef provides a function to determine if a given cell reference
// in a range.
func (f *File) checkCellInRangeRef(cell, rangeRef string) (bool, error) {
col, row, err := CellNameToCoordinatesCache(cell)
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return false, err
}

if strings.Count(rangeRef, ":") != 1 {
if rng := strings.Split(rangeRef, ":"); len(rng) != 2 {
return false, err
}
coordinates, err := rangeRefToCoordinatesCache(rangeRef)
coordinates, err := rangeRefToCoordinates(rangeRef)
if err != nil {
return false, err
}
Expand Down

0 comments on commit 32154a4

Please sign in to comment.