未验证 提交 4eb34866 编写于 作者: 3 327674413 提交者: GitHub

This closes #1783, support set conditional formatting with multiple cell ranges (#1787)

上级 50e23df8
......@@ -471,12 +471,12 @@ func (af *arrayFormulaOperandToken) setCoordinates() error {
}
var c, r int
if col {
if cellRef.Row = TotalRows; i == 1 {
if cellRef.Row = TotalRows; i == 0 {
cellRef.Row = 1
}
}
if row {
if cellRef.Col = MaxColumns; i == 1 {
if cellRef.Col = MaxColumns; i == 0 {
cellRef.Col = 1
}
}
......
......@@ -2760,13 +2760,9 @@ func (f *File) SetConditionalFormat(sheet, rangeRef string, opts []ConditionalFo
if err != nil {
return err
}
if strings.Contains(rangeRef, ":") {
rect, err := rangeRefToCoordinates(rangeRef)
if err != nil {
return err
}
_ = sortCoordinates(rect)
rangeRef, _ = f.coordinatesToRangeRef(rect, strings.Contains(rangeRef, "$"))
SQRef, mastCell, err := prepareConditionalFormatRange(rangeRef)
if err != nil {
return err
}
// Create a pseudo GUID for each unique rule.
var rules int
......@@ -2796,7 +2792,7 @@ func (f *File) SetConditionalFormat(sheet, rangeRef string, opts []ConditionalFo
drawFunc, ok := drawContFmtFunc[vt]
if ok {
priority := rules + i
rule, x14rule := drawFunc(priority, ct, strings.Split(rangeRef, ":")[0],
rule, x14rule := drawFunc(priority, ct, mastCell,
fmt.Sprintf("{00000000-0000-0000-%04X-%012X}", f.getSheetID(sheet), priority), &opt)
if rule == nil {
return ErrParameterInvalid
......@@ -2817,12 +2813,53 @@ func (f *File) SetConditionalFormat(sheet, rangeRef string, opts []ConditionalFo
}
ws.ConditionalFormatting = append(ws.ConditionalFormatting, &xlsxConditionalFormatting{
SQRef: rangeRef,
SQRef: SQRef,
CfRule: cfRule,
})
return err
}
// prepareConditionalFormatRange returns checked cell range and master cell
// reference by giving conditional formatting range reference.
func prepareConditionalFormatRange(rangeRef string) (string, string, error) {
var SQRef, mastCell string
if rangeRef == "" {
return SQRef, mastCell, ErrParameterRequired
}
rangeRef = strings.ReplaceAll(rangeRef, ",", " ")
for i, cellRange := range strings.Split(rangeRef, " ") {
var cellNames []string
for j, ref := range strings.Split(cellRange, ":") {
if j > 1 {
return SQRef, mastCell, ErrParameterInvalid
}
cellRef, col, row, err := parseRef(ref)
if err != nil {
return SQRef, mastCell, err
}
var c, r int
if col {
if cellRef.Row = TotalRows; j == 0 {
cellRef.Row = 1
}
}
if row {
if cellRef.Col = MaxColumns; j == 0 {
cellRef.Col = 1
}
}
c, r = cellRef.Col, cellRef.Row
cellName, _ := CoordinatesToCellName(c, r)
cellNames = append(cellNames, cellName)
if i == 0 && j == 0 {
mastCell = cellName
}
}
SQRef += strings.Join(cellNames, ":") + " "
}
return strings.TrimSuffix(SQRef, " "), mastCell, nil
}
// appendCfRule provides a function to append rules to conditional formatting.
func (f *File) appendCfRule(ws *xlsxWorksheet, rule *xlsxX14CfRule) error {
var (
......
......@@ -178,6 +178,10 @@ func TestSetConditionalFormat(t *testing.T) {
assert.NoError(t, f.SetConditionalFormat("Sheet1", ref, condFmts))
}
f = NewFile()
// Test creating a conditional format without cell reference
assert.Equal(t, ErrParameterRequired, f.SetConditionalFormat("Sheet1", "", nil))
// Test creating a conditional format with invalid cell reference
assert.Equal(t, ErrParameterInvalid, f.SetConditionalFormat("Sheet1", "A1:A2:A3", nil))
// Test creating a conditional format with existing extension lists
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
assert.True(t, ok)
......@@ -272,11 +276,11 @@ func TestGetConditionalFormats(t *testing.T) {
{{Type: "icon_set", IconStyle: "3Arrows", ReverseIcons: true, IconsOnly: true}},
} {
f := NewFile()
err := f.SetConditionalFormat("Sheet1", "A2:A1", format)
err := f.SetConditionalFormat("Sheet1", "A2:A1,B:B,2:2", format)
assert.NoError(t, err)
opts, err := f.GetConditionalFormats("Sheet1")
assert.NoError(t, err)
assert.Equal(t, format, opts["A1:A2"])
assert.Equal(t, format, opts["A2:A1 B1:B1048576 A2:XFD2"])
}
// Test get multiple conditional formats
f := NewFile()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册