From bd5dd17673f767b9f4643423c77eec486f2ad53f Mon Sep 17 00:00:00 2001
From: xuri <xuri.me@gmail.com>
Date: Sat, 12 Nov 2022 00:02:11 +0800
Subject: This is a breaking change, remove partial internal error log print,
 throw XML deserialize error

- Add error return value for the `GetComments`, `GetDefaultFont` and `SetDefaultFont` functions
- Update unit tests
---
 styles.go | 112 +++++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 75 insertions(+), 37 deletions(-)

(limited to 'styles.go')

diff --git a/styles.go b/styles.go
index f7d00e1..08d6b0c 100644
--- a/styles.go
+++ b/styles.go
@@ -1037,15 +1037,15 @@ func formatToE(v, format string, date1904 bool) string {
 
 // stylesReader provides a function to get the pointer to the structure after
 // deserialization of xl/styles.xml.
-func (f *File) stylesReader() *xlsxStyleSheet {
+func (f *File) stylesReader() (*xlsxStyleSheet, error) {
 	if f.Styles == nil {
 		f.Styles = new(xlsxStyleSheet)
 		if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathStyles)))).
 			Decode(f.Styles); err != nil && err != io.EOF {
-			log.Printf("xml decode error: %s", err)
+			return f.Styles, err
 		}
 	}
-	return f.Styles
+	return f.Styles, nil
 }
 
 // styleSheetWriter provides a function to save xl/styles.xml after serialize
@@ -1965,9 +1965,12 @@ func parseFormatStyleSet(style interface{}) (*Style, error) {
 //
 // Cell Sheet1!A6 in the Excel Application: martes, 04 de Julio de 2017
 func (f *File) NewStyle(style interface{}) (int, error) {
-	var fs *Style
-	var err error
-	var cellXfsID, fontID, borderID, fillID int
+	var (
+		fs                                  *Style
+		font                                *xlsxFont
+		err                                 error
+		cellXfsID, fontID, borderID, fillID int
+	)
 	fs, err = parseFormatStyleSet(style)
 	if err != nil {
 		return cellXfsID, err
@@ -1975,21 +1978,25 @@ func (f *File) NewStyle(style interface{}) (int, error) {
 	if fs.DecimalPlaces == 0 {
 		fs.DecimalPlaces = 2
 	}
-	s := f.stylesReader()
+	s, err := f.stylesReader()
+	if err != nil {
+		return cellXfsID, err
+	}
 	s.Lock()
 	defer s.Unlock()
 	// check given style already exist.
-	if cellXfsID = f.getStyleID(s, fs); cellXfsID != -1 {
+	if cellXfsID, err = f.getStyleID(s, fs); err != nil || cellXfsID != -1 {
 		return cellXfsID, err
 	}
 
 	numFmtID := newNumFmt(s, fs)
 
 	if fs.Font != nil {
-		fontID = f.getFontID(s, fs)
+		fontID, _ = f.getFontID(s, fs)
 		if fontID == -1 {
 			s.Fonts.Count++
-			s.Fonts.Font = append(s.Fonts.Font, f.newFont(fs))
+			font, _ = f.newFont(fs)
+			s.Fonts.Font = append(s.Fonts.Font, font)
 			fontID = s.Fonts.Count - 1
 		}
 	}
@@ -2065,12 +2072,19 @@ var getXfIDFuncs = map[string]func(int, xlsxXf, *Style) bool{
 
 // getStyleID provides a function to get styleID by given style. If given
 // style does not exist, will return -1.
-func (f *File) getStyleID(ss *xlsxStyleSheet, style *Style) (styleID int) {
-	styleID = -1
+func (f *File) getStyleID(ss *xlsxStyleSheet, style *Style) (int, error) {
+	var (
+		err     error
+		fontID  int
+		styleID = -1
+	)
 	if ss.CellXfs == nil {
-		return
+		return styleID, err
+	}
+	numFmtID, borderID, fillID := getNumFmtID(ss, style), getBorderID(ss, style), getFillID(ss, style)
+	if fontID, err = f.getFontID(ss, style); err != nil {
+		return styleID, err
 	}
-	numFmtID, borderID, fillID, fontID := getNumFmtID(ss, style), getBorderID(ss, style), getFillID(ss, style), f.getFontID(ss, style)
 	if style.CustomNumFmt != nil {
 		numFmtID = getCustomNumFmtID(ss, style)
 	}
@@ -2082,10 +2096,10 @@ func (f *File) getStyleID(ss *xlsxStyleSheet, style *Style) (styleID int) {
 			getXfIDFuncs["alignment"](0, xf, style) &&
 			getXfIDFuncs["protection"](0, xf, style) {
 			styleID = xfID
-			return
+			return styleID, err
 		}
 	}
-	return
+	return styleID, err
 }
 
 // NewConditionalStyle provides a function to create style for conditional
@@ -2093,7 +2107,10 @@ func (f *File) getStyleID(ss *xlsxStyleSheet, style *Style) (styleID int) {
 // function. Note that the color field uses RGB color code and only support to
 // set font, fills, alignment and borders currently.
 func (f *File) NewConditionalStyle(style string) (int, error) {
-	s := f.stylesReader()
+	s, err := f.stylesReader()
+	if err != nil {
+		return 0, err
+	}
 	fs, err := parseFormatStyleSet(style)
 	if err != nil {
 		return 0, err
@@ -2108,7 +2125,7 @@ func (f *File) NewConditionalStyle(style string) (int, error) {
 		dxf.Border = newBorders(fs)
 	}
 	if fs.Font != nil {
-		dxf.Font = f.newFont(fs)
+		dxf.Font, _ = f.newFont(fs)
 	}
 	dxfStr, _ := xml.Marshal(dxf)
 	if s.Dxfs == nil {
@@ -2123,41 +2140,56 @@ func (f *File) NewConditionalStyle(style string) (int, error) {
 
 // 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 {
-	font := f.readDefaultFont()
-	return *font.Name.Val
+func (f *File) GetDefaultFont() (string, error) {
+	font, err := f.readDefaultFont()
+	if err != nil {
+		return "", err
+	}
+	return *font.Name.Val, err
 }
 
 // SetDefaultFont changes the default font in the workbook.
-func (f *File) SetDefaultFont(fontName string) {
-	font := f.readDefaultFont()
+func (f *File) SetDefaultFont(fontName string) error {
+	font, err := f.readDefaultFont()
+	if err != nil {
+		return err
+	}
 	font.Name.Val = stringPtr(fontName)
-	s := f.stylesReader()
+	s, _ := f.stylesReader()
 	s.Fonts.Font[0] = font
 	custom := true
 	s.CellStyles.CellStyle[0].CustomBuiltIn = &custom
+	return err
 }
 
 // readDefaultFont provides an un-marshalled font value.
-func (f *File) readDefaultFont() *xlsxFont {
-	s := f.stylesReader()
-	return s.Fonts.Font[0]
+func (f *File) readDefaultFont() (*xlsxFont, error) {
+	s, err := f.stylesReader()
+	if err != nil {
+		return nil, err
+	}
+	return s.Fonts.Font[0], err
 }
 
 // getFontID provides a function to get font ID.
 // If given font does not exist, will return -1.
-func (f *File) getFontID(styleSheet *xlsxStyleSheet, style *Style) (fontID int) {
-	fontID = -1
+func (f *File) getFontID(styleSheet *xlsxStyleSheet, style *Style) (int, error) {
+	var err error
+	fontID := -1
 	if styleSheet.Fonts == nil || style.Font == nil {
-		return
+		return fontID, err
 	}
 	for idx, fnt := range styleSheet.Fonts.Font {
-		if reflect.DeepEqual(*fnt, *f.newFont(style)) {
+		font, err := f.newFont(style)
+		if err != nil {
+			return fontID, err
+		}
+		if reflect.DeepEqual(*fnt, *font) {
 			fontID = idx
-			return
+			return fontID, err
 		}
 	}
-	return
+	return fontID, err
 }
 
 // newFontColor set font color by given styles.
@@ -2190,7 +2222,8 @@ func newFontColor(font *Font) *xlsxColor {
 
 // newFont provides a function to add font style by given cell format
 // settings.
-func (f *File) newFont(style *Style) *xlsxFont {
+func (f *File) newFont(style *Style) (*xlsxFont, error) {
+	var err error
 	if style.Font.Size < MinFontSize {
 		style.Font.Size = 11
 	}
@@ -2207,7 +2240,9 @@ func (f *File) newFont(style *Style) *xlsxFont {
 		fnt.I = &attrValBool{Val: &style.Font.Italic}
 	}
 	if *fnt.Name.Val == "" {
-		*fnt.Name.Val = f.GetDefaultFont()
+		if *fnt.Name.Val, err = f.GetDefaultFont(); err != nil {
+			return &fnt, err
+		}
 	}
 	if style.Font.Strike {
 		fnt.Strike = &attrValBool{Val: &style.Font.Strike}
@@ -2215,7 +2250,7 @@ func (f *File) newFont(style *Style) *xlsxFont {
 	if idx := inStrSlice(supportedUnderlineTypes, style.Font.Underline, true); idx != -1 {
 		fnt.U = &attrValString{Val: stringPtr(supportedUnderlineTypes[idx])}
 	}
-	return &fnt
+	return &fnt, err
 }
 
 // getNumFmtID provides a function to get number format code ID.
@@ -2754,7 +2789,10 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
 	ws.Lock()
 	defer ws.Unlock()
 
-	s := f.stylesReader()
+	s, err := f.stylesReader()
+	if err != nil {
+		return err
+	}
 	s.Lock()
 	defer s.Unlock()
 	if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
-- 
cgit v1.2.1