Browse Source

Don't duplicate Xf's in the style file.

Geoffrey J. Teale 11 years ago
parent
commit
21092a15e4
3 changed files with 41 additions and 15 deletions
  1. 2 2
      file_test.go
  2. 4 13
      sheet_test.go
  3. 35 0
      xmlStyle.go

+ 2 - 2
file_test.go

@@ -279,7 +279,7 @@ func (l *FileSuite) TestMarshalFile(c *C) {
 	c.Assert(parts["xl/worksheets/sheet1.xml"], Equals, expectedSheet1)
 
 	expectedSheet2 := `<?xml version="1.0" encoding="UTF-8"?>
-<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetPr filterMode="false"><pageSetUpPr fitToPage="false"></pageSetUpPr></sheetPr><sheetViews><sheetView windowProtection="false" showFormulas="false" showGridLines="true" showRowColHeaders="true" showZeros="true" rightToLeft="false" tabSelected="true" showOutlineSymbols="true" defaultGridColor="true" view="normal" topLeftCell="A1" colorId="64" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100" workbookViewId="0"><selection pane="topLeft" activeCell="A1" activeCellId="0" sqref="A1"></selection></sheetView></sheetViews><sheetFormatPr defaultRowHeight="12.85"></sheetFormatPr><dimension ref="A1"></dimension><cols><col collapsed="false" hidden="false" max="1" min="1" width="9.5"></col></cols><printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"></printOptions><pageMargins left="0.7875" right="0.7875" top="1.05277777777778" bottom="1.05277777777778" header="0.7875" footer="0.7875"></pageMargins><pageSetup paperSize="9" scale="100" firstPageNumber="1" fitToWidth="1" fitToHeight="1" pageOrder="downThenOver" orientation="portrait" usePrinterDefaults="false" blackAndWhite="false" draft="false" cellComments="none" useFirstPageNumber="true" horizontalDpi="300" verticalDpi="300" copies="1"></pageSetup><sheetData><row r="1"><c r="A1" s="1" t="s"><v>0</v></c></row></sheetData><headerFooter differentFirst="false" differentOddEven="false"><oddHeader>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12&amp;A</oddHeader><oddFooter>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12Page &amp;P</oddFooter></headerFooter></worksheet>`
+<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetPr filterMode="false"><pageSetUpPr fitToPage="false"></pageSetUpPr></sheetPr><sheetViews><sheetView windowProtection="false" showFormulas="false" showGridLines="true" showRowColHeaders="true" showZeros="true" rightToLeft="false" tabSelected="true" showOutlineSymbols="true" defaultGridColor="true" view="normal" topLeftCell="A1" colorId="64" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100" workbookViewId="0"><selection pane="topLeft" activeCell="A1" activeCellId="0" sqref="A1"></selection></sheetView></sheetViews><sheetFormatPr defaultRowHeight="12.85"></sheetFormatPr><dimension ref="A1"></dimension><cols><col collapsed="false" hidden="false" max="1" min="1" width="9.5"></col></cols><printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"></printOptions><pageMargins left="0.7875" right="0.7875" top="1.05277777777778" bottom="1.05277777777778" header="0.7875" footer="0.7875"></pageMargins><pageSetup paperSize="9" scale="100" firstPageNumber="1" fitToWidth="1" fitToHeight="1" pageOrder="downThenOver" orientation="portrait" usePrinterDefaults="false" blackAndWhite="false" draft="false" cellComments="none" useFirstPageNumber="true" horizontalDpi="300" verticalDpi="300" copies="1"></pageSetup><sheetData><row r="1"><c r="A1" s="0" t="s"><v>0</v></c></row></sheetData><headerFooter differentFirst="false" differentOddEven="false"><oddHeader>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12&amp;A</oddHeader><oddFooter>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12Page &amp;P</oddFooter></headerFooter></worksheet>`
 	c.Assert(parts["xl/worksheets/sheet2.xml"], Equals, expectedSheet2)
 
 	// .rels.xml
@@ -650,7 +650,7 @@ func (l *FileSuite) TestMarshalFile(c *C) {
 	// For now we only allow simple string data in the
 	// spreadsheet.  Style support will follow.
 	expectedStyles := `<?xml version="1.0" encoding="UTF-8"?>
-<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="1"><font><sz val="12"/><name val="Verdana"/><family val="0"/><charset val="0"/></font></fonts><cellStyleXfs count="2"><xf applyAlignment="false" applyBorder="false" applyFont="false" applyFill="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="false" textRotation="0" vertical="" wrapText="false"/></xf><xf applyAlignment="false" applyBorder="false" applyFont="false" applyFill="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="false" textRotation="0" vertical="" wrapText="false"/></xf></cellStyleXfs><cellXfs count="2"><xf applyAlignment="false" applyBorder="false" applyFont="false" applyFill="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="false" textRotation="0" vertical="" wrapText="false"/></xf><xf applyAlignment="false" applyBorder="false" applyFont="false" applyFill="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="false" textRotation="0" vertical="" wrapText="false"/></xf></cellXfs></styleSheet>`
+<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="1"><font><sz val="12"/><name val="Verdana"/><family val="0"/><charset val="0"/></font></fonts><cellStyleXfs count="1"><xf applyAlignment="false" applyBorder="false" applyFont="false" applyFill="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="false" textRotation="0" vertical="" wrapText="false"/></xf></cellStyleXfs><cellXfs count="1"><xf applyAlignment="false" applyBorder="false" applyFont="false" applyFill="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="false" textRotation="0" vertical="" wrapText="false"/></xf></cellXfs></styleSheet>`
 	c.Assert(parts["xl/styles.xml"], Equals, expectedStyles)
 }
 

+ 4 - 13
sheet_test.go

@@ -92,30 +92,21 @@ func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
 	c.Assert(styles.Borders.Border[0].Top.Style, Equals, "none")
 	c.Assert(styles.Borders.Border[0].Bottom.Style, Equals, "thin")
 
-	c.Assert(styles.CellStyleXfs.Count, Equals, 2)
+	c.Assert(styles.CellStyleXfs.Count, Equals, 1)
 	// The 0th CellStyleXf could just be getting the zero values by default
 	c.Assert(styles.CellStyleXfs.Xf[0].FontId, Equals, 0)
 	c.Assert(styles.CellStyleXfs.Xf[0].FillId, Equals, 0)
 	c.Assert(styles.CellStyleXfs.Xf[0].BorderId, Equals, 0)
-	// The 1st element cannot get initialised this way by accident.
-	c.Assert(styles.CellStyleXfs.Xf[1].FontId, Equals, 0)
-	c.Assert(styles.CellStyleXfs.Xf[1].FillId, Equals, 0)
-	c.Assert(styles.CellStyleXfs.Xf[1].BorderId, Equals, 0)
 
-	c.Assert(styles.CellXfs.Count, Equals, 2)
+	c.Assert(styles.CellXfs.Count, Equals, 1)
 	c.Assert(styles.CellXfs.Xf[0].FontId, Equals, 0)
 	c.Assert(styles.CellXfs.Xf[0].FillId, Equals, 0)
 	c.Assert(styles.CellXfs.Xf[0].BorderId, Equals, 0)
-	// As above, we need the 1st element to make the test fail
-	// when it should.
-	c.Assert(styles.CellXfs.Xf[1].FontId, Equals, 0)
-	c.Assert(styles.CellXfs.Xf[1].FillId, Equals, 0)
-	c.Assert(styles.CellXfs.Xf[1].BorderId, Equals, 0)
 
 	// Finally we check that the cell points to the right CellXf /
 	// CellStyleXf.
 	c.Assert(worksheet.SheetData.Row[0].C[0].S, Equals, 0)
-	c.Assert(worksheet.SheetData.Row[0].C[1].S, Equals, 1)
+	c.Assert(worksheet.SheetData.Row[0].C[1].S, Equals, 0)
 }
 
 func (s *SheetSuite) TestMarshalSheet(c *C) {
@@ -158,6 +149,6 @@ func (s *SheetSuite) TestMarshalSheetWithMultipleCells(c *C) {
 	_, err = output.Write(body)
 	c.Assert(err, IsNil)
 	expectedXLSXSheet := `<?xml version="1.0" encoding="UTF-8"?>
-<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetPr filterMode="false"><pageSetUpPr fitToPage="false"></pageSetUpPr></sheetPr><sheetViews><sheetView windowProtection="false" showFormulas="false" showGridLines="true" showRowColHeaders="true" showZeros="true" rightToLeft="false" tabSelected="true" showOutlineSymbols="true" defaultGridColor="true" view="normal" topLeftCell="A1" colorId="64" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100" workbookViewId="0"><selection pane="topLeft" activeCell="A1" activeCellId="0" sqref="A1"></selection></sheetView></sheetViews><sheetFormatPr defaultRowHeight="12.85"></sheetFormatPr><dimension ref="A1:B1"></dimension><cols><col collapsed="false" hidden="false" max="1" min="1" width="9.5"></col><col collapsed="false" hidden="false" max="2" min="2" width="9.5"></col></cols><printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"></printOptions><pageMargins left="0.7875" right="0.7875" top="1.05277777777778" bottom="1.05277777777778" header="0.7875" footer="0.7875"></pageMargins><pageSetup paperSize="9" scale="100" firstPageNumber="1" fitToWidth="1" fitToHeight="1" pageOrder="downThenOver" orientation="portrait" usePrinterDefaults="false" blackAndWhite="false" draft="false" cellComments="none" useFirstPageNumber="true" horizontalDpi="300" verticalDpi="300" copies="1"></pageSetup><sheetData><row r="1"><c r="A1" s="0" t="s"><v>0</v></c><c r="B1" s="1" t="s"><v>1</v></c></row></sheetData><headerFooter differentFirst="false" differentOddEven="false"><oddHeader>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12&amp;A</oddHeader><oddFooter>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12Page &amp;P</oddFooter></headerFooter></worksheet>`
+<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetPr filterMode="false"><pageSetUpPr fitToPage="false"></pageSetUpPr></sheetPr><sheetViews><sheetView windowProtection="false" showFormulas="false" showGridLines="true" showRowColHeaders="true" showZeros="true" rightToLeft="false" tabSelected="true" showOutlineSymbols="true" defaultGridColor="true" view="normal" topLeftCell="A1" colorId="64" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100" workbookViewId="0"><selection pane="topLeft" activeCell="A1" activeCellId="0" sqref="A1"></selection></sheetView></sheetViews><sheetFormatPr defaultRowHeight="12.85"></sheetFormatPr><dimension ref="A1:B1"></dimension><cols><col collapsed="false" hidden="false" max="1" min="1" width="9.5"></col><col collapsed="false" hidden="false" max="2" min="2" width="9.5"></col></cols><printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"></printOptions><pageMargins left="0.7875" right="0.7875" top="1.05277777777778" bottom="1.05277777777778" header="0.7875" footer="0.7875"></pageMargins><pageSetup paperSize="9" scale="100" firstPageNumber="1" fitToWidth="1" fitToHeight="1" pageOrder="downThenOver" orientation="portrait" usePrinterDefaults="false" blackAndWhite="false" draft="false" cellComments="none" useFirstPageNumber="true" horizontalDpi="300" verticalDpi="300" copies="1"></pageSetup><sheetData><row r="1"><c r="A1" s="0" t="s"><v>0</v></c><c r="B1" s="0" t="s"><v>1</v></c></row></sheetData><headerFooter differentFirst="false" differentOddEven="false"><oddHeader>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12&amp;A</oddHeader><oddFooter>&amp;C&amp;&#34;Times New Roman,Regular&#34;&amp;12Page &amp;P</oddFooter></headerFooter></worksheet>`
 	c.Assert(output.String(), Equals, expectedXLSXSheet)
 }

+ 35 - 0
xmlStyle.go

@@ -143,6 +143,12 @@ func (styles *xlsxStyleSheet) addBorder(xBorder xlsxBorder) (index int) {
 }
 
 func (styles *xlsxStyleSheet) addCellStyleXf(xCellStyleXf xlsxXf) (index int) {
+	var cellStyleXf xlsxXf
+	for index, cellStyleXf = range styles.CellStyleXfs.Xf {
+		if cellStyleXf.Equals(xCellStyleXf) {
+			return index
+		}
+	}
 	styles.CellStyleXfs.Xf = append(styles.CellStyleXfs.Xf, xCellStyleXf)
 	index = styles.CellStyleXfs.Count
 	styles.CellStyleXfs.Count += 1
@@ -150,6 +156,13 @@ func (styles *xlsxStyleSheet) addCellStyleXf(xCellStyleXf xlsxXf) (index int) {
 }
 
 func (styles *xlsxStyleSheet) addCellXf(xCellXf xlsxXf) (index int) {
+	var cellXf xlsxXf
+	for index, cellXf = range styles.CellXfs.Xf {
+		if cellXf.Equals(xCellXf) {
+			return index
+		}
+	}
+
 	styles.CellXfs.Xf = append(styles.CellXfs.Xf, xCellXf)
 	index = styles.CellXfs.Count
 	styles.CellXfs.Count += 1
@@ -610,6 +623,19 @@ type xlsxXf struct {
 	alignment       xlsxAlignment `xml:"alignment"`
 }
 
+func (xf *xlsxXf) Equals(other xlsxXf) bool {
+	return xf.ApplyAlignment == other.ApplyAlignment &&
+		xf.ApplyBorder == other.ApplyBorder &&
+		xf.ApplyFont == other.ApplyFont &&
+		xf.ApplyFill == other.ApplyFill &&
+		xf.ApplyProtection == other.ApplyProtection &&
+		xf.BorderId == other.BorderId &&
+		xf.FillId == other.FillId &&
+		xf.FontId == other.FontId &&
+		xf.NumFmtId == other.NumFmtId &&
+		xf.alignment.Equals(other.alignment)
+}
+
 func (xf *xlsxXf) Marshal(outputBorderMap, outputFillMap, outputFontMap map[int]int) (result string, err error) {
 	var xalignment string
 	result = fmt.Sprintf(`<xf applyAlignment="%t" applyBorder="%t" applyFont="%t" applyFill="%t" applyProtection="%t" borderId="%d" fillId="%d" fontId="%d" numFmtId="%d">`, xf.ApplyAlignment, xf.ApplyBorder, xf.ApplyFont, xf.ApplyFill, xf.ApplyProtection, outputBorderMap[xf.BorderId], outputFillMap[xf.FillId], outputFontMap[xf.FontId], xf.NumFmtId)
@@ -631,6 +657,15 @@ type xlsxAlignment struct {
 	WrapText     bool   `xml:"wrapText,attr"`
 }
 
+func (alignment *xlsxAlignment) Equals(other xlsxAlignment) bool {
+	return alignment.Horizontal == other.Horizontal &&
+		alignment.Indent == other.Indent &&
+		alignment.ShrinkToFit == other.ShrinkToFit &&
+		alignment.TextRotation == other.TextRotation &&
+		alignment.Vertical == other.Vertical &&
+		alignment.WrapText == other.WrapText
+}
+
 func (alignment *xlsxAlignment) Marshal() (result string, err error) {
 	result = fmt.Sprintf(`<alignment horizontal="%s" indent="%d" shrinkToFit="%t" textRotation="%d" vertical="%s" wrapText="%t"/>`, alignment.Horizontal, alignment.Indent, alignment.ShrinkToFit, alignment.TextRotation, alignment.Vertical, alignment.WrapText)
 	return