diff --git a/excelize_test.go b/excelize_test.go index 6d47a72e751ce06298788a2c931d68e3fb56a837..1b23dca90ac360c3025dbadbf3d96df65ec70e5c 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -361,6 +361,37 @@ func TestSetCellStyleFill(t *testing.T) { } } +func TestSetCellStyleFont(t *testing.T) { + xlsx, err := OpenFile("./test/Workbook_2.xlsx") + if err != nil { + t.Log(err) + } + err = xlsx.SetCellStyle("Sheet2", "A1", "A1", `{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}`) + if err != nil { + t.Log(err) + } + err = xlsx.SetCellStyle("Sheet2", "A2", "A2", `{"font":{"italic":true,"underline":"double"}}`) + if err != nil { + t.Log(err) + } + err = xlsx.SetCellStyle("Sheet2", "A3", "A3", `{"font":{"bold":true}}`) + if err != nil { + t.Log(err) + } + err = xlsx.SetCellStyle("Sheet2", "A4", "A4", `{"font":{"bold":true,"family":"","size":0,"color":"","underline":""}}`) + if err != nil { + t.Log(err) + } + err = xlsx.SetCellStyle("Sheet2", "A5", "A5", `{"font":{"color":"#777777"}}`) + if err != nil { + t.Log(err) + } + err = xlsx.Save() + if err != nil { + t.Log(err) + } +} + func TestSetDeleteSheet(t *testing.T) { xlsx, err := OpenFile("./test/Workbook_3.xlsx") if err != nil { diff --git a/rows.go b/rows.go index b753fcd539ff53218cd23098c2c16ff6cbfd69e1..7e5ae5e409737e905964c788c12b208be6c74b7d 100644 --- a/rows.go +++ b/rows.go @@ -6,7 +6,11 @@ import ( "strings" ) -// GetRows return all the rows in a sheet by given "sheet" + index, for example: +// GetRows return all the rows in a sheet by given "sheet" + index. For now you +// should use sheet_name like "sheet3" where "sheet" is a constant part and "3" +// is a sheet number. For example, if sheet named as "SomeUniqueData" and it is +// second if spreadsheet program interface - you should use "sheet2" here. For +// example: // // index := xlsx.GetSheetIndex("Sheet2") // rows := xlsx.GetRows("sheet" + strconv.Itoa(index)) diff --git a/styles.go b/styles.go index 96f041fd42b0ee31a9979e53c7abcacbc8ae1009..46b7a03e3e9c26645921d7fa281d8e1c221b6b1e 100644 --- a/styles.go +++ b/styles.go @@ -97,6 +97,13 @@ func parseFormatStyleSet(style string) (*formatCellStyle, error) { // fmt.Println(err) // } // +// Set font style for cell H9 on Sheet1: +// +// err = xlsx.SetCellStyle("Sheet1", "H9", "H9", `{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777"}}`) +// if err != nil { +// fmt.Println(err) +// } +// // The following shows the border styles sorted by excelize index number: // // +-------+---------------+--------+-----------------+ @@ -223,6 +230,16 @@ func parseFormatStyleSet(style string) (*formatCellStyle, error) { // | distributed | // +------------------+ // +// The following the type of font underline style: +// +// +------------------+ +// | Style | +// +==================+ +// | single | +// +------------------+ +// | double | +// +------------------+ +// // Excel's built-in formats are shown in the following table: // // +-------+----------------------------------------------------+ @@ -311,10 +328,11 @@ func (f *File) SetCellStyle(sheet, hcell, vcell, style string) error { return err } numFmtID := setNumFmt(&styleSheet, formatCellStyle) + fontID := setFont(&styleSheet, formatCellStyle) borderID := setBorders(&styleSheet, formatCellStyle) fillID := setFills(&styleSheet, formatCellStyle) applyAlignment, alignment := setAlignment(&styleSheet, formatCellStyle) - cellXfsID := setCellXfs(&styleSheet, numFmtID, fillID, borderID, applyAlignment, alignment) + cellXfsID := setCellXfs(&styleSheet, fontID, numFmtID, fillID, borderID, applyAlignment, alignment) output, err := xml.Marshal(styleSheet) if err != nil { return err @@ -324,6 +342,42 @@ func (f *File) SetCellStyle(sheet, hcell, vcell, style string) error { return err } +// setFont provides function to add font style by given cell format settings. +func setFont(style *xlsxStyleSheet, formatCellStyle *formatCellStyle) int { + if formatCellStyle.Font == nil { + return 0 + } + fontUnderlineType := map[string]string{"single": "single", "double": "double"} + if formatCellStyle.Font.Family == "" { + formatCellStyle.Font.Family = "Calibri" + } + if formatCellStyle.Font.Size < 1 { + formatCellStyle.Font.Size = 11 + } + if formatCellStyle.Font.Color == "" { + formatCellStyle.Font.Color = "#000000" + } + f := font{ + B: formatCellStyle.Font.Bold, + I: formatCellStyle.Font.Italic, + Sz: &attrValInt{Val: formatCellStyle.Font.Size}, + Color: &xlsxColor{RGB: getPaletteColor(formatCellStyle.Font.Color)}, + Name: &attrValString{Val: formatCellStyle.Font.Family}, + Family: &attrValInt{Val: 2}, + Scheme: &attrValString{Val: "minor"}, + } + val, ok := fontUnderlineType[formatCellStyle.Font.Underline] + if ok { + f.U = &attrValString{Val: val} + } + font, _ := xml.Marshal(f) + style.Fonts.Count++ + style.Fonts.Font = append(style.Fonts.Font, &xlsxFont{ + Font: string(font[6 : len(font)-7]), + }) + return style.Fonts.Count - 1 +} + // setNumFmt provides function to check if number format code in the range of // built-in values. func setNumFmt(style *xlsxStyleSheet, formatCellStyle *formatCellStyle) int { @@ -491,8 +545,12 @@ func setBorders(style *xlsxStyleSheet, formatCellStyle *formatCellStyle) int { // setCellXfs provides function to set describes all of the formatting for a // cell. -func setCellXfs(style *xlsxStyleSheet, numFmtID, fillID, borderID int, applyAlignment bool, alignment *xlsxAlignment) int { +func setCellXfs(style *xlsxStyleSheet, fontID, numFmtID, fillID, borderID int, applyAlignment bool, alignment *xlsxAlignment) int { var xf xlsxXf + xf.FontID = fontID + if fontID != 0 { + xf.ApplyFont = true + } xf.NumFmtID = numFmtID if numFmtID != 0 { xf.ApplyNumberFormat = true diff --git a/templates.go b/templates.go index 81b531ec5d6397e04a401842cf918684895e1b2e..0c6d3b3886c5136201b1a91dd9e5870d3f7a7f57 100644 --- a/templates.go +++ b/templates.go @@ -22,4 +22,4 @@ const templateDocpropsCore = `` -const templateTheme = `` +const templateTheme = `` diff --git a/xmlStyles.go b/xmlStyles.go index 14b5e4bbe83a0e86ee2fb5a112c427dcd233039d..682c5d333ab8fa231097c10ce2850533dbc2ef42 100644 --- a/xmlStyles.go +++ b/xmlStyles.go @@ -57,11 +57,23 @@ type xlsxColor struct { Tint float64 `xml:"tint,attr,omitempty"` } -// xlsxFonts directly maps the fonts element. This element contains all font +// xlsxFonts directly maps the font element. This element contains all font // definitions for this workbook. type xlsxFonts struct { Count int `xml:"count,attr"` - Font []*xlsxFont `xml:"font,omitempty"` + Font []*xlsxFont `xml:"font"` +} + +// font directly maps the font element. +type font struct { + B bool `xml:"b,omitempty"` + I bool `xml:"i,omitempty"` + U *attrValString `xml:"u"` + Sz *attrValInt `xml:"sz"` + Color *xlsxColor `xml:"color"` + Name *attrValString `xml:"name"` + Family *attrValInt `xml:"family"` + Scheme *attrValString `xml:"scheme"` } // xlsxFont directly maps the font element. This element defines the properties @@ -283,6 +295,14 @@ type formatCellStyle struct { Color []string `json:"color"` Shading int `json:"shading"` } `json:"fill"` + Font *struct { + Bold bool `json:"bold"` + Italic bool `json:"italic"` + Underline string `json:"underline"` + Family string `json:"family"` + Size int `json:"size"` + Color string `json:"color"` + } `json:"font"` Alignment *struct { Horizontal string `json:"horizontal"` Indent int `json:"indent"`