大家好,這里是符華~
查看前三篇:
【Go】excelize庫實現excel導入導出封裝(一),自定義導出樣式、隔行背景色、自適應行高、動態導出指定列、動態更改表頭
【Go】excelize庫實現excel導入導出封裝(二),基于map、多個sheet、多級表頭、樹形結構表頭導出,橫向、縱向合并單元格導出
【Go】excelize庫實現excel導入導出封裝(三),基于excel模板導出excel
背景
前兩篇文章中,導出時的樣式都有設置統一的基礎樣式的。但是有些時候,我們需要對特定的某一列或某幾列設置單獨的樣式。比如某一列單元格的值都是數值類型,我們需要讓這一列右對齊,其它列不變(基礎樣式是居中對齊);又或者是把某一列文字標紅或背景色填充為紅色,其它列不變(保持基礎樣式)。
這篇文章就是來實現:在基礎樣式的基礎上,對特定的列設置單獨的自定義樣式,且這些特定的列每列都可以設置單獨的樣式。
實現
修改 tag
因為我們是對一整列設置樣式,因此我們可以直接將自定義的樣式,放在需要設置樣式的那個字段的tag里面。
如下圖:
我們解析excel這個tag的時候,是通過正則表達式來解析的,因此在之前的正則表達式基礎上,需要再加上style的解析:
同時對應的tag結構體,也需要再加上Style屬性:
然后根據正則表達式解析tag值時,將解析到的style值設置到tag結構體的Style屬性中:
設置
tag和tag解析部分修改完后,我們需要考慮下在tag里面添加樣式的時候,我們應該按什么格式來設置,到后面解析這些樣式的時候更方便。
然后我目前想到的設置格式是這樣的:
樣式類名和樣式名,對應excelize庫下的xmlStyles.go里面的Style結構體里的屬性名:
樣式類名是必須的,這樣方便我們判斷這個樣式是屬于哪個樣式類(對應的結構體)的,然后將Alignment{Horizontal:left},Font{Color:#ff0000,Size:16.0,Family:黑體},Fill{Color:#f9cb9c,Type:pattern,Pattern:1}
這一段字符串根據樣式類名分隔,分隔后處理成 json 字符串,再轉成對應的樣式類結構體。
代碼如下:
// customStyle就是 Alignment{Horizontal:left},Font{Color:#ff0000,Size:16.0,Family:黑體},Fill{Color:#f9cb9c,Type:pattern,Pattern:1} 這一串字符
// 設置自定義樣式:customStyle 定義的樣式、 baseStyle 基礎樣式
func (e *Excel) SetCustomCellStyle(customStyle string, baseStyle int) int {style, _ := e.F.GetStyle(baseStyle)if style == nil {style = &excelize.Style{}}patt := ".*?{.*?}" // 使用正則解析每一個樣式類和它的大括號里面包含的樣式re := regexp.MustCompile(patt)matches := re.FindAllStringSubmatch(customStyle, -1)for i := range matches {s := matches[i][0]if strings.HasPrefix(s, ",") {s = strings.TrimPrefix(s, ",")}s = strings.ReplaceAll(s, "{", "")s = strings.ReplaceAll(s, "}", "")if strings.HasPrefix(s, "Alignment") { // 對齊樣式result := stringBuilder("Alignment", s) // 處理成json字符串json.Unmarshal([]byte(result), &style.Alignment) // 將json字符串轉成對應的結構體} else if strings.HasPrefix(s, "Font") { // 字體樣式result := stringBuilder("Font", s)json.Unmarshal([]byte(result), &style.Font)} else if strings.HasPrefix(s, "Fill") { // 背景填充樣式result := stringBuilder("Fill", s)json.Unmarshal([]byte(result), &style.Fill)}}i, _ := e.F.NewStyle(style)return i
}// 字符串處理拼接(處理成結構體json字符串)replaceStr 需要替換的字符
func stringBuilder(replaceStr, str string) string {var builder strings.Builderbuilder.WriteString("{")str = strings.ReplaceAll(str, replaceStr, "")split := strings.Split(str, ",")for v := range split {split1 := strings.Split(split[v], ":")if v > 0 {builder.WriteString(",")}builder.WriteString("\"")builder.WriteString(split1[0])builder.WriteString("\"")// 如果是數值或bool類型,不需要拼接引號if IsNumeric(split1[1]) || IsBool(split1[1]) {builder.WriteString(":")builder.WriteString(split1[1])} else {// 因為Fill下面的Color屬性是字符串數組的,因此需要拼接中括號if replaceStr == "Fill" && split1[0] == "Color" {builder.WriteString(":[\"")builder.WriteString(split1[1])builder.WriteString("\"]")} else {// 字符串需要拼接引號builder.WriteString(":\"")builder.WriteString(split1[1])builder.WriteString("\"")}}}builder.WriteString("}")return builder.String()
}// 是否是數字:包含正負整數和正負小數
func IsNumeric(s string) bool {// 正則表達式匹配整數和小數b, _ := regexp.MatchString(`^-?\d+(\.\d+)?$`, s)return b
}// 是否是bool值
func IsBool(s string) bool {return strings.EqualFold(s, "true") || strings.EqualFold(s, "false")
}
樣式解析并且設置完成后,在導出excel時,將在tag里設置了的樣式,應用到對應的列中。因此我們還需要對構建數據行的代碼進行修改:
測試
效果圖:
最后
完整代碼:點這里
ok以上就是今天的全部內容了,大家看完順便給我點個Star、加關注唄~🥰🥳