Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
5e247de8
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 搜索 >>
未验证
提交
5e247de8
编写于
11月 14, 2023
作者:
Y
Yang Li
提交者:
GitHub
11月 14, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support set time period type conditional formatting (#1718)
上级
2499bf6b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
83 addition
and
49 deletion
+83
-49
styles.go
styles.go
+72
-42
styles_test.go
styles_test.go
+11
-7
未找到文件。
styles.go
浏览文件 @
5e247de8
...
...
@@ -26,15 +26,13 @@ import (
// validType defined the list of valid validation types.
var
validType
=
map
[
string
]
string
{
"cell"
:
"cellIs"
,
"date"
:
"date"
,
// Doesn't support currently
"time"
:
"time"
,
// Doesn't support currently
"average"
:
"aboveAverage"
,
"duplicate"
:
"duplicateValues"
,
"unique"
:
"uniqueValues"
,
"top"
:
"top10"
,
"bottom"
:
"top10"
,
"text"
:
"text"
,
"time_period"
:
"timePeriod"
,
// Doesn't support currently
"time_period"
:
"timePeriod"
,
"blanks"
:
"containsBlanks"
,
"no_blanks"
:
"notContainsBlanks"
,
"errors"
:
"containsErrors"
,
...
...
@@ -48,60 +46,62 @@ var validType = map[string]string{
// criteriaType defined the list of valid criteria types.
var
criteriaType
=
map
[
string
]
string
{
"between"
:
"between"
,
"not between"
:
"notBetween"
,
"equal to"
:
"equal"
,
"="
:
"equal"
,
"=="
:
"equal"
,
"not equal to"
:
"notEqual"
,
"!="
:
"notEqual"
,
"<"
:
"lessThan"
,
"<="
:
"lessThanOrEqual"
,
"<>"
:
"notEqual"
,
"greater than"
:
"greaterThan"
,
"="
:
"equal"
,
"=="
:
"equal"
,
">"
:
"greaterThan"
,
"less than"
:
"lessThan"
,
"<"
:
"lessThan"
,
"greater than or equal to"
:
"greaterThanOrEqual"
,
">="
:
"greaterThanOrEqual"
,
"less than or equal to"
:
"lessThanOrEqual"
,
"<="
:
"lessThanOrEqual"
,
"containing"
:
"containsText"
,
"not containing"
:
"notContains"
,
"begins with"
:
"beginsWith"
,
"between"
:
"between"
,
"containing"
:
"containsText"
,
"continue month"
:
"nextMonth"
,
"continue week"
:
"nextWeek"
,
"ends with"
:
"endsWith"
,
"yesterday"
:
"yesterday"
,
"today"
:
"today"
,
"equal to"
:
"equal"
,
"greater than or equal to"
:
"greaterThanOrEqual"
,
"greater than"
:
"greaterThan"
,
"last 7 days"
:
"last7Days"
,
"last week"
:
"lastWeek"
,
"this week"
:
"thisWeek"
,
"continue week"
:
"continueWeek"
,
"last month"
:
"lastMonth"
,
"last week"
:
"lastWeek"
,
"less than or equal to"
:
"lessThanOrEqual"
,
"less than"
:
"lessThan"
,
"not between"
:
"notBetween"
,
"not containing"
:
"notContains"
,
"not equal to"
:
"notEqual"
,
"this month"
:
"thisMonth"
,
"continue month"
:
"continueMonth"
,
"this week"
:
"thisWeek"
,
"today"
:
"today"
,
"tomorrow"
:
"tomorrow"
,
"yesterday"
:
"yesterday"
,
}
// operatorType defined the list of valid operator types.
var
operatorType
=
map
[
string
]
string
{
"
lastMonth"
:
"last mon
th"
,
"
beginsWith"
:
"begins wi
th"
,
"between"
:
"between"
,
"notEqual"
:
"not equal to"
,
"containsText"
:
"containing"
,
"endsWith"
:
"ends with"
,
"equal"
:
"equal to"
,
"greaterThan"
:
"greater than"
,
"greaterThanOrEqual"
:
"greater than or equal to"
,
"last7Days"
:
"last 7 days"
,
"lastMonth"
:
"last month"
,
"lastWeek"
:
"last week"
,
"lessThan"
:
"less than"
,
"lessThanOrEqual"
:
"less than or equal to"
,
"today"
:
"today"
,
"equal"
:
"equal to"
,
"nextMonth"
:
"continue month"
,
"nextWeek"
:
"continue week"
,
"notBetween"
:
"not between"
,
"notContains"
:
"not containing"
,
"notEqual"
:
"not equal to"
,
"thisMonth"
:
"this month"
,
"thisWeek"
:
"this week"
,
"endsWith"
:
"ends with"
,
"today"
:
"today"
,
"tomorrow"
:
"tomorrow"
,
"yesterday"
:
"yesterday"
,
"lessThan"
:
"less than"
,
"beginsWith"
:
"begins with"
,
"last7Days"
:
"last 7 days"
,
"thisMonth"
:
"this month"
,
"containsText"
:
"containing"
,
"lastWeek"
:
"last week"
,
"continueWeek"
:
"continue week"
,
"continueMonth"
:
"continue month"
,
"notBetween"
:
"not between"
,
"greaterThanOrEqual"
:
"greater than or equal to"
,
}
// stylesReader provides a function to get the pointer to the structure after
...
...
@@ -1225,6 +1225,7 @@ var (
// drawContFmtFunc defines functions to create conditional formats.
drawContFmtFunc
=
map
[
string
]
func
(
p
int
,
ct
,
ref
,
GUID
string
,
fmtCond
*
ConditionalFormatOptions
)
(
*
xlsxCfRule
,
*
xlsxX14CfRule
){
"cellIs"
:
drawCondFmtCellIs
,
"timePeriod"
:
drawCondFmtTimePeriod
,
"text"
:
drawCondFmtText
,
"top10"
:
drawCondFmtTop10
,
"aboveAverage"
:
drawCondFmtAboveAverage
,
...
...
@@ -1243,6 +1244,7 @@ var (
// extractContFmtFunc defines functions to get conditional formats.
extractContFmtFunc
=
map
[
string
]
func
(
c
*
xlsxCfRule
,
extLst
*
xlsxExtLst
)
ConditionalFormatOptions
{
"cellIs"
:
extractCondFmtCellIs
,
"timePeriod"
:
extractCondFmtTimePeriod
,
"containsText"
:
extractCondFmtText
,
"notContainsText"
:
extractCondFmtText
,
"beginsWith"
:
extractCondFmtText
,
...
...
@@ -2241,10 +2243,6 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
// | Value
// | MinValue
// | MaxValue
// date | Criteria
// | Value
// | MinValue
// | MaxValue
// time_period | Criteria
// text | Criteria
// | Value
...
...
@@ -2772,6 +2770,12 @@ func extractCondFmtCellIs(c *xlsxCfRule, extLst *xlsxExtLst) ConditionalFormatOp
return
format
}
// extractCondFmtTimePeriod provides a function to extract conditional format
// settings for time period by given conditional formatting rule.
func
extractCondFmtTimePeriod
(
c
*
xlsxCfRule
,
extLst
*
xlsxExtLst
)
ConditionalFormatOptions
{
return
ConditionalFormatOptions
{
StopIfTrue
:
c
.
StopIfTrue
,
Type
:
"time_period"
,
Criteria
:
operatorType
[
c
.
Operator
],
Format
:
*
c
.
DxfID
}
}
// extractCondFmtText provides a function to extract conditional format
// settings for text cell values by given conditional formatting rule.
func
extractCondFmtText
(
c
*
xlsxCfRule
,
extLst
*
xlsxExtLst
)
ConditionalFormatOptions
{
...
...
@@ -3034,6 +3038,32 @@ func drawCondFmtCellIs(p int, ct, ref, GUID string, format *ConditionalFormatOpt
return
c
,
nil
}
// drawCondFmtTimePeriod provides a function to create conditional formatting
// rule for time period by given priority, criteria type and format settings.
func
drawCondFmtTimePeriod
(
p
int
,
ct
,
ref
,
GUID
string
,
format
*
ConditionalFormatOptions
)
(
*
xlsxCfRule
,
*
xlsxX14CfRule
)
{
return
&
xlsxCfRule
{
Priority
:
p
+
1
,
StopIfTrue
:
format
.
StopIfTrue
,
Type
:
"timePeriod"
,
Operator
:
ct
,
Formula
:
[]
string
{
map
[
string
]
string
{
"yesterday"
:
fmt
.
Sprintf
(
"FLOOR(%s,1)=TODAY()-1"
,
ref
),
"today"
:
fmt
.
Sprintf
(
"FLOOR(%s,1)=TODAY()"
,
ref
),
"tomorrow"
:
fmt
.
Sprintf
(
"FLOOR(%s,1)=TODAY()+1"
,
ref
),
"last 7 days"
:
fmt
.
Sprintf
(
"AND(TODAY()-FLOOR(%[1]s,1)<=6,FLOOR(%[1]s,1)<=TODAY())"
,
ref
),
"last week"
:
fmt
.
Sprintf
(
"AND(TODAY()-ROUNDDOWN(%[1]s,0)>=(WEEKDAY(TODAY())),TODAY()-ROUNDDOWN(%[1]s,0)<(WEEKDAY(TODAY())+7))"
,
ref
),
"this week"
:
fmt
.
Sprintf
(
"AND(TODAY()-ROUNDDOWN(%[1]s,0)<=WEEKDAY(TODAY())-1,ROUNDDOWN(%[1]s,0)-TODAY()>=7-WEEKDAY(TODAY()))"
,
ref
),
"continue week"
:
fmt
.
Sprintf
(
"AND(ROUNDDOWN(%[1]s,0)-TODAY()>(7-WEEKDAY(TODAY())),ROUNDDOWN(%[1]s,0)-TODAY()<(15-WEEKDAY(TODAY())))"
,
ref
),
"last month"
:
fmt
.
Sprintf
(
"AND(MONTH(%[1]s)=MONTH(TODAY())-1,OR(YEAR(%[1]s)=YEAR(TODAY()),AND(MONTH(%[1]s)=1,YEAR(%[1]s)=YEAR(TODAY())-1)))"
,
ref
),
"this month"
:
fmt
.
Sprintf
(
"AND(MONTH(%[1]s)=MONTH(TODAY()),YEAR(%[1]s)=YEAR(TODAY()))"
,
ref
),
"continue month"
:
fmt
.
Sprintf
(
"AND(MONTH(%[1]s)=MONTH(TODAY())+1,OR(YEAR(%[1]s)=YEAR(TODAY()),AND(MONTH(%[1]s)=12,YEAR(%[1]s)=YEAR(TODAY())+1)))"
,
ref
),
}[
ct
],
},
DxfID
:
intPtr
(
format
.
Format
),
},
nil
}
// drawCondFmtText provides a function to create conditional formatting rule for
// text cell values by given priority, criteria type and format settings.
func
drawCondFmtText
(
p
int
,
ct
,
ref
,
GUID
string
,
format
*
ConditionalFormatOptions
)
(
*
xlsxCfRule
,
*
xlsxX14CfRule
)
{
...
...
styles_test.go
浏览文件 @
5e247de8
...
...
@@ -192,19 +192,23 @@ func TestSetConditionalFormat(t *testing.T) {
// Test creating a conditional format with invalid icon set style
assert
.
Equal
(
t
,
ErrParameterInvalid
,
f
.
SetConditionalFormat
(
"Sheet1"
,
"A1:A2"
,
[]
ConditionalFormatOptions
{{
Type
:
"icon_set"
,
IconStyle
:
"unknown"
}}))
// Test unsupported conditional formatting rule types
for
_
,
val
:=
range
[]
string
{
"date"
,
"time"
,
"time_period"
,
}
{
assert
.
Equal
(
t
,
ErrParameterInvalid
,
f
.
SetConditionalFormat
(
"Sheet1"
,
"A1"
,
[]
ConditionalFormatOptions
{{
Type
:
val
}}))
}
assert
.
Equal
(
t
,
ErrParameterInvalid
,
f
.
SetConditionalFormat
(
"Sheet1"
,
"A1"
,
[]
ConditionalFormatOptions
{{
Type
:
"unsupported"
}}))
}
func
TestGetConditionalFormats
(
t
*
testing
.
T
)
{
for
_
,
format
:=
range
[][]
ConditionalFormatOptions
{
{{
Type
:
"cell"
,
Format
:
1
,
Criteria
:
"greater than"
,
Value
:
"6"
}},
{{
Type
:
"cell"
,
Format
:
1
,
Criteria
:
"between"
,
MinValue
:
"6"
,
MaxValue
:
"8"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"yesterday"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"today"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"tomorrow"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"last 7 days"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"last week"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"this week"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"continue week"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"last month"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"this month"
}},
{{
Type
:
"time_period"
,
Format
:
1
,
Criteria
:
"continue month"
}},
{{
Type
:
"text"
,
Format
:
1
,
Criteria
:
"containing"
,
Value
:
"~!@#$%^&*()_+{}|:<>?
\"
';"
}},
{{
Type
:
"text"
,
Format
:
1
,
Criteria
:
"not containing"
,
Value
:
"text"
}},
{{
Type
:
"text"
,
Format
:
1
,
Criteria
:
"begins with"
,
Value
:
"prefix"
}},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录