Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
866e7fd9
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 搜索 >>
未验证
提交
866e7fd9
编写于
11月 28, 2023
作者:
B
Bram Vanbilsen
提交者:
GitHub
11月 29, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
This closes #1729, support copy conditional format and data validation on duplicate row (#1733)
上级
bce2789c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
123 addition
and
10 deletion
+123
-10
rows.go
rows.go
+82
-8
rows_test.go
rows_test.go
+41
-2
未找到文件。
rows.go
浏览文件 @
866e7fd9
...
...
@@ -18,10 +18,24 @@ import (
"math"
"os"
"strconv"
"strings"
"github.com/mohae/deepcopy"
)
// duplicateHelperFunc defines functions to duplicate helper.
var
duplicateHelperFunc
=
[
3
]
func
(
*
File
,
*
xlsxWorksheet
,
string
,
int
,
int
)
error
{
func
(
f
*
File
,
ws
*
xlsxWorksheet
,
sheet
string
,
row
,
row2
int
)
error
{
return
f
.
duplicateConditionalFormat
(
ws
,
sheet
,
row
,
row2
)
},
func
(
f
*
File
,
ws
*
xlsxWorksheet
,
sheet
string
,
row
,
row2
int
)
error
{
return
f
.
duplicateDataValidations
(
ws
,
sheet
,
row
,
row2
)
},
func
(
f
*
File
,
ws
*
xlsxWorksheet
,
sheet
string
,
row
,
row2
int
)
error
{
return
f
.
duplicateMergeCells
(
ws
,
sheet
,
row
,
row2
)
},
}
// GetRows return all the rows in a sheet by given worksheet name, returned as
// a two-dimensional array, where the value of the cell is converted to the
// string type. If the cell format can be applied to the value of the cell,
...
...
@@ -618,7 +632,7 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
}
if
row2
<
1
||
row
==
row2
{
return
nil
return
err
}
var
ok
bool
...
...
@@ -637,7 +651,7 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
}
if
!
ok
{
return
nil
return
err
}
idx2
:=
-
1
...
...
@@ -647,10 +661,6 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
break
}
}
if
idx2
==
-
1
&&
len
(
ws
.
SheetData
.
Row
)
>=
row2
{
return
nil
}
rowCopy
.
C
=
append
(
make
([]
xlsxC
,
0
,
len
(
rowCopy
.
C
)),
rowCopy
.
C
...
)
rowCopy
.
adjustSingleRowDimensions
(
row2
-
row
)
_
=
f
.
adjustSingleRowFormulas
(
sheet
,
sheet
,
&
rowCopy
,
row
,
row2
-
row
,
true
)
...
...
@@ -660,12 +670,76 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
}
else
{
ws
.
SheetData
.
Row
=
append
(
ws
.
SheetData
.
Row
,
rowCopy
)
}
return
f
.
duplicateMergeCells
(
sheet
,
ws
,
row
,
row2
)
for
_
,
fn
:=
range
duplicateHelperFunc
{
if
err
:=
fn
(
f
,
ws
,
sheet
,
row
,
row2
);
err
!=
nil
{
return
err
}
}
return
err
}
// duplicateConditionalFormat create conditional formatting for the destination
// row if there are conditional formats in the copied row.
func
(
f
*
File
)
duplicateConditionalFormat
(
ws
*
xlsxWorksheet
,
sheet
string
,
row
,
row2
int
)
error
{
var
cfs
[]
*
xlsxConditionalFormatting
for
_
,
cf
:=
range
ws
.
ConditionalFormatting
{
if
cf
!=
nil
{
if
!
strings
.
Contains
(
cf
.
SQRef
,
":"
)
{
cf
.
SQRef
+=
":"
+
cf
.
SQRef
}
abs
:=
strings
.
Contains
(
cf
.
SQRef
,
"$"
)
coordinates
,
err
:=
rangeRefToCoordinates
(
cf
.
SQRef
)
if
err
!=
nil
{
return
err
}
x1
,
y1
,
x2
,
y2
:=
coordinates
[
0
],
coordinates
[
1
],
coordinates
[
2
],
coordinates
[
3
]
if
y1
==
y2
&&
y1
==
row
{
cfCopy
:=
deepcopy
.
Copy
(
*
cf
)
.
(
xlsxConditionalFormatting
)
if
cfCopy
.
SQRef
,
err
=
f
.
coordinatesToRangeRef
([]
int
{
x1
,
row2
,
x2
,
row2
},
abs
);
err
!=
nil
{
return
err
}
cfs
=
append
(
cfs
,
&
cfCopy
)
}
}
}
ws
.
ConditionalFormatting
=
append
(
ws
.
ConditionalFormatting
,
cfs
...
)
return
nil
}
// duplicateDataValidations create data validations for the destination row if
// there are data validation rules in the copied row.
func
(
f
*
File
)
duplicateDataValidations
(
ws
*
xlsxWorksheet
,
sheet
string
,
row
,
row2
int
)
error
{
if
ws
.
DataValidations
==
nil
{
return
nil
}
var
dvs
[]
*
xlsxDataValidation
for
_
,
dv
:=
range
ws
.
DataValidations
.
DataValidation
{
if
dv
!=
nil
{
if
!
strings
.
Contains
(
dv
.
Sqref
,
":"
)
{
dv
.
Sqref
+=
":"
+
dv
.
Sqref
}
abs
:=
strings
.
Contains
(
dv
.
Sqref
,
"$"
)
coordinates
,
err
:=
rangeRefToCoordinates
(
dv
.
Sqref
)
if
err
!=
nil
{
return
err
}
x1
,
y1
,
x2
,
y2
:=
coordinates
[
0
],
coordinates
[
1
],
coordinates
[
2
],
coordinates
[
3
]
if
y1
==
y2
&&
y1
==
row
{
dvCopy
:=
deepcopy
.
Copy
(
*
dv
)
.
(
xlsxDataValidation
)
if
dvCopy
.
Sqref
,
err
=
f
.
coordinatesToRangeRef
([]
int
{
x1
,
row2
,
x2
,
row2
},
abs
);
err
!=
nil
{
return
err
}
dvs
=
append
(
dvs
,
&
dvCopy
)
}
}
}
ws
.
DataValidations
.
DataValidation
=
append
(
ws
.
DataValidations
.
DataValidation
,
dvs
...
)
return
nil
}
// duplicateMergeCells merge cells in the destination row if there are single
// row merged cells in the copied row.
func
(
f
*
File
)
duplicateMergeCells
(
sheet
string
,
ws
*
xlsxWorksheet
,
row
,
row2
int
)
error
{
func
(
f
*
File
)
duplicateMergeCells
(
ws
*
xlsxWorksheet
,
sheet
string
,
row
,
row2
int
)
error
{
if
ws
.
MergeCells
==
nil
{
return
nil
}
...
...
rows_test.go
浏览文件 @
866e7fd9
...
...
@@ -878,6 +878,23 @@ func TestDuplicateRow(t *testing.T) {
}))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"A1"
,
"Amount+C1"
))
assert
.
NoError
(
t
,
f
.
SetCellValue
(
"Sheet1"
,
"A10"
,
"A10"
))
format
,
err
:=
f
.
NewConditionalStyle
(
&
Style
{
Font
:
&
Font
{
Color
:
"9A0511"
},
Fill
:
Fill
{
Type
:
"pattern"
,
Color
:
[]
string
{
"FEC7CE"
},
Pattern
:
1
}})
assert
.
NoError
(
t
,
err
)
expected
:=
[]
ConditionalFormatOptions
{
{
Type
:
"cell"
,
Criteria
:
"greater than"
,
Format
:
format
,
Value
:
"0"
},
}
assert
.
NoError
(
t
,
f
.
SetConditionalFormat
(
"Sheet1"
,
"A1"
,
expected
))
dv
:=
NewDataValidation
(
true
)
dv
.
Sqref
=
"A1"
assert
.
NoError
(
t
,
dv
.
SetDropList
([]
string
{
"1"
,
"2"
,
"3"
}))
assert
.
NoError
(
t
,
f
.
AddDataValidation
(
"Sheet1"
,
dv
))
ws
,
ok
:=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
assert
.
True
(
t
,
ok
)
ws
.
(
*
xlsxWorksheet
)
.
DataValidations
.
DataValidation
[
0
]
.
Sqref
=
"A1"
assert
.
NoError
(
t
,
f
.
DuplicateRowTo
(
"Sheet1"
,
1
,
10
))
formula
,
err
:=
f
.
GetCellFormula
(
"Sheet1"
,
"A10"
)
assert
.
NoError
(
t
,
err
)
...
...
@@ -885,6 +902,28 @@ func TestDuplicateRow(t *testing.T) {
value
,
err
:=
f
.
GetCellValue
(
"Sheet1"
,
"A11"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
"A10"
,
value
)
cfs
,
err
:=
f
.
GetConditionalFormats
(
"Sheet1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Len
(
t
,
cfs
,
2
)
assert
.
Equal
(
t
,
expected
,
cfs
[
"A10:A10"
])
dvs
,
err
:=
f
.
GetDataValidations
(
"Sheet1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Len
(
t
,
dvs
,
2
)
assert
.
Equal
(
t
,
"A10:A10"
,
dvs
[
1
]
.
Sqref
)
// Test duplicate data validation with row number exceeds maximum limit
assert
.
Equal
(
t
,
ErrMaxRows
,
f
.
duplicateDataValidations
(
ws
.
(
*
xlsxWorksheet
),
"Sheet1"
,
1
,
TotalRows
+
1
))
// Test duplicate data validation with invalid range reference
ws
.
(
*
xlsxWorksheet
)
.
DataValidations
.
DataValidation
[
0
]
.
Sqref
=
"A"
assert
.
Equal
(
t
,
newCellNameToCoordinatesError
(
"A"
,
newInvalidCellNameError
(
"A"
)),
f
.
duplicateDataValidations
(
ws
.
(
*
xlsxWorksheet
),
"Sheet1"
,
1
,
10
))
// Test duplicate conditional formatting with row number exceeds maximum limit
assert
.
Equal
(
t
,
ErrMaxRows
,
f
.
duplicateConditionalFormat
(
ws
.
(
*
xlsxWorksheet
),
"Sheet1"
,
1
,
TotalRows
+
1
))
// Test duplicate conditional formatting with invalid range reference
ws
.
(
*
xlsxWorksheet
)
.
ConditionalFormatting
[
0
]
.
SQRef
=
"A"
assert
.
Equal
(
t
,
newCellNameToCoordinatesError
(
"A"
,
newInvalidCellNameError
(
"A"
)),
f
.
duplicateConditionalFormat
(
ws
.
(
*
xlsxWorksheet
),
"Sheet1"
,
1
,
10
))
}
func
TestDuplicateRowTo
(
t
*
testing
.
T
)
{
...
...
@@ -911,9 +950,9 @@ func TestDuplicateMergeCells(t *testing.T) {
ws
:=
&
xlsxWorksheet
{
MergeCells
:
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A1:-"
}},
}}
assert
.
EqualError
(
t
,
f
.
duplicateMergeCells
(
"Sheet1"
,
ws
,
0
,
0
),
`cannot convert cell "-" to coordinates: invalid cell name "-"`
)
assert
.
EqualError
(
t
,
f
.
duplicateMergeCells
(
ws
,
"Sheet1"
,
0
,
0
),
`cannot convert cell "-" to coordinates: invalid cell name "-"`
)
ws
.
MergeCells
.
Cells
[
0
]
.
Ref
=
"A1:B1"
assert
.
EqualError
(
t
,
f
.
duplicateMergeCells
(
"SheetN"
,
ws
,
1
,
2
),
"sheet SheetN does not exist"
)
assert
.
EqualError
(
t
,
f
.
duplicateMergeCells
(
ws
,
"SheetN"
,
1
,
2
),
"sheet SheetN does not exist"
)
}
func
TestGetValueFromInlineStr
(
t
*
testing
.
T
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录