已验证 提交 c63ae6d2 编写于 作者: xurime's avatar xurime

This fixed #1610, support to create a conditional format with number format and protection

上级 a1810aa0
......@@ -1032,6 +1032,7 @@ func (f *File) NewStyle(style *Style) (int, error) {
return setCellXfs(s, fontID, numFmtID, fillID, borderID, applyAlignment, applyProtection, alignment, protection)
}
// getXfIDFuncs provides a function to get xfID by given style.
var getXfIDFuncs = map[string]func(int, xlsxXf, *Style) bool{
"numFmt": func(numFmtID int, xf xlsxXf, style *Style) bool {
if style.CustomNumFmt == nil && numFmtID == -1 {
......@@ -1121,7 +1122,10 @@ func (f *File) NewConditionalStyle(style *Style) (int, error) {
if err != nil {
return 0, err
}
dxf := dxf{
if fs.DecimalPlaces != nil && (*fs.DecimalPlaces < 0 || *fs.DecimalPlaces > 30) {
fs.DecimalPlaces = intPtr(2)
}
dxf := xlsxDxf{
Fill: newFills(fs, false),
}
if fs.Alignment != nil {
......@@ -1133,17 +1137,55 @@ func (f *File) NewConditionalStyle(style *Style) (int, error) {
if fs.Font != nil {
dxf.Font, _ = f.newFont(fs)
}
dxfStr, _ := xml.Marshal(dxf)
if fs.Protection != nil {
dxf.Protection = newProtection(fs)
}
dxf.NumFmt = newDxfNumFmt(s, style, &dxf)
if s.Dxfs == nil {
s.Dxfs = &xlsxDxfs{}
}
s.Dxfs.Count++
s.Dxfs.Dxfs = append(s.Dxfs.Dxfs, &xlsxDxf{
Dxf: string(dxfStr[5 : len(dxfStr)-6]),
})
s.Dxfs.Dxfs = append(s.Dxfs.Dxfs, &dxf)
return s.Dxfs.Count - 1, nil
}
// newDxfNumFmt provides a function to create number format for conditional
// format styles.
func newDxfNumFmt(styleSheet *xlsxStyleSheet, style *Style, dxf *xlsxDxf) *xlsxNumFmt {
dp, numFmtID := "0", 164 // Default custom number format code from 164.
if style.DecimalPlaces != nil && *style.DecimalPlaces > 0 {
dp += "."
for i := 0; i < *style.DecimalPlaces; i++ {
dp += "0"
}
}
if style.CustomNumFmt != nil {
if styleSheet.Dxfs != nil {
for _, d := range styleSheet.Dxfs.Dxfs {
if d != nil && d.NumFmt != nil && d.NumFmt.NumFmtID > numFmtID {
numFmtID = d.NumFmt.NumFmtID
}
}
}
return &xlsxNumFmt{NumFmtID: numFmtID + 1, FormatCode: *style.CustomNumFmt}
}
numFmtCode, ok := builtInNumFmt[style.NumFmt]
if style.NumFmt > 0 && ok {
return &xlsxNumFmt{NumFmtID: style.NumFmt, FormatCode: numFmtCode}
}
fc, currency := currencyNumFmt[style.NumFmt]
if !currency {
return nil
}
if style.DecimalPlaces != nil {
fc = strings.ReplaceAll(fc, "0.00", dp)
}
if style.NegRed {
fc = fc + ";[Red]" + fc
}
return &xlsxNumFmt{NumFmtID: numFmtID, FormatCode: fc}
}
// GetDefaultFont provides the default font name currently set in the
// workbook. The spreadsheet generated by excelize default font is Calibri.
func (f *File) GetDefaultFont() (string, error) {
......
......@@ -355,10 +355,26 @@ func TestNewStyle(t *testing.T) {
func TestNewConditionalStyle(t *testing.T) {
f := NewFile()
_, err := f.NewConditionalStyle(&Style{Protection: &Protection{Hidden: true, Locked: true}})
assert.NoError(t, err)
_, err = f.NewConditionalStyle(&Style{DecimalPlaces: intPtr(4), NumFmt: 165, NegRed: true})
assert.NoError(t, err)
_, err = f.NewConditionalStyle(&Style{DecimalPlaces: intPtr(-1)})
assert.NoError(t, err)
_, err = f.NewConditionalStyle(&Style{NumFmt: 1})
assert.NoError(t, err)
_, err = f.NewConditionalStyle(&Style{NumFmt: 27})
assert.NoError(t, err)
numFmt := "general"
_, err = f.NewConditionalStyle(&Style{CustomNumFmt: &numFmt})
assert.NoError(t, err)
numFmt1 := "0.00"
_, err = f.NewConditionalStyle(&Style{CustomNumFmt: &numFmt1})
assert.NoError(t, err)
// Test create conditional style with unsupported charset style sheet
f.Styles = nil
f.Pkg.Store(defaultXMLPathStyles, MacintoshCyrillicCharset)
_, err := f.NewConditionalStyle(&Style{Font: &Font{Color: "9A0511"}, Fill: Fill{Type: "pattern", Color: []string{"FEC7CE"}, Pattern: 1}})
_, err = f.NewConditionalStyle(&Style{Font: &Font{Color: "9A0511"}, Fill: Fill{Type: "pattern", Color: []string{"FEC7CE"}, Pattern: 1}})
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
}
......
......@@ -251,11 +251,6 @@ type xlsxDxfs struct {
// xlsxDxf directly maps the dxf element. A single dxf record, expressing
// incremental formatting to be applied.
type xlsxDxf struct {
Dxf string `xml:",innerxml"`
}
// dxf directly maps the dxf element.
type dxf struct {
Font *xlsxFont `xml:"font"`
NumFmt *xlsxNumFmt `xml:"numFmt"`
Fill *xlsxFill `xml:"fill"`
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册