@@ -1193,59 +1193,59 @@ var (
11931193 }
11941194
11951195 // extractContFmtFunc defines functions to get conditional formats.
1196- extractContFmtFunc = map [string ]func (* File , * xlsxCfRule , * xlsxExtLst ) ConditionalFormatOptions {
1197- "cellIs" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1196+ extractContFmtFunc = map [string ]func (* File , string , * xlsxCfRule , * xlsxExtLst ) ConditionalFormatOptions {
1197+ "cellIs" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
11981198 return f .extractCondFmtCellIs (c , extLst )
11991199 },
1200- "timePeriod" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1201- return f .extractCondFmtTimePeriod (c , extLst )
1200+ "timePeriod" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1201+ return f .extractCondFmtTimePeriod (c , ref , extLst )
12021202 },
1203- "containsText" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1203+ "containsText" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12041204 return f .extractCondFmtText (c , extLst )
12051205 },
1206- "notContainsText" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1206+ "notContainsText" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12071207 return f .extractCondFmtText (c , extLst )
12081208 },
1209- "beginsWith" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1209+ "beginsWith" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12101210 return f .extractCondFmtText (c , extLst )
12111211 },
1212- "endsWith" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1212+ "endsWith" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12131213 return f .extractCondFmtText (c , extLst )
12141214 },
1215- "top10" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1215+ "top10" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12161216 return f .extractCondFmtTop10 (c , extLst )
12171217 },
1218- "aboveAverage" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1218+ "aboveAverage" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12191219 return f .extractCondFmtAboveAverage (c , extLst )
12201220 },
1221- "duplicateValues" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1221+ "duplicateValues" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12221222 return f .extractCondFmtDuplicateUniqueValues (c , extLst )
12231223 },
1224- "uniqueValues" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1224+ "uniqueValues" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12251225 return f .extractCondFmtDuplicateUniqueValues (c , extLst )
12261226 },
1227- "containsBlanks" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1227+ "containsBlanks" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12281228 return f .extractCondFmtBlanks (c , extLst )
12291229 },
1230- "notContainsBlanks" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1230+ "notContainsBlanks" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12311231 return f .extractCondFmtNoBlanks (c , extLst )
12321232 },
1233- "containsErrors" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1233+ "containsErrors" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12341234 return f .extractCondFmtErrors (c , extLst )
12351235 },
1236- "notContainsErrors" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1236+ "notContainsErrors" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12371237 return f .extractCondFmtNoErrors (c , extLst )
12381238 },
1239- "colorScale" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1239+ "colorScale" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12401240 return f .extractCondFmtColorScale (c , extLst )
12411241 },
1242- "dataBar" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1242+ "dataBar" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12431243 return f .extractCondFmtDataBar (c , extLst )
12441244 },
1245- "expression" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1245+ "expression" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12461246 return f .extractCondFmtExp (c , extLst )
12471247 },
1248- "iconSet" : func (f * File , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
1248+ "iconSet" : func (f * File , ref string , c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
12491249 return f .extractCondFmtIconSet (c , extLst )
12501250 },
12511251 }
@@ -2969,8 +2969,26 @@ func (f *File) extractCondFmtCellIs(c *xlsxCfRule, extLst *xlsxExtLst) Condition
29692969
29702970// extractCondFmtTimePeriod provides a function to extract conditional format
29712971// settings for time period by given conditional formatting rule.
2972- func (f * File ) extractCondFmtTimePeriod (c * xlsxCfRule , extLst * xlsxExtLst ) ConditionalFormatOptions {
2973- return ConditionalFormatOptions {Format : c .DxfID , StopIfTrue : c .StopIfTrue , Type : "time_period" , Criteria : operatorType [c .Operator ]}
2972+ func (f * File ) extractCondFmtTimePeriod (c * xlsxCfRule , ref string , extLst * xlsxExtLst ) ConditionalFormatOptions {
2973+ var critera string
2974+ for _ , formula := range c .Formula {
2975+ if c , ok := map [string ]string {
2976+ fmt .Sprintf ("FLOOR(%s,1)=TODAY()-1" , ref ): "yesterday" ,
2977+ fmt .Sprintf ("FLOOR(%s,1)=TODAY()" , ref ): "today" ,
2978+ fmt .Sprintf ("FLOOR(%s,1)=TODAY()+1" , ref ): "tomorrow" ,
2979+ fmt .Sprintf ("AND(TODAY()-FLOOR(%[1]s,1)<=6,FLOOR(%[1]s,1)<=TODAY())" , ref ): "last 7 days" ,
2980+ fmt .Sprintf ("AND(TODAY()-ROUNDDOWN(%[1]s,0)>=(WEEKDAY(TODAY())),TODAY()-ROUNDDOWN(%[1]s,0)<(WEEKDAY(TODAY())+7))" , ref ): "last week" ,
2981+ fmt .Sprintf ("AND(TODAY()-ROUNDDOWN(%[1]s,0)<=WEEKDAY(TODAY())-1,ROUNDDOWN(%[1]s,0)-TODAY()>=7-WEEKDAY(TODAY()))" , ref ): "this week" ,
2982+ fmt .Sprintf ("AND(ROUNDDOWN(%[1]s,0)-TODAY()>(7-WEEKDAY(TODAY())),ROUNDDOWN(%[1]s,0)-TODAY()<(15-WEEKDAY(TODAY())))" , ref ): "continue week" ,
2983+ 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 ): "last month" ,
2984+ fmt .Sprintf ("AND(MONTH(%[1]s)=MONTH(TODAY()),YEAR(%[1]s)=YEAR(TODAY()))" , ref ): "this month" ,
2985+ 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 ): "continue month" ,
2986+ }[formula ]; ok {
2987+ critera = c
2988+ break
2989+ }
2990+ }
2991+ return ConditionalFormatOptions {Format : c .DxfID , StopIfTrue : c .StopIfTrue , Type : "time_period" , Criteria : critera }
29742992}
29752993
29762994// extractCondFmtText provides a function to extract conditional format
@@ -3207,9 +3225,13 @@ func (f *File) GetConditionalFormats(sheet string) (map[string][]ConditionalForm
32073225 }
32083226 for _ , cf := range ws .ConditionalFormatting {
32093227 var opts []ConditionalFormatOptions
3228+ _ , mastCell , err := prepareConditionalFormatRange (cf .SQRef )
3229+ if err != nil {
3230+ return conditionalFormats , err
3231+ }
32103232 for _ , cr := range cf .CfRule {
32113233 if extractFunc , ok := extractContFmtFunc [cr .Type ]; ok {
3212- opts = append (opts , extractFunc (f , cr , ws .ExtLst ))
3234+ opts = append (opts , extractFunc (f , mastCell , cr , ws .ExtLst ))
32133235 }
32143236 }
32153237 conditionalFormats [cf .SQRef ] = opts
@@ -3246,9 +3268,17 @@ func (f *File) UnsetConditionalFormat(sheet, rangeRef string) error {
32463268 if err != nil {
32473269 return err
32483270 }
3249- for i , cf := range ws .ConditionalFormatting {
3250- if cf .SQRef == rangeRef {
3271+ delCells , err := flatSqref (rangeRef )
3272+ if err != nil {
3273+ return err
3274+ }
3275+ for i := 0 ; i < len (ws .ConditionalFormatting ); i ++ {
3276+ if ws .ConditionalFormatting [i ].SQRef , err = deleteCellsFromSqref (ws .ConditionalFormatting [i ].SQRef , delCells ); err != nil {
3277+ return err
3278+ }
3279+ if len (ws .ConditionalFormatting [i ].SQRef ) == 0 {
32513280 ws .ConditionalFormatting = append (ws .ConditionalFormatting [:i ], ws .ConditionalFormatting [i + 1 :]... )
3281+ i --
32523282 }
32533283 }
32543284 if ws .ExtLst != nil {
@@ -3263,7 +3293,9 @@ func (f *File) UnsetConditionalFormat(sheet, rangeRef string) error {
32633293 if ext .URI == ExtURIConditionalFormattings {
32643294 decodeCondFmts := new (decodeX14ConditionalFormattingRules )
32653295 _ = f .xmlNewDecoder (strings .NewReader (ext .Content )).Decode (decodeCondFmts )
3266- condFmtsBytes , _ = decodeCondFmts .deleteCfRule (rangeRef )
3296+ if condFmtsBytes , err = decodeCondFmts .deleteCfRule (delCells ); err != nil {
3297+ return err
3298+ }
32673299 decodeExtLst .Ext [idx ].Content = string (condFmtsBytes )
32683300 if len (decodeExtLst .Ext [idx ].Content ) == 57 { // empty x14:conditionalFormattings element
32693301 decodeExtLst .Ext = append (decodeExtLst .Ext [:idx ], decodeExtLst .Ext [idx + 1 :]... )
@@ -3287,10 +3319,16 @@ func (f *File) UnsetConditionalFormat(sheet, rangeRef string) error {
32873319// deleteCfRule provides a function to delete conditional formatting rule by
32883320// given range reference and return the updated x14:conditionalFormattings
32893321// element content.
3290- func (r * decodeX14ConditionalFormattingRules ) deleteCfRule (rangeRef string ) ([]byte , error ) {
3291- condFmts := & xlsxX14ConditionalFormattings {}
3322+ func (r * decodeX14ConditionalFormattingRules ) deleteCfRule (delCells map [int ][][]int ) ([]byte , error ) {
3323+ var (
3324+ err error
3325+ condFmts = & xlsxX14ConditionalFormattings {}
3326+ )
32923327 for _ , condFmt := range r .CondFmt {
3293- if condFmt .Sqref == rangeRef {
3328+ if condFmt .Sqref , err = deleteCellsFromSqref (condFmt .Sqref , delCells ); err != nil {
3329+ return nil , err
3330+ }
3331+ if len (condFmt .Sqref ) == 0 {
32943332 continue
32953333 }
32963334 x14ConditionalFormatting := xlsxX14ConditionalFormatting {
@@ -3403,7 +3441,6 @@ func drawCondFmtTimePeriod(p int, ct, ref, GUID string, format *ConditionalForma
34033441 Priority : p + 1 ,
34043442 StopIfTrue : format .StopIfTrue ,
34053443 Type : "timePeriod" ,
3406- Operator : ct ,
34073444 Formula : []string {
34083445 map [string ]string {
34093446 "yesterday" : fmt .Sprintf ("FLOOR(%s,1)=TODAY()-1" , ref ),
0 commit comments