9
9
10
10
package excelize
11
11
12
- import "strings"
12
+ import (
13
+ "errors"
14
+ "strings"
15
+ )
13
16
14
17
type adjustDirection bool
15
18
@@ -140,46 +143,85 @@ func (f *File) adjustAutoFilter(xlsx *xlsxWorksheet, dir adjustDirection, num, o
140
143
return nil
141
144
}
142
145
143
- rng := strings .Split (xlsx .AutoFilter .Ref , ":" )
144
- firstCell := rng [0 ]
145
- lastCell := rng [1 ]
146
-
147
- firstCol , firstRow , err := CellNameToCoordinates (firstCell )
146
+ coordinates , err := f .areaRefToCoordinates (xlsx .AutoFilter .Ref )
148
147
if err != nil {
149
148
return err
150
149
}
150
+ x1 , y1 , x2 , y2 := coordinates [0 ], coordinates [1 ], coordinates [2 ], coordinates [3 ]
151
151
152
- lastCol , lastRow , err := CellNameToCoordinates (lastCell )
153
- if err != nil {
154
- return err
155
- }
156
-
157
- if (dir == rows && firstRow == num && offset < 0 ) || (dir == columns && firstCol == num && lastCol == num ) {
152
+ if (dir == rows && y1 == num && offset < 0 ) || (dir == columns && x1 == num && x2 == num ) {
158
153
xlsx .AutoFilter = nil
159
154
for rowIdx := range xlsx .SheetData .Row {
160
155
rowData := & xlsx .SheetData .Row [rowIdx ]
161
- if rowData .R > firstRow && rowData .R <= lastRow {
156
+ if rowData .R > y1 && rowData .R <= y2 {
162
157
rowData .Hidden = false
163
158
}
164
159
}
165
160
return nil
166
161
}
167
162
163
+ coordinates = f .adjustAutoFilterHelper (dir , coordinates , num , offset )
164
+ x1 , y1 , x2 , y2 = coordinates [0 ], coordinates [1 ], coordinates [2 ], coordinates [3 ]
165
+
166
+ if xlsx .AutoFilter .Ref , err = f .coordinatesToAreaRef ([]int {x1 , y1 , x2 , y2 }); err != nil {
167
+ return err
168
+ }
169
+ return nil
170
+ }
171
+
172
+ // adjustAutoFilterHelper provides a function for adjusting auto filter to
173
+ // compare and calculate cell axis by the given adjust direction, operation
174
+ // axis and offset.
175
+ func (f * File ) adjustAutoFilterHelper (dir adjustDirection , coordinates []int , num , offset int ) []int {
168
176
if dir == rows {
169
- if firstRow >= num {
170
- firstCell , _ = CoordinatesToCellName ( firstCol , firstRow + offset )
177
+ if coordinates [ 1 ] >= num {
178
+ coordinates [ 1 ] += offset
171
179
}
172
- if lastRow >= num {
173
- lastCell , _ = CoordinatesToCellName ( lastCol , lastRow + offset )
180
+ if coordinates [ 3 ] >= num {
181
+ coordinates [ 3 ] += offset
174
182
}
175
183
} else {
176
- if lastCol >= num {
177
- lastCell , _ = CoordinatesToCellName ( lastCol + offset , lastRow )
184
+ if coordinates [ 2 ] >= num {
185
+ coordinates [ 2 ] += offset
178
186
}
179
187
}
188
+ return coordinates
189
+ }
180
190
181
- xlsx .AutoFilter .Ref = firstCell + ":" + lastCell
182
- return nil
191
+ // areaRefToCoordinates provides a function to convert area reference to a
192
+ // pair of coordinates.
193
+ func (f * File ) areaRefToCoordinates (ref string ) ([]int , error ) {
194
+ coordinates := make ([]int , 4 )
195
+ rng := strings .Split (ref , ":" )
196
+ firstCell := rng [0 ]
197
+ lastCell := rng [1 ]
198
+ var err error
199
+ coordinates [0 ], coordinates [1 ], err = CellNameToCoordinates (firstCell )
200
+ if err != nil {
201
+ return coordinates , err
202
+ }
203
+ coordinates [2 ], coordinates [3 ], err = CellNameToCoordinates (lastCell )
204
+ if err != nil {
205
+ return coordinates , err
206
+ }
207
+ return coordinates , err
208
+ }
209
+
210
+ // coordinatesToAreaRef provides a function to convert a pair of coordinates
211
+ // to area reference.
212
+ func (f * File ) coordinatesToAreaRef (coordinates []int ) (string , error ) {
213
+ if len (coordinates ) != 4 {
214
+ return "" , errors .New ("coordinates length must be 4" )
215
+ }
216
+ firstCell , err := CoordinatesToCellName (coordinates [0 ], coordinates [1 ])
217
+ if err != nil {
218
+ return "" , err
219
+ }
220
+ lastCell , err := CoordinatesToCellName (coordinates [2 ], coordinates [3 ])
221
+ if err != nil {
222
+ return "" , err
223
+ }
224
+ return firstCell + ":" + lastCell , err
183
225
}
184
226
185
227
// adjustMergeCells provides a function to update merged cells when inserting
@@ -190,59 +232,56 @@ func (f *File) adjustMergeCells(xlsx *xlsxWorksheet, dir adjustDirection, num, o
190
232
}
191
233
192
234
for i , areaData := range xlsx .MergeCells .Cells {
193
- rng := strings .Split (areaData .Ref , ":" )
194
- firstCell := rng [0 ]
195
- lastCell := rng [1 ]
196
-
197
- firstCol , firstRow , err := CellNameToCoordinates (firstCell )
235
+ coordinates , err := f .areaRefToCoordinates (areaData .Ref )
198
236
if err != nil {
199
237
return err
200
238
}
201
-
202
- lastCol , lastRow , err := CellNameToCoordinates (lastCell )
203
- if err != nil {
204
- return err
205
- }
206
-
207
- adjust := func (v int ) int {
208
- if v >= num {
209
- v += offset
210
- if v < 1 {
211
- return 1
212
- }
213
- return v
214
- }
215
- return v
216
- }
217
-
239
+ x1 , y1 , x2 , y2 := coordinates [0 ], coordinates [1 ], coordinates [2 ], coordinates [3 ]
218
240
if dir == rows {
219
- firstRow = adjust (firstRow )
220
- lastRow = adjust (lastRow )
241
+ if y1 == num && y2 == num && offset < 0 {
242
+ f .deleteMergeCell (xlsx , i )
243
+ }
244
+ y1 = f .adjustMergeCellsHelper (y1 , num , offset )
245
+ y2 = f .adjustMergeCellsHelper (y2 , num , offset )
221
246
} else {
222
- firstCol = adjust (firstCol )
223
- lastCol = adjust (lastCol )
224
- }
225
-
226
- if firstCol == lastCol && firstRow == lastRow {
227
- if len (xlsx .MergeCells .Cells ) > 1 {
228
- xlsx .MergeCells .Cells = append (xlsx .MergeCells .Cells [:i ], xlsx .MergeCells .Cells [i + 1 :]... )
229
- xlsx .MergeCells .Count = len (xlsx .MergeCells .Cells )
230
- } else {
231
- xlsx .MergeCells = nil
247
+ if x1 == num && x2 == num && offset < 0 {
248
+ f .deleteMergeCell (xlsx , i )
232
249
}
250
+ x1 = f .adjustMergeCellsHelper (x1 , num , offset )
251
+ x2 = f .adjustMergeCellsHelper (x2 , num , offset )
233
252
}
234
-
235
- if firstCell , err = CoordinatesToCellName (firstCol , firstRow ); err != nil {
253
+ if x1 == x2 && y1 == y2 {
254
+ f .deleteMergeCell (xlsx , i )
255
+ }
256
+ if areaData .Ref , err = f .coordinatesToAreaRef ([]int {x1 , y1 , x2 , y2 }); err != nil {
236
257
return err
237
258
}
259
+ }
260
+ return nil
261
+ }
238
262
239
- if lastCell , err = CoordinatesToCellName (lastCol , lastRow ); err != nil {
240
- return err
263
+ // adjustMergeCellsHelper provides a function for adjusting merge cells to
264
+ // compare and calculate cell axis by the given pivot, operation axis and
265
+ // offset.
266
+ func (f * File ) adjustMergeCellsHelper (pivot , num , offset int ) int {
267
+ if pivot >= num {
268
+ pivot += offset
269
+ if pivot < 1 {
270
+ return 1
241
271
}
272
+ return pivot
273
+ }
274
+ return pivot
275
+ }
242
276
243
- areaData .Ref = firstCell + ":" + lastCell
277
+ // deleteMergeCell provides a function to delete merged cell by given index.
278
+ func (f * File ) deleteMergeCell (sheet * xlsxWorksheet , idx int ) {
279
+ if len (sheet .MergeCells .Cells ) > 1 {
280
+ sheet .MergeCells .Cells = append (sheet .MergeCells .Cells [:idx ], sheet .MergeCells .Cells [idx + 1 :]... )
281
+ sheet .MergeCells .Count = len (sheet .MergeCells .Cells )
282
+ } else {
283
+ sheet .MergeCells = nil
244
284
}
245
- return nil
246
285
}
247
286
248
287
// adjustCalcChain provides a function to update the calculation chain when
0 commit comments