Skip to content

Commit f6f14f5

Browse files
authored
Speed up merge cells
1 parent 61d0ed1 commit f6f14f5

14 files changed

+226
-129
lines changed

adjust.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
145145
return nil
146146
}
147147

148-
coordinates, err := f.areaRefToCoordinates(ws.AutoFilter.Ref)
148+
coordinates, err := areaRefToCoordinates(ws.AutoFilter.Ref)
149149
if err != nil {
150150
return err
151151
}
@@ -199,7 +199,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
199199

200200
for i := 0; i < len(ws.MergeCells.Cells); i++ {
201201
areaData := ws.MergeCells.Cells[i]
202-
coordinates, err := f.areaRefToCoordinates(areaData.Ref)
202+
coordinates, err := areaRefToCoordinates(areaData.Ref)
203203
if err != nil {
204204
return err
205205
}
@@ -219,7 +219,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
219219
x1 = f.adjustMergeCellsHelper(x1, num, offset)
220220
x2 = f.adjustMergeCellsHelper(x2, num, offset)
221221
}
222-
if x1 == x2 && y1 == y2 {
222+
if x1 == x2 && y1 == y2 && i >= 0 {
223223
f.deleteMergeCell(ws, i)
224224
i--
225225
}
@@ -234,7 +234,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
234234
// compare and calculate cell axis by the given pivot, operation axis and
235235
// offset.
236236
func (f *File) adjustMergeCellsHelper(pivot, num, offset int) int {
237-
if pivot >= num {
237+
if pivot > num {
238238
pivot += offset
239239
if pivot < 1 {
240240
return 1

adjust_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ func TestAdjustHelper(t *testing.T) {
8484
assert.EqualError(t, f.adjustHelper("SheetN", rows, 0, 0), "sheet SheetN is not exist")
8585
}
8686

87+
func TestAdjustMergeCellsHelper(t *testing.T) {
88+
assert.Equal(t, 1, NewFile().adjustMergeCellsHelper(1, 0, -2))
89+
}
90+
8791
func TestAdjustCalcChain(t *testing.T) {
8892
f := NewFile()
8993
f.CalcChain = &xlsxCalcChain{

calc.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -5103,11 +5103,11 @@ func (fn *formulaFuncs) kth(name string, argsList *list.List) formulaArg {
51035103
return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 2 arguments", name))
51045104
}
51055105
array := argsList.Front().Value.(formulaArg).ToList()
5106-
kArg := argsList.Back().Value.(formulaArg).ToNumber()
5107-
if kArg.Type != ArgNumber {
5108-
return kArg
5106+
argK := argsList.Back().Value.(formulaArg).ToNumber()
5107+
if argK.Type != ArgNumber {
5108+
return argK
51095109
}
5110-
k := int(kArg.Number)
5110+
k := int(argK.Number)
51115111
if k < 1 {
51125112
return newErrorFormulaArg(formulaErrorNUM, "k should be > 0")
51135113
}
@@ -7177,7 +7177,7 @@ func (fn *formulaFuncs) VLOOKUP(argsList *list.List) formulaArg {
71777177
func vlookupBinarySearch(tableArray, lookupValue formulaArg) (matchIdx int, wasExact bool) {
71787178
var low, high, lastMatchIdx int = 0, len(tableArray.Matrix) - 1, -1
71797179
for low <= high {
7180-
var mid int = low + (high-low)/2
7180+
mid := low + (high-low)/2
71817181
mtx := tableArray.Matrix[mid]
71827182
lhs := mtx[0]
71837183
switch lookupValue.Type {
@@ -7216,7 +7216,7 @@ func vlookupBinarySearch(tableArray, lookupValue formulaArg) (matchIdx int, wasE
72167216
func hlookupBinarySearch(row []formulaArg, lookupValue formulaArg) (matchIdx int, wasExact bool) {
72177217
var low, high, lastMatchIdx int = 0, len(row) - 1, -1
72187218
for low <= high {
7219-
var mid int = low + (high-low)/2
7219+
mid := low + (high-low)/2
72207220
mtx := row[mid]
72217221
result := compareFormulaArg(mtx, lookupValue, false, false)
72227222
if result == criteriaEq {

cell.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,28 @@ func (f *File) SetCellValue(sheet, axis string, value interface{}) error {
101101
return err
102102
}
103103

104+
// String extracts characters from a string item.
105+
func (x xlsxSI) String() string {
106+
if len(x.R) > 0 {
107+
var rows strings.Builder
108+
for _, s := range x.R {
109+
if s.T != nil {
110+
rows.WriteString(s.T.Val)
111+
}
112+
}
113+
return bstrUnmarshal(rows.String())
114+
}
115+
if x.T != nil {
116+
return bstrUnmarshal(x.T.Val)
117+
}
118+
return ""
119+
}
120+
121+
// hasValue determine if cell non-blank value.
122+
func (c *xlsxC) hasValue() bool {
123+
return c.S != 0 || c.V != "" || c.F != nil || c.T != ""
124+
}
125+
104126
// setCellIntFunc is a wrapper of SetCellInt.
105127
func (f *File) setCellIntFunc(sheet, axis string, value interface{}) error {
106128
var err error
@@ -431,13 +453,11 @@ func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error) {
431453
if _, _, err := SplitCellName(axis); err != nil {
432454
return false, "", err
433455
}
434-
435456
ws, err := f.workSheetReader(sheet)
436457
if err != nil {
437458
return false, "", err
438459
}
439-
axis, err = f.mergeCellsParser(ws, axis)
440-
if err != nil {
460+
if axis, err = f.mergeCellsParser(ws, axis); err != nil {
441461
return false, "", err
442462
}
443463
if ws.Hyperlinks != nil {
@@ -485,8 +505,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
485505
if err != nil {
486506
return err
487507
}
488-
axis, err = f.mergeCellsParser(ws, axis)
489-
if err != nil {
508+
if axis, err = f.mergeCellsParser(ws, axis); err != nil {
490509
return err
491510
}
492511

@@ -932,7 +951,7 @@ func (f *File) checkCellInArea(cell, area string) (bool, error) {
932951
if len(rng) != 2 {
933952
return false, err
934953
}
935-
coordinates, err := f.areaRefToCoordinates(area)
954+
coordinates, err := areaRefToCoordinates(area)
936955
if err != nil {
937956
return false, err
938957
}

col.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,10 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
616616
// getColWidth provides a function to get column width in pixels by given
617617
// sheet name and column number.
618618
func (f *File) getColWidth(sheet string, col int) int {
619-
xlsx, _ := f.workSheetReader(sheet)
620-
if xlsx.Cols != nil {
619+
ws, _ := f.workSheetReader(sheet)
620+
if ws.Cols != nil {
621621
var width float64
622-
for _, v := range xlsx.Cols.Col {
622+
for _, v := range ws.Cols.Col {
623623
if v.Min <= col && col <= v.Max {
624624
width = v.Width
625625
}

lib.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,11 @@ func CoordinatesToCellName(col, row int, abs ...bool) (string, error) {
221221

222222
// areaRefToCoordinates provides a function to convert area reference to a
223223
// pair of coordinates.
224-
func (f *File) areaRefToCoordinates(ref string) ([]int, error) {
224+
func areaRefToCoordinates(ref string) ([]int, error) {
225225
rng := strings.Split(strings.Replace(ref, "$", "", -1), ":")
226226
if len(rng) < 2 {
227227
return nil, ErrParameterInvalid
228228
}
229-
230229
return areaRangeToCoordinates(rng[0], rng[1])
231230
}
232231

@@ -290,7 +289,7 @@ func (f *File) flatSqref(sqref string) (cells map[int][][]int, err error) {
290289
}
291290
cells[col] = append(cells[col], []int{col, row})
292291
case 2:
293-
if coordinates, err = f.areaRefToCoordinates(ref); err != nil {
292+
if coordinates, err = areaRefToCoordinates(ref); err != nil {
294293
return
295294
}
296295
_ = sortCoordinates(coordinates)

0 commit comments

Comments
 (0)