Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
a8cbcfa3
excelize
项目概览
xuri
/
excelize
通知
13
Star
2
Fork
4
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
excelize
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
a8cbcfa3
编写于
10月 24, 2023
作者:
R
rjtee
提交者:
GitHub
10月 24, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
This closes #1306 and closes #1615 (#1698)
- Support adjust formula on inserting/deleting columns/rows
上级
05689d6a
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
186 addition
and
36 deletion
+186
-36
adjust.go
adjust.go
+118
-24
adjust_test.go
adjust_test.go
+46
-8
calc.go
calc.go
+1
-1
calc_test.go
calc_test.go
+1
-1
lib.go
lib.go
+3
-0
rows.go
rows.go
+1
-1
rows_test.go
rows_test.go
+15
-0
xmlCalcChain.go
xmlCalcChain.go
+1
-1
未找到文件。
adjust.go
浏览文件 @
a8cbcfa3
...
...
@@ -16,6 +16,8 @@ import (
"encoding/xml"
"io"
"strings"
"github.com/xuri/efp"
)
type
adjustDirection
bool
...
...
@@ -42,9 +44,9 @@ func (f *File) adjustHelper(sheet string, dir adjustDirection, num, offset int)
}
sheetID
:=
f
.
getSheetID
(
sheet
)
if
dir
==
rows
{
err
=
f
.
adjustRowDimensions
(
ws
,
num
,
offset
)
err
=
f
.
adjustRowDimensions
(
sheet
,
ws
,
num
,
offset
)
}
else
{
err
=
f
.
adjustColDimensions
(
ws
,
num
,
offset
)
err
=
f
.
adjustColDimensions
(
sheet
,
ws
,
num
,
offset
)
}
if
err
!=
nil
{
return
err
...
...
@@ -116,7 +118,7 @@ func (f *File) adjustCols(ws *xlsxWorksheet, col, offset int) error {
// adjustColDimensions provides a function to update column dimensions when
// inserting or deleting rows or columns.
func
(
f
*
File
)
adjustColDimensions
(
ws
*
xlsxWorksheet
,
col
,
offset
int
)
error
{
func
(
f
*
File
)
adjustColDimensions
(
sheet
string
,
ws
*
xlsxWorksheet
,
col
,
offset
int
)
error
{
for
rowIdx
:=
range
ws
.
SheetData
.
Row
{
for
_
,
v
:=
range
ws
.
SheetData
.
Row
[
rowIdx
]
.
C
{
if
cellCol
,
_
,
_
:=
CellNameToCoordinates
(
v
.
R
);
col
<=
cellCol
{
...
...
@@ -131,9 +133,11 @@ func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error {
if
cellCol
,
cellRow
,
_
:=
CellNameToCoordinates
(
v
.
R
);
col
<=
cellCol
{
if
newCol
:=
cellCol
+
offset
;
newCol
>
0
{
ws
.
SheetData
.
Row
[
rowIdx
]
.
C
[
colIdx
]
.
R
,
_
=
CoordinatesToCellName
(
newCol
,
cellRow
)
_
=
f
.
adjustFormula
(
ws
.
SheetData
.
Row
[
rowIdx
]
.
C
[
colIdx
]
.
F
,
columns
,
offset
,
false
)
}
}
if
err
:=
f
.
adjustFormula
(
sheet
,
ws
.
SheetData
.
Row
[
rowIdx
]
.
C
[
colIdx
]
.
F
,
columns
,
col
,
offset
,
false
);
err
!=
nil
{
return
err
}
}
}
return
f
.
adjustCols
(
ws
,
col
,
offset
)
...
...
@@ -141,40 +145,49 @@ func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error {
// adjustRowDimensions provides a function to update row dimensions when
// inserting or deleting rows or columns.
func
(
f
*
File
)
adjustRowDimensions
(
ws
*
xlsxWorksheet
,
row
,
offset
int
)
error
{
func
(
f
*
File
)
adjustRowDimensions
(
sheet
string
,
ws
*
xlsxWorksheet
,
row
,
offset
int
)
error
{
totalRows
:=
len
(
ws
.
SheetData
.
Row
)
if
totalRows
==
0
{
return
nil
}
lastRow
:=
&
ws
.
SheetData
.
Row
[
totalRows
-
1
]
if
newRow
:=
lastRow
.
R
+
offset
;
lastRow
.
R
>=
row
&&
newRow
>
0
&&
newRow
>
=
TotalRows
{
if
newRow
:=
lastRow
.
R
+
offset
;
lastRow
.
R
>=
row
&&
newRow
>
0
&&
newRow
>
TotalRows
{
return
ErrMaxRows
}
for
i
:=
0
;
i
<
len
(
ws
.
SheetData
.
Row
);
i
++
{
r
:=
&
ws
.
SheetData
.
Row
[
i
]
if
newRow
:=
r
.
R
+
offset
;
r
.
R
>=
row
&&
newRow
>
0
{
f
.
adjustSingleRowDimensions
(
r
,
newRow
,
offset
,
false
)
if
err
:=
f
.
adjustSingleRowDimensions
(
sheet
,
r
,
row
,
offset
,
false
);
err
!=
nil
{
return
err
}
}
}
return
nil
}
// adjustSingleRowDimensions provides a function to adjust single row dimensions.
func
(
f
*
File
)
adjustSingleRowDimensions
(
r
*
xlsxRow
,
num
,
offset
int
,
si
bool
)
{
r
.
R
=
num
func
(
f
*
File
)
adjustSingleRowDimensions
(
sheet
string
,
r
*
xlsxRow
,
num
,
offset
int
,
si
bool
)
error
{
r
.
R
+=
offset
for
i
,
col
:=
range
r
.
C
{
colName
,
_
,
_
:=
SplitCellName
(
col
.
R
)
r
.
C
[
i
]
.
R
,
_
=
JoinCellName
(
colName
,
num
)
_
=
f
.
adjustFormula
(
col
.
F
,
rows
,
offset
,
si
)
r
.
C
[
i
]
.
R
,
_
=
JoinCellName
(
colName
,
r
.
R
)
if
err
:=
f
.
adjustFormula
(
sheet
,
col
.
F
,
rows
,
num
,
offset
,
si
);
err
!=
nil
{
return
err
}
}
return
nil
}
// adjustFormula provides a function to adjust shared formula reference.
func
(
f
*
File
)
adjustFormula
(
formula
*
xlsxF
,
dir
adjustDirection
,
offset
int
,
si
bool
)
error
{
if
formula
!=
nil
&&
formula
.
Ref
!=
""
{
coordinates
,
err
:=
rangeRefToCoordinates
(
formula
.
Ref
)
// adjustFormula provides a function to adjust formula reference and shared
// formula reference.
func
(
f
*
File
)
adjustFormula
(
sheet
string
,
formula
*
xlsxF
,
dir
adjustDirection
,
num
,
offset
int
,
si
bool
)
error
{
if
formula
==
nil
{
return
nil
}
adjustRef
:=
func
(
ref
string
)
(
string
,
error
)
{
coordinates
,
err
:=
rangeRefToCoordinates
(
ref
)
if
err
!=
nil
{
return
err
return
ref
,
err
}
if
dir
==
columns
{
coordinates
[
0
]
+=
offset
...
...
@@ -183,16 +196,72 @@ func (f *File) adjustFormula(formula *xlsxF, dir adjustDirection, offset int, si
coordinates
[
1
]
+=
offset
coordinates
[
3
]
+=
offset
}
if
formula
.
Ref
,
err
=
f
.
coordinatesToRangeRef
(
coordinates
);
err
!=
nil
{
return
f
.
coordinatesToRangeRef
(
coordinates
)
}
var
err
error
if
formula
.
Ref
!=
""
{
if
formula
.
Ref
,
err
=
adjustRef
(
formula
.
Ref
);
err
!=
nil
{
return
err
}
if
si
&&
formula
.
Si
!=
nil
{
formula
.
Si
=
intPtr
(
*
formula
.
Si
+
1
)
}
}
if
formula
.
T
==
STCellFormulaTypeArray
{
formula
.
Content
,
err
=
adjustRef
(
strings
.
TrimPrefix
(
formula
.
Content
,
"="
))
return
err
}
if
formula
.
Content
!=
""
&&
!
strings
.
ContainsAny
(
formula
.
Content
,
"[:]"
)
{
content
,
err
:=
f
.
adjustFormulaRef
(
sheet
,
formula
.
Content
,
dir
,
num
,
offset
)
if
err
!=
nil
{
return
err
}
formula
.
Content
=
content
}
return
nil
}
// adjustFormulaRef returns adjusted formula text by giving adjusting direction
// and the base number of column or row, and offset.
func
(
f
*
File
)
adjustFormulaRef
(
sheet
string
,
text
string
,
dir
adjustDirection
,
num
,
offset
int
)
(
string
,
error
)
{
var
(
formulaText
string
definedNames
[]
string
ps
=
efp
.
ExcelParser
()
)
for
_
,
definedName
:=
range
f
.
GetDefinedName
()
{
if
definedName
.
Scope
==
"Workbook"
||
definedName
.
Scope
==
sheet
{
definedNames
=
append
(
definedNames
,
definedName
.
Name
)
}
}
for
_
,
token
:=
range
ps
.
Parse
(
text
)
{
if
token
.
TType
==
efp
.
TokenTypeOperand
&&
token
.
TSubType
==
efp
.
TokenSubTypeRange
{
if
inStrSlice
(
definedNames
,
token
.
TValue
,
true
)
!=
-
1
{
formulaText
+=
token
.
TValue
continue
}
c
,
r
,
err
:=
CellNameToCoordinates
(
token
.
TValue
)
if
err
!=
nil
{
return
formulaText
,
err
}
if
dir
==
columns
&&
c
>=
num
{
c
+=
offset
}
if
dir
==
rows
{
r
+=
offset
}
cell
,
err
:=
CoordinatesToCellName
(
c
,
r
,
strings
.
Contains
(
token
.
TValue
,
"$"
))
if
err
!=
nil
{
return
formulaText
,
err
}
formulaText
+=
cell
continue
}
formulaText
+=
token
.
TValue
}
return
formulaText
,
nil
}
// adjustHyperlinks provides a function to update hyperlinks when inserting or
// deleting rows or columns.
func
(
f
*
File
)
adjustHyperlinks
(
ws
*
xlsxWorksheet
,
sheet
string
,
dir
adjustDirection
,
num
,
offset
int
)
{
...
...
@@ -260,7 +329,7 @@ func (f *File) adjustTable(ws *xlsxWorksheet, sheet string, dir adjustDirection,
return
}
// Remove the table when deleting the header row of the table
if
dir
==
rows
&&
num
==
coordinates
[
0
]
{
if
dir
==
rows
&&
num
==
coordinates
[
0
]
&&
offset
==
-
1
{
ws
.
TableParts
.
TableParts
=
append
(
ws
.
TableParts
.
TableParts
[
:
idx
],
ws
.
TableParts
.
TableParts
[
idx
+
1
:
]
...
)
ws
.
TableParts
.
Count
=
len
(
ws
.
TableParts
.
TableParts
)
idx
--
...
...
@@ -316,8 +385,8 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
}
// adjustAutoFilterHelper provides a function for adjusting auto filter to
// compare and calculate cell reference by the giv
en adjust direction, operation
// reference and offset.
// compare and calculate cell reference by the giv
ing adjusting direction,
//
operation
reference and offset.
func
(
f
*
File
)
adjustAutoFilterHelper
(
dir
adjustDirection
,
coordinates
[]
int
,
num
,
offset
int
)
[]
int
{
if
dir
==
rows
{
if
coordinates
[
1
]
>=
num
{
...
...
@@ -422,13 +491,34 @@ func (f *File) deleteMergeCell(ws *xlsxWorksheet, idx int) {
}
}
// adjustCalcChainRef update the cell reference in calculation chain when
// inserting or deleting rows or columns.
func
(
f
*
File
)
adjustCalcChainRef
(
i
,
c
,
r
,
offset
int
,
dir
adjustDirection
)
{
if
dir
==
rows
{
if
rn
:=
r
+
offset
;
rn
>
0
{
f
.
CalcChain
.
C
[
i
]
.
R
,
_
=
CoordinatesToCellName
(
c
,
rn
)
}
return
}
if
nc
:=
c
+
offset
;
nc
>
0
{
f
.
CalcChain
.
C
[
i
]
.
R
,
_
=
CoordinatesToCellName
(
nc
,
r
)
}
}
// adjustCalcChain provides a function to update the calculation chain when
// inserting or deleting rows or columns.
func
(
f
*
File
)
adjustCalcChain
(
dir
adjustDirection
,
num
,
offset
,
sheetID
int
)
error
{
if
f
.
CalcChain
==
nil
{
return
nil
}
// If sheet ID is omitted, it is assumed to be the same as the i value of
// the previous cell.
var
prevSheetID
int
for
index
,
c
:=
range
f
.
CalcChain
.
C
{
if
c
.
I
==
0
{
c
.
I
=
prevSheetID
}
prevSheetID
=
c
.
I
if
c
.
I
!=
sheetID
{
continue
}
...
...
@@ -437,14 +527,18 @@ func (f *File) adjustCalcChain(dir adjustDirection, num, offset, sheetID int) er
return
err
}
if
dir
==
rows
&&
num
<=
rowNum
{
if
newRow
:=
rowNum
+
offset
;
newRow
>
0
{
f
.
CalcChain
.
C
[
index
]
.
R
,
_
=
CoordinatesToCellName
(
colNum
,
newRow
)
if
num
==
rowNum
&&
offset
==
-
1
{
_
=
f
.
deleteCalcChain
(
c
.
I
,
c
.
R
)
continue
}
f
.
adjustCalcChainRef
(
index
,
colNum
,
rowNum
,
offset
,
dir
)
}
if
dir
==
columns
&&
num
<=
colNum
{
if
newCol
:=
colNum
+
offset
;
newCol
>
0
{
f
.
CalcChain
.
C
[
index
]
.
R
,
_
=
CoordinatesToCellName
(
newCol
,
rowNum
)
if
num
==
colNum
&&
offset
==
-
1
{
_
=
f
.
deleteCalcChain
(
c
.
I
,
c
.
R
)
continue
}
f
.
adjustCalcChainRef
(
index
,
colNum
,
rowNum
,
offset
,
dir
)
}
}
return
nil
...
...
adjust_test.go
浏览文件 @
a8cbcfa3
...
...
@@ -357,13 +357,18 @@ func TestAdjustHelper(t *testing.T) {
func
TestAdjustCalcChain
(
t
*
testing
.
T
)
{
f
:=
NewFile
()
f
.
CalcChain
=
&
xlsxCalcChain
{
C
:
[]
xlsxCalcChainC
{
{
R
:
"B2"
,
I
:
2
},
{
R
:
"B2"
,
I
:
1
},
},
C
:
[]
xlsxCalcChainC
{{
R
:
"B2"
,
I
:
2
},
{
R
:
"B2"
,
I
:
1
},
{
R
:
"A1"
,
I
:
1
}},
}
assert
.
NoError
(
t
,
f
.
InsertCols
(
"Sheet1"
,
"A"
,
1
))
assert
.
NoError
(
t
,
f
.
InsertRows
(
"Sheet1"
,
1
,
1
))
f
.
CalcChain
=
&
xlsxCalcChain
{
C
:
[]
xlsxCalcChainC
{{
R
:
"B2"
,
I
:
1
},
{
R
:
"B3"
},
{
R
:
"A1"
}},
}
assert
.
NoError
(
t
,
f
.
RemoveRow
(
"Sheet1"
,
3
))
assert
.
NoError
(
t
,
f
.
RemoveCol
(
"Sheet1"
,
"B"
))
f
.
CalcChain
=
&
xlsxCalcChain
{
C
:
[]
xlsxCalcChainC
{{
R
:
"B2"
,
I
:
2
},
{
R
:
"B2"
,
I
:
1
}}}
f
.
CalcChain
.
C
[
1
]
.
R
=
"invalid coordinates"
assert
.
Equal
(
t
,
f
.
InsertCols
(
"Sheet1"
,
"A"
,
1
),
newCellNameToCoordinatesError
(
"invalid coordinates"
,
newInvalidCellNameError
(
"invalid coordinates"
)))
f
.
CalcChain
=
nil
...
...
@@ -449,11 +454,11 @@ func TestAdjustCols(t *testing.T) {
func
TestAdjustFormula
(
t
*
testing
.
T
)
{
f
:=
NewFile
()
formulaType
,
ref
:=
STCellFormulaTypeShared
,
"C1:C5"
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"C1"
,
"
=
A1+B1"
,
FormulaOpts
{
Ref
:
&
ref
,
Type
:
&
formulaType
}))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"C1"
,
"A1+B1"
,
FormulaOpts
{
Ref
:
&
ref
,
Type
:
&
formulaType
}))
assert
.
NoError
(
t
,
f
.
DuplicateRowTo
(
"Sheet1"
,
1
,
10
))
assert
.
NoError
(
t
,
f
.
InsertCols
(
"Sheet1"
,
"B"
,
1
))
assert
.
NoError
(
t
,
f
.
InsertRows
(
"Sheet1"
,
1
,
1
))
for
cell
,
expected
:=
range
map
[
string
]
string
{
"D2"
:
"
=A1+B1"
,
"D3"
:
"=A2+B2"
,
"D11"
:
"=A1+B
1"
}
{
for
cell
,
expected
:=
range
map
[
string
]
string
{
"D2"
:
"
A2+C2"
,
"D3"
:
"A3+C3"
,
"D11"
:
"A11+C1
1"
}
{
formula
,
err
:=
f
.
GetCellFormula
(
"Sheet1"
,
cell
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
expected
,
formula
)
...
...
@@ -461,7 +466,40 @@ func TestAdjustFormula(t *testing.T) {
assert
.
NoError
(
t
,
f
.
SaveAs
(
filepath
.
Join
(
"test"
,
"TestAdjustFormula.xlsx"
)))
assert
.
NoError
(
t
,
f
.
Close
())
assert
.
NoError
(
t
,
f
.
adjustFormula
(
nil
,
rows
,
0
,
false
))
assert
.
Equal
(
t
,
f
.
adjustFormula
(
&
xlsxF
{
Ref
:
"-"
},
rows
,
0
,
false
),
ErrParameterInvalid
)
assert
.
Equal
(
t
,
f
.
adjustFormula
(
&
xlsxF
{
Ref
:
"XFD1:XFD1"
},
columns
,
1
,
false
),
ErrColumnNumber
)
assert
.
NoError
(
t
,
f
.
adjustFormula
(
"Sheet1"
,
nil
,
rows
,
0
,
0
,
false
))
assert
.
Equal
(
t
,
ErrParameterInvalid
,
f
.
adjustFormula
(
"Sheet1"
,
&
xlsxF
{
Ref
:
"-"
},
rows
,
0
,
0
,
false
))
assert
.
Equal
(
t
,
ErrColumnNumber
,
f
.
adjustFormula
(
"Sheet1"
,
&
xlsxF
{
Ref
:
"XFD1:XFD1"
},
columns
,
0
,
1
,
false
))
_
,
err
:=
f
.
adjustFormulaRef
(
"Sheet1"
,
"XFE1"
,
columns
,
0
,
1
)
assert
.
Equal
(
t
,
ErrColumnNumber
,
err
)
_
,
err
=
f
.
adjustFormulaRef
(
"Sheet1"
,
"XFD1"
,
columns
,
0
,
1
)
assert
.
Equal
(
t
,
ErrColumnNumber
,
err
)
f
=
NewFile
()
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"B1"
,
"XFD1"
))
assert
.
Equal
(
t
,
ErrColumnNumber
,
f
.
InsertCols
(
"Sheet1"
,
"A"
,
1
))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"B2"
,
fmt
.
Sprintf
(
"A%d"
,
TotalRows
)))
assert
.
Equal
(
t
,
ErrMaxRows
,
f
.
InsertRows
(
"Sheet1"
,
1
,
1
))
// Test adjust formula with defined name in formula text
f
=
NewFile
()
assert
.
NoError
(
t
,
f
.
SetDefinedName
(
&
DefinedName
{
Name
:
"Amount"
,
RefersTo
:
"Sheet1!$B$2"
,
}))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"B2"
,
"Amount+B3"
))
assert
.
NoError
(
t
,
f
.
RemoveRow
(
"Sheet1"
,
1
))
formula
,
err
:=
f
.
GetCellFormula
(
"Sheet1"
,
"B1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
"Amount+B2"
,
formula
)
// Test adjust formula with array formula
f
=
NewFile
()
formulaType
,
reference
:=
STCellFormulaTypeArray
,
"A3:A3"
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A3"
,
"=A1:A2"
,
FormulaOpts
{
Ref
:
&
reference
,
Type
:
&
formulaType
}))
assert
.
NoError
(
t
,
f
.
InsertRows
(
"Sheet1"
,
1
,
1
))
formula
,
err
=
f
.
GetCellFormula
(
"Sheet1"
,
"A4"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
"A2:A3"
,
formula
)
}
calc.go
浏览文件 @
a8cbcfa3
...
...
@@ -14454,7 +14454,7 @@ func (fn *formulaFuncs) ADDRESS(argsList *list.List) formulaArg {
if rowNum.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
if rowNum.Number >
=
TotalRows {
if rowNum.Number > TotalRows {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
colNum := argsList.Front().Next().Value.(formulaArg).ToNumber()
...
...
calc_test.go
浏览文件 @
a8cbcfa3
...
...
@@ -3970,7 +3970,7 @@ func TestCalcCellValue(t *testing.T) {
"=ADDRESS(1,1,0,TRUE)"
:
{
"#NUM!"
,
"#NUM!"
},
"=ADDRESS(1,16385,2,TRUE)"
:
{
"#VALUE!"
,
"#VALUE!"
},
"=ADDRESS(1,16385,3,TRUE)"
:
{
"#VALUE!"
,
"#VALUE!"
},
"=ADDRESS(104857
6
,1,1,TRUE)"
:
{
"#VALUE!"
,
"#VALUE!"
},
"=ADDRESS(104857
7
,1,1,TRUE)"
:
{
"#VALUE!"
,
"#VALUE!"
},
// CHOOSE
"=CHOOSE()"
:
{
"#VALUE!"
,
"CHOOSE requires 2 arguments"
},
"=CHOOSE(
\"
index_num
\"
,0)"
:
{
"#VALUE!"
,
"CHOOSE requires first argument of type number"
},
...
...
lib.go
浏览文件 @
a8cbcfa3
...
...
@@ -270,6 +270,9 @@ func CoordinatesToCellName(col, row int, abs ...bool) (string, error) {
if
col
<
1
||
row
<
1
{
return
""
,
newCoordinatesToCellNameError
(
col
,
row
)
}
if
row
>
TotalRows
{
return
""
,
ErrMaxRows
}
sign
:=
""
for
_
,
a
:=
range
abs
{
if
a
{
...
...
rows.go
浏览文件 @
a8cbcfa3
...
...
@@ -652,7 +652,7 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
}
rowCopy
.
C
=
append
(
make
([]
xlsxC
,
0
,
len
(
rowCopy
.
C
)),
rowCopy
.
C
...
)
f
.
adjustSingleRowDimensions
(
&
rowCopy
,
row2
,
row2
-
row
,
true
)
_
=
f
.
adjustSingleRowDimensions
(
sheet
,
&
rowCopy
,
row
,
row2
-
row
,
true
)
if
idx2
!=
-
1
{
ws
.
SheetData
.
Row
[
idx2
]
=
rowCopy
...
...
rows_test.go
浏览文件 @
a8cbcfa3
...
...
@@ -870,6 +870,21 @@ func TestDuplicateRow(t *testing.T) {
f
:=
NewFile
()
// Test duplicate row with invalid sheet name
assert
.
EqualError
(
t
,
f
.
DuplicateRowTo
(
"Sheet:1"
,
1
,
2
),
ErrSheetNameInvalid
.
Error
())
f
=
NewFile
()
assert
.
NoError
(
t
,
f
.
SetDefinedName
(
&
DefinedName
{
Name
:
"Amount"
,
RefersTo
:
"Sheet1!$B$1"
,
}))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A1"
,
"Amount+C1"
))
assert
.
NoError
(
t
,
f
.
SetCellValue
(
"Sheet1"
,
"A10"
,
"A10"
))
assert
.
NoError
(
t
,
f
.
DuplicateRowTo
(
"Sheet1"
,
1
,
10
))
formula
,
err
:=
f
.
GetCellFormula
(
"Sheet1"
,
"A10"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
"Amount+C10"
,
formula
)
value
,
err
:=
f
.
GetCellValue
(
"Sheet1"
,
"A11"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
"A10"
,
value
)
}
func
TestDuplicateRowTo
(
t
*
testing
.
T
)
{
...
...
xmlCalcChain.go
浏览文件 @
a8cbcfa3
...
...
@@ -76,7 +76,7 @@ type xlsxCalcChain struct {
// | boolean datatype.
type
xlsxCalcChainC
struct
{
R
string
`xml:"r,attr"`
I
int
`xml:"i,attr"`
I
int
`xml:"i,attr
,omitempty
"`
L
bool
`xml:"l,attr,omitempty"`
S
bool
`xml:"s,attr,omitempty"`
T
bool
`xml:"t,attr,omitempty"`
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录