Prechádzať zdrojové kódy

Correctly setup named styles.

Previously the relationship assumed that there was a cellStyleXfs.Xf at
the same index as the cellXf.Xf - however really we only use a
cellStyleXf.Xf when the cellXf.Xf has an XfId (which points to the
cellStyleXf.Xf index).  Reflect this when reading from file, and
output when marshaling.
Geoffrey J. Teale 10 rokov pred
rodič
commit
715e7540fc
3 zmenil súbory, kde vykonal 70 pridanie a 24 odobranie
  1. 9 8
      style.go
  2. 41 16
      xmlStyle.go
  3. 20 0
      xmlStyle_test.go

+ 9 - 8
style.go

@@ -5,14 +5,15 @@ import "strconv"
 // Style is a high level structure intended to provide user access to
 // Style is a high level structure intended to provide user access to
 // the contents of Style within an XLSX file.
 // the contents of Style within an XLSX file.
 type Style struct {
 type Style struct {
-	Border         Border
-	Fill           Fill
-	Font           Font
-	ApplyBorder    bool
-	ApplyFill      bool
-	ApplyFont      bool
-	ApplyAlignment bool
-	Alignment      Alignment
+	Border          Border
+	Fill            Fill
+	Font            Font
+	ApplyBorder     bool
+	ApplyFill       bool
+	ApplyFont       bool
+	ApplyAlignment  bool
+	Alignment       Alignment
+	NamedStyleIndex *int
 }
 }
 
 
 // Return a new Style structure initialised with the default values.
 // Return a new Style structure initialised with the default values.

+ 41 - 16
xmlStyle.go

@@ -116,7 +116,7 @@ func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style *Style) {
 	if ok {
 	if ok {
 		return
 		return
 	}
 	}
-	var styleXf xlsxXf
+	var namedStyleXf xlsxXf
 	style = &Style{}
 	style = &Style{}
 	style.Border = Border{}
 	style.Border = Border{}
 	style.Fill = Fill{}
 	style.Fill = Fill{}
@@ -126,18 +126,17 @@ func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style *Style) {
 	if styleIndex > -1 && xfCount > 0 && styleIndex <= xfCount {
 	if styleIndex > -1 && xfCount > 0 && styleIndex <= xfCount {
 		xf := styles.CellXfs.Xf[styleIndex]
 		xf := styles.CellXfs.Xf[styleIndex]
 
 
-		// Google docs can produce output that has fewer
-		// CellStyleXfs than CellXfs - this copes with that.
-		if styleIndex < styles.CellStyleXfs.Count {
-			styleXf = styles.CellStyleXfs.Xf[styleIndex]
+		if xf.XfId != nil {
+			namedStyleXf = styles.CellStyleXfs.Xf[*xf.XfId]
+			style.NamedStyleIndex = xf.XfId
 		} else {
 		} else {
-			styleXf = xlsxXf{}
+			namedStyleXf = xlsxXf{}
 		}
 		}
 
 
-		style.ApplyBorder = xf.ApplyBorder || styleXf.ApplyBorder
-		style.ApplyFill = xf.ApplyFill || styleXf.ApplyFill
-		style.ApplyFont = xf.ApplyFont || styleXf.ApplyFont
-		style.ApplyAlignment = xf.ApplyAlignment || styleXf.ApplyAlignment
+		style.ApplyBorder = xf.ApplyBorder || namedStyleXf.ApplyBorder
+		style.ApplyFill = xf.ApplyFill || namedStyleXf.ApplyFill
+		style.ApplyFont = xf.ApplyFont || namedStyleXf.ApplyFont
+		style.ApplyAlignment = xf.ApplyAlignment || namedStyleXf.ApplyAlignment
 
 
 		if xf.BorderId > -1 && xf.BorderId < styles.Borders.Count {
 		if xf.BorderId > -1 && xf.BorderId < styles.Borders.Count {
 			var border xlsxBorder
 			var border xlsxBorder
@@ -356,6 +355,7 @@ func (styles *xlsxStyleSheet) Marshal() (result string, err error) {
 	var xborders string
 	var xborders string
 	var xcellStyleXfs string
 	var xcellStyleXfs string
 	var xcellXfs string
 	var xcellXfs string
+	var xcellStyles string
 
 
 	var outputFontMap map[int]int = make(map[int]int)
 	var outputFontMap map[int]int = make(map[int]int)
 	var outputFillMap map[int]int = make(map[int]int)
 	var outputFillMap map[int]int = make(map[int]int)
@@ -400,6 +400,12 @@ func (styles *xlsxStyleSheet) Marshal() (result string, err error) {
 	}
 	}
 	result += xcellXfs
 	result += xcellXfs
 
 
+	xcellStyles, err = styles.CellStyles.Marshal()
+	if err != nil {
+		return
+	}
+	result += xcellStyles
+
 	result += `</styleSheet>`
 	result += `</styleSheet>`
 	return
 	return
 }
 }
@@ -754,17 +760,36 @@ func (line *xlsxLine) Equals(other xlsxLine) bool {
 }
 }
 
 
 type xlsxCellStyles struct {
 type xlsxCellStyles struct {
+	XMLName   xml.Name        `xml:"cellStyles"`
 	Count     int             `xml:"count,attr"`
 	Count     int             `xml:"count,attr"`
 	CellStyle []xlsxCellStyle `xml:"cellStyle,omitempty"`
 	CellStyle []xlsxCellStyle `xml:"cellStyle,omitempty"`
 }
 }
 
 
+func (cellStyles *xlsxCellStyles) Marshal() (result string, err error) {
+	if cellStyles.Count > 0 {
+		result = fmt.Sprintf(`<cellStyles count="%d">`, cellStyles.Count)
+		for _, cellStyle := range cellStyles.CellStyle {
+			var xCellStyle []byte
+			xCellStyle, err = xml.Marshal(cellStyle)
+			if err != nil {
+				return
+			}
+			result += string(xCellStyle)
+		}
+		result += `</cellStyles>`
+	}
+	return
+
+}
+
 type xlsxCellStyle struct {
 type xlsxCellStyle struct {
-	BuiltInId     *int   `xml:"builtInId,attr,omitempty"`
-	CustomBuiltIn *bool  `xml:"customBuiltIn,attr,omitempty"`
-	Hidden        *bool  `xml:"hidden,attr,omitempty"`
-	ILevel        *bool  `xml:"iLevel,attr,omitempty"`
-	Name          string `xml:"name,attr"`
-	XFId          int    `xml:"xfId,att"`
+	XMLName       xml.Name `xml:"cellStyle"`
+	BuiltInId     *int     `xml:"builtInId,attr,omitempty"`
+	CustomBuiltIn *bool    `xml:"customBuiltIn,attr,omitempty"`
+	Hidden        *bool    `xml:"hidden,attr,omitempty"`
+	ILevel        *bool    `xml:"iLevel,attr,omitempty"`
+	Name          string   `xml:"name,attr"`
+	XfId          int      `xml:"xfId,attr"`
 }
 }
 
 
 // xlsxCellStyleXfs directly maps the cellStyleXfs element in the
 // xlsxCellStyleXfs directly maps the cellStyleXfs element in the

+ 20 - 0
xmlStyle_test.go

@@ -110,6 +110,26 @@ func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellStyleXf(c *C) {
 	c.Assert(string(result), Equals, expected)
 	c.Assert(string(result), Equals, expected)
 }
 }
 
 
+// Test we produce valid output for a style file with one cellStyle definition.
+func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellStyle(c *C) {
+	var builtInId int
+	styles := newXlsxStyleSheet(nil)
+	styles.CellStyles = xlsxCellStyles{Count: 1}
+	styles.CellStyles.CellStyle = make([]xlsxCellStyle, 1)
+
+	builtInId = 31
+	styles.CellStyles.CellStyle[0] = xlsxCellStyle{
+		Name:      "Bob",
+		BuiltInId: &builtInId, // XXX Todo - work out built-ins!
+		XfId:      0,
+	}
+	expected := `<?xml version="1.0" encoding="UTF-8"?>
+<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><cellStyles count="1"><cellStyle builtInId="31" name="Bob" xfId="0"></cellStyle></cellStyles></styleSheet>`
+	result, err := styles.Marshal()
+	c.Assert(err, IsNil)
+	c.Assert(string(result), Equals, expected)
+}
+
 // Test we produce valid output for a style file with one cellXf
 // Test we produce valid output for a style file with one cellXf
 // definition.
 // definition.
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellXf(c *C) {
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellXf(c *C) {