Browse Source

Merge branch 'blackss2-master'

Geoffrey J. Teale 10 years ago
parent
commit
2d5bc2c1b0
9 changed files with 272 additions and 89 deletions
  1. 88 10
      cell.go
  2. 31 1
      col.go
  3. 2 2
      file_test.go
  4. 6 1
      lib.go
  5. 93 51
      sheet.go
  6. 18 16
      sheet_test.go
  7. 20 2
      style.go
  8. 8 0
      xmlStyle.go
  9. 6 6
      xmlWorksheet.go

+ 88 - 10
cell.go

@@ -5,6 +5,7 @@ import (
 	"math"
 	"math"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"time"
 )
 )
 
 
 // CellType is an int type for storing metadata about the data type in the cell.
 // CellType is an int type for storing metadata about the data type in the cell.
@@ -18,6 +19,8 @@ const (
 	CellTypeBool
 	CellTypeBool
 	CellTypeInline
 	CellTypeInline
 	CellTypeError
 	CellTypeError
+	CellTypeDate
+	CellTypeGeneral
 )
 )
 
 
 // Cell is a high level structure intended to provide user access to
 // Cell is a high level structure intended to provide user access to
@@ -43,7 +46,7 @@ type CellInterface interface {
 
 
 // NewCell creates a cell and adds it to a row.
 // NewCell creates a cell and adds it to a row.
 func NewCell(r *Row) *Cell {
 func NewCell(r *Row) *Cell {
-	return &Cell{style: NewStyle(), Row: r}
+	return &Cell{Row: r}
 }
 }
 
 
 // Merge with other cells, horizontally and/or vertically.
 // Merge with other cells, horizontally and/or vertically.
@@ -71,7 +74,7 @@ func (c *Cell) String() string {
 
 
 // SetFloat sets the value of a cell to a float.
 // SetFloat sets the value of a cell to a float.
 func (c *Cell) SetFloat(n float64) {
 func (c *Cell) SetFloat(n float64) {
-	c.SetFloatWithFormat(n, "general")
+	c.SetFloatWithFormat(n, builtInNumFmt[builtInNumFmtIndex_GENERAL])
 }
 }
 
 
 /*
 /*
@@ -100,6 +103,36 @@ func (c *Cell) SetFloatWithFormat(n float64, format string) {
 	c.cellType = CellTypeNumeric
 	c.cellType = CellTypeNumeric
 }
 }
 
 
+var timeLocationUTC *time.Location
+
+func init() {
+	timeLocationUTC, _ = time.LoadLocation("UTC")
+}
+
+func timeToUTCTime(t time.Time) time.Time {
+	return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), timeLocationUTC)
+}
+
+func timeToExcelTime(t time.Time) float64 {
+	return float64(t.Unix())/86400.0 + 25569.0
+}
+
+// SetDate sets the value of a cell to a float.
+func (c *Cell) SetDate(t time.Time) {
+	c.SetDateTimeWithFormat(float64(int64(timeToExcelTime(timeToUTCTime(t)))), builtInNumFmt[14])
+}
+
+func (c *Cell) SetDateTime(t time.Time) {
+	c.SetDateTimeWithFormat(timeToExcelTime(timeToUTCTime(t)), builtInNumFmt[14])
+}
+
+func (c *Cell) SetDateTimeWithFormat(n float64, format string) {
+	c.Value = strconv.FormatFloat(n, 'f', -1, 64)
+	c.numFmt = format
+	c.formula = ""
+	c.cellType = CellTypeDate
+}
+
 // Float returns the value of cell as a number.
 // Float returns the value of cell as a number.
 func (c *Cell) Float() (float64, error) {
 func (c *Cell) Float() (float64, error) {
 	f, err := strconv.ParseFloat(c.Value, 64)
 	f, err := strconv.ParseFloat(c.Value, 64)
@@ -112,7 +145,7 @@ func (c *Cell) Float() (float64, error) {
 // SetInt64 sets a cell's value to a 64-bit integer.
 // SetInt64 sets a cell's value to a 64-bit integer.
 func (c *Cell) SetInt64(n int64) {
 func (c *Cell) SetInt64(n int64) {
 	c.Value = fmt.Sprintf("%d", n)
 	c.Value = fmt.Sprintf("%d", n)
-	c.numFmt = "0"
+	c.numFmt = builtInNumFmt[builtInNumFmtIndex_INT]
 	c.formula = ""
 	c.formula = ""
 	c.cellType = CellTypeNumeric
 	c.cellType = CellTypeNumeric
 }
 }
@@ -129,11 +162,53 @@ func (c *Cell) Int64() (int64, error) {
 // SetInt sets a cell's value to an integer.
 // SetInt sets a cell's value to an integer.
 func (c *Cell) SetInt(n int) {
 func (c *Cell) SetInt(n int) {
 	c.Value = fmt.Sprintf("%d", n)
 	c.Value = fmt.Sprintf("%d", n)
-	c.numFmt = "0"
+	c.numFmt = builtInNumFmt[builtInNumFmtIndex_INT]
 	c.formula = ""
 	c.formula = ""
 	c.cellType = CellTypeNumeric
 	c.cellType = CellTypeNumeric
 }
 }
 
 
+// SetInt sets a cell's value to an integer.
+func (c *Cell) SetValue(n interface{}) {
+	var s string
+	switch n.(type) {
+	case time.Time:
+		c.SetDateTime(n.(time.Time))
+		return
+	case int:
+		c.setGeneral(fmt.Sprintf("%v", n))
+		return
+	case int32:
+		c.setGeneral(fmt.Sprintf("%v", n))
+		return
+	case int64:
+		c.setGeneral(fmt.Sprintf("%v", n))
+		return
+	case float32:
+		c.setGeneral(fmt.Sprintf("%v", n))
+		return
+	case float64:
+		c.setGeneral(fmt.Sprintf("%v", n))
+		return
+	case string:
+		s = n.(string)
+	case []byte:
+		s = string(n.([]byte))
+	case nil:
+		s = ""
+	default:
+		s = fmt.Sprintf("%v", n)
+	}
+	c.SetString(s)
+}
+
+// SetInt sets a cell's value to an integer.
+func (c *Cell) setGeneral(s string) {
+	c.Value = s
+	c.numFmt = builtInNumFmt[builtInNumFmtIndex_GENERAL]
+	c.formula = ""
+	c.cellType = CellTypeGeneral
+}
+
 // Int returns the value of cell as integer.
 // Int returns the value of cell as integer.
 // Has max 53 bits of precision
 // Has max 53 bits of precision
 // See: float64(int64(math.MaxInt))
 // See: float64(int64(math.MaxInt))
@@ -184,6 +259,9 @@ func (c *Cell) Formula() string {
 
 
 // GetStyle returns the Style associated with a Cell
 // GetStyle returns the Style associated with a Cell
 func (c *Cell) GetStyle() *Style {
 func (c *Cell) GetStyle() *Style {
+	if c.style == nil {
+		c.style = NewStyle()
+	}
 	return c.style
 	return c.style
 }
 }
 
 
@@ -222,11 +300,11 @@ func (c *Cell) FormattedValue() string {
 		return parseTime(c)
 		return parseTime(c)
 	}
 	}
 	switch numberFormat {
 	switch numberFormat {
-	case "general", "@":
+	case builtInNumFmt[builtInNumFmtIndex_GENERAL], builtInNumFmt[builtInNumFmtIndex_STRING]:
 		return c.Value
 		return c.Value
-	case "0", "#,##0":
+	case builtInNumFmt[builtInNumFmtIndex_INT], "#,##0":
 		return c.formatToInt("%d")
 		return c.formatToInt("%d")
-	case "0.00", "#,##0.00":
+	case builtInNumFmt[builtInNumFmtIndex_FLOAT], "#,##0.00":
 		return c.formatToFloat("%.2f")
 		return c.formatToFloat("%.2f")
 	case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
 	case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
 		f, err := strconv.ParseFloat(c.Value, 64)
 		f, err := strconv.ParseFloat(c.Value, 64)
@@ -278,9 +356,9 @@ func parseTime(c *Cell) string {
 	format := c.GetNumberFormat()
 	format := c.GetNumberFormat()
 	// Replace Excel placeholders with Go time placeholders.
 	// Replace Excel placeholders with Go time placeholders.
 	// For example, replace yyyy with 2006. These are in a specific order,
 	// For example, replace yyyy with 2006. These are in a specific order,
-    // due to the fact that m is used in month, minute, and am/pm. It would
-    // be easier to fix that with regular expressions, but if it's possible
-    // to keep this simple it would be easier to maintain.
+	// due to the fact that m is used in month, minute, and am/pm. It would
+	// be easier to fix that with regular expressions, but if it's possible
+	// to keep this simple it would be easier to maintain.
 	replacements := []struct{ xltime, gotime string }{
 	replacements := []struct{ xltime, gotime string }{
 		{"yyyy", "2006"},
 		{"yyyy", "2006"},
 		{"yy", "06"},
 		{"yy", "06"},

+ 31 - 1
col.go

@@ -9,5 +9,35 @@ type Col struct {
 	Hidden    bool
 	Hidden    bool
 	Width     float64
 	Width     float64
 	Collapsed bool
 	Collapsed bool
-	//	Style     int
+	numFmt    string
+	style     *Style
+}
+
+func (c *Col) SetType(cellType CellType) {
+	switch cellType {
+	case CellTypeString:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_STRING]
+	case CellTypeBool:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_GENERAL] //TEMP
+	case CellTypeNumeric:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_INT]
+	case CellTypeDate:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_DATE]
+	case CellTypeFormula:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_GENERAL]
+	case CellTypeError:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_GENERAL] //TEMP
+	case CellTypeGeneral:
+		c.numFmt = builtInNumFmt[builtInNumFmtIndex_GENERAL]
+	}
+}
+
+// GetStyle returns the Style associated with a Col
+func (c *Col) GetStyle() *Style {
+	return c.style
+}
+
+// SetStyle sets the style of a Col
+func (c *Col) SetStyle(style *Style) {
+	c.style = style
 }
 }

+ 2 - 2
file_test.go

@@ -281,11 +281,11 @@ func (l *FileSuite) TestMarshalFile(c *C) {
 
 
 	// sheets
 	// sheets
 	expectedSheet1 := `<?xml version="1.0" encoding="UTF-8"?>
 	expectedSheet1 := `<?xml version="1.0" encoding="UTF-8"?>
-<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetPr filterMode="false"><pageSetUpPr fitToPage="false"></pageSetUpPr></sheetPr><dimension ref="A1"></dimension><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><cols><col collapsed="false" hidden="false" max="1" min="1" width="9.5"></col></cols><sheetData><row r="1"><c r="A1" t="s"><v>0</v></c></row></sheetData><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><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><dimension ref="A1"></dimension><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><cols><col collapsed="false" hidden="false" max="1" min="1" style="0" width="9.5"></col></cols><sheetData><row r="1"><c r="A1" t="s"><v>0</v></c></row></sheetData><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><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/sheet1.xml"], Equals, expectedSheet1)
 	c.Assert(parts["xl/worksheets/sheet1.xml"], Equals, expectedSheet1)
 
 
 	expectedSheet2 := `<?xml version="1.0" encoding="UTF-8"?>
 	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><dimension ref="A1"></dimension><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><cols><col collapsed="false" hidden="false" max="1" min="1" width="9.5"></col></cols><sheetData><row r="1"><c r="A1" t="s"><v>0</v></c></row></sheetData><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><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><dimension ref="A1"></dimension><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><cols><col collapsed="false" hidden="false" max="1" min="1" style="0" width="9.5"></col></cols><sheetData><row r="1"><c r="A1" t="s"><v>0</v></c></row></sheetData><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><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)
 	c.Assert(parts["xl/worksheets/sheet2.xml"], Equals, expectedSheet2)
 
 
 	// .rels.xml
 	// .rels.xml

+ 6 - 1
lib.go

@@ -458,11 +458,16 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, []*Col, in
 		// spreadsheet - we deliberately exclude these
 		// spreadsheet - we deliberately exclude these
 		// columns.
 		// columns.
 		for i := rawcol.Min; i <= rawcol.Max && i <= colCount; i++ {
 		for i := rawcol.Min; i <= rawcol.Max && i <= colCount; i++ {
-			cols[i-1] = &Col{
+			col := &Col{
 				Min:    rawcol.Min,
 				Min:    rawcol.Min,
 				Max:    rawcol.Max,
 				Max:    rawcol.Max,
 				Hidden: rawcol.Hidden,
 				Hidden: rawcol.Hidden,
 				Width:  rawcol.Width}
 				Width:  rawcol.Width}
+			cols[i-1] = col
+			if file.styles != nil {
+				col.style = file.styles.getStyle(rawcol.Style)
+				col.numFmt = file.styles.getNumberFormat(rawcol.Style)
+			}
 		}
 		}
 	}
 	}
 
 

+ 93 - 51
sheet.go

@@ -50,17 +50,23 @@ func (s *Sheet) AddRow() *Row {
 func (s *Sheet) maybeAddCol(cellCount int) {
 func (s *Sheet) maybeAddCol(cellCount int) {
 	if cellCount > s.MaxCol {
 	if cellCount > s.MaxCol {
 		col := &Col{
 		col := &Col{
+			style:     NewStyle(),
 			Min:       cellCount,
 			Min:       cellCount,
 			Max:       cellCount,
 			Max:       cellCount,
 			Hidden:    false,
 			Hidden:    false,
 			Collapsed: false,
 			Collapsed: false,
-			// Style:     0,
-			Width: ColWidth}
+			Width:     ColWidth}
 		s.Cols = append(s.Cols, col)
 		s.Cols = append(s.Cols, col)
 		s.MaxCol = cellCount
 		s.MaxCol = cellCount
 	}
 	}
 }
 }
 
 
+// Make sure we always have as many Cols as we do cells.
+func (s *Sheet) Col(idx int) *Col {
+	s.maybeAddCol(idx + 1)
+	return s.Cols[idx]
+}
+
 // Get a Cell by passing it's cartesian coordinates (zero based) as
 // Get a Cell by passing it's cartesian coordinates (zero based) as
 // row and column integer indexes.
 // row and column integer indexes.
 //
 //
@@ -84,12 +90,12 @@ func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
 		return fmt.Errorf("Could not set width for range %d-%d: startcol must be less than endcol.", startcol, endcol)
 		return fmt.Errorf("Could not set width for range %d-%d: startcol must be less than endcol.", startcol, endcol)
 	}
 	}
 	col := &Col{
 	col := &Col{
+		style:     NewStyle(),
 		Min:       startcol + 1,
 		Min:       startcol + 1,
 		Max:       endcol + 1,
 		Max:       endcol + 1,
 		Hidden:    false,
 		Hidden:    false,
 		Collapsed: false,
 		Collapsed: false,
-		// Style:     0,
-		Width: width}
+		Width:     width}
 	s.Cols = append(s.Cols, col)
 	s.Cols = append(s.Cols, col)
 	if endcol+1 > s.MaxCol {
 	if endcol+1 > s.MaxCol {
 		s.MaxCol = endcol + 1
 		s.MaxCol = endcol + 1
@@ -103,7 +109,33 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 	xSheet := xlsxSheetData{}
 	xSheet := xlsxSheetData{}
 	maxRow := 0
 	maxRow := 0
 	maxCell := 0
 	maxCell := 0
-	XfId := 0
+
+	colsXfIdList := make([]int, len(s.Cols))
+	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
+	for c, col := range s.Cols {
+		XfId := 0
+
+		style := col.GetStyle()
+		//col's style always not nil
+		if style != nil {
+			xNumFmt := styles.newNumFmt(col.numFmt)
+			XfId = handleStyleForXLSX(style, xNumFmt.NumFmtId, styles)
+		}
+		colsXfIdList[c] = XfId
+
+		if col.Width == 0 {
+			col.Width = ColWidth
+		}
+		worksheet.Cols.Col = append(worksheet.Cols.Col,
+			xlsxCol{Min: col.Min,
+				Max:       col.Max,
+				Hidden:    col.Hidden,
+				Width:     col.Width,
+				Collapsed: col.Collapsed,
+				Style:     XfId,
+			})
+	}
+
 	for r, row := range s.Rows {
 	for r, row := range s.Rows {
 		if r > maxRow {
 		if r > maxRow {
 			maxRow = r
 			maxRow = r
@@ -115,41 +147,18 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 			xRow.Ht = fmt.Sprintf("%g", row.Height)
 			xRow.Ht = fmt.Sprintf("%g", row.Height)
 		}
 		}
 		for c, cell := range row.Cells {
 		for c, cell := range row.Cells {
-			style := cell.GetStyle()
-			if style != nil {
-				xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
-				fontId := styles.addFont(xFont)
-				fillId := styles.addFill(xFill)
-				// generate NumFmtId and add new NumFmt
-				xNumFmt := styles.newNumFmt(cell.numFmt)
-
-				// HACK - adding light grey fill, as in OO and Google
-				greyfill := xlsxFill{}
-				greyfill.PatternFill.PatternType = "lightGrey"
-				styles.addFill(greyfill)
-
-				borderId := styles.addBorder(xBorder)
-				xCellStyleXf.FontId = fontId
-				xCellStyleXf.FillId = fillId
-				xCellStyleXf.BorderId = borderId
-				xCellStyleXf.NumFmtId = 0 // General
-				xCellXf.FontId = fontId
-				xCellXf.FillId = fillId
-				xCellXf.BorderId = borderId
-				xCellXf.NumFmtId = xNumFmt.NumFmtId
-				// apply the numFmtId when it is not the default cellxf
-				if xCellXf.NumFmtId > 0 {
-					xCellXf.ApplyNumberFormat = true
-				}
+			XfId := colsXfIdList[c]
 
 
-				xCellStyleXf.Alignment.Horizontal = style.Alignment.Horizontal
-				xCellStyleXf.Alignment.Vertical = style.Alignment.Vertical
-				xCellXf.Alignment.Horizontal = style.Alignment.Horizontal
-				xCellXf.Alignment.Vertical = style.Alignment.Vertical
+			// generate NumFmtId and add new NumFmt
+			xNumFmt := styles.newNumFmt(cell.numFmt)
 
 
-				styles.addCellStyleXf(xCellStyleXf)
-				XfId = styles.addCellXf(xCellXf)
+			style := cell.style
+			if style != nil {
+				XfId = handleStyleForXLSX(style, xNumFmt.NumFmtId, styles)
+			} else if len(cell.numFmt) > 0 && s.Cols[c].numFmt != cell.numFmt {
+				XfId = handleNumFmtIdForXLSX(xNumFmt.NumFmtId, styles)
 			}
 			}
+
 			if c > maxCell {
 			if c > maxCell {
 				maxCell = c
 				maxCell = c
 			}
 			}
@@ -167,6 +176,9 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 			case CellTypeNumeric:
 			case CellTypeNumeric:
 				xC.V = cell.Value
 				xC.V = cell.Value
 				xC.S = XfId
 				xC.S = XfId
+			case CellTypeDate:
+				xC.V = cell.Value
+				xC.S = XfId
 			case CellTypeFormula:
 			case CellTypeFormula:
 				xC.V = cell.Value
 				xC.V = cell.Value
 				xC.F = &xlsxF{Content: cell.formula}
 				xC.F = &xlsxF{Content: cell.formula}
@@ -176,6 +188,9 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 				xC.F = &xlsxF{Content: cell.formula}
 				xC.F = &xlsxF{Content: cell.formula}
 				xC.T = "e"
 				xC.T = "e"
 				xC.S = XfId
 				xC.S = XfId
+			case CellTypeGeneral:
+				xC.V = cell.Value
+				xC.S = XfId
 			}
 			}
 			xRow.C = append(xRow.C, xC)
 			xRow.C = append(xRow.C, xC)
 
 
@@ -200,20 +215,6 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 		worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
 		worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
 	}
 	}
 
 
-	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
-	for _, col := range s.Cols {
-		if col.Width == 0 {
-			col.Width = ColWidth
-		}
-		worksheet.Cols.Col = append(worksheet.Cols.Col,
-			xlsxCol{Min: col.Min,
-				Max:       col.Max,
-				Hidden:    col.Hidden,
-				Width:     col.Width,
-				Collapsed: col.Collapsed,
-				// Style:     col.Style
-			})
-	}
 	worksheet.SheetData = xSheet
 	worksheet.SheetData = xSheet
 	dimension := xlsxDimension{}
 	dimension := xlsxDimension{}
 	dimension.Ref = fmt.Sprintf("A1:%s%d",
 	dimension.Ref = fmt.Sprintf("A1:%s%d",
@@ -224,3 +225,44 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 	worksheet.Dimension = dimension
 	worksheet.Dimension = dimension
 	return worksheet
 	return worksheet
 }
 }
+
+func handleStyleForXLSX(style *Style, NumFmtId int, styles *xlsxStyleSheet) (XfId int) {
+	xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
+	fontId := styles.addFont(xFont)
+	fillId := styles.addFill(xFill)
+
+	// HACK - adding light grey fill, as in OO and Google
+	greyfill := xlsxFill{}
+	greyfill.PatternFill.PatternType = "lightGrey"
+	styles.addFill(greyfill)
+
+	borderId := styles.addBorder(xBorder)
+	xCellStyleXf.FontId = fontId
+	xCellStyleXf.FillId = fillId
+	xCellStyleXf.BorderId = borderId
+	xCellStyleXf.NumFmtId = builtInNumFmtIndex_GENERAL
+	xCellXf.FontId = fontId
+	xCellXf.FillId = fillId
+	xCellXf.BorderId = borderId
+	xCellXf.NumFmtId = NumFmtId
+	// apply the numFmtId when it is not the default cellxf
+	if xCellXf.NumFmtId > 0 {
+		xCellXf.ApplyNumberFormat = true
+	}
+
+	xCellStyleXf.Alignment.Horizontal = style.Alignment.Horizontal
+	xCellStyleXf.Alignment.Vertical = style.Alignment.Vertical
+	xCellXf.Alignment.Horizontal = style.Alignment.Horizontal
+	xCellXf.Alignment.Vertical = style.Alignment.Vertical
+
+	styles.addCellStyleXf(xCellStyleXf)
+	XfId = styles.addCellXf(xCellXf)
+	return
+}
+
+func handleNumFmtIdForXLSX(NumFmtId int, styles *xlsxStyleSheet) (XfId int) {
+	xCellXf := makeXLSXCellElement()
+	xCellXf.NumFmtId = NumFmtId
+	XfId = styles.addCellXf(xCellXf)
+	return
+}

File diff suppressed because it is too large
+ 18 - 16
sheet_test.go


+ 20 - 2
style.go

@@ -60,11 +60,11 @@ func (style *Style) makeXLSXStyleElements() (xFont xlsxFont, xFill xlsxFill, xBo
 	xBorder.Right = xlsxLine{Style: style.Border.Right}
 	xBorder.Right = xlsxLine{Style: style.Border.Right}
 	xBorder.Top = xlsxLine{Style: style.Border.Top}
 	xBorder.Top = xlsxLine{Style: style.Border.Top}
 	xBorder.Bottom = xlsxLine{Style: style.Border.Bottom}
 	xBorder.Bottom = xlsxLine{Style: style.Border.Bottom}
+	xCellXf = makeXLSXCellElement()
 	xCellXf.ApplyBorder = style.ApplyBorder
 	xCellXf.ApplyBorder = style.ApplyBorder
 	xCellXf.ApplyFill = style.ApplyFill
 	xCellXf.ApplyFill = style.ApplyFill
 	xCellXf.ApplyFont = style.ApplyFont
 	xCellXf.ApplyFont = style.ApplyFont
 	xCellXf.ApplyAlignment = style.ApplyAlignment
 	xCellXf.ApplyAlignment = style.ApplyAlignment
-	xCellXf.NumFmtId = 0
 	xCellStyleXf.ApplyBorder = style.ApplyBorder
 	xCellStyleXf.ApplyBorder = style.ApplyBorder
 	xCellStyleXf.ApplyFill = style.ApplyFill
 	xCellStyleXf.ApplyFill = style.ApplyFill
 	xCellStyleXf.ApplyFont = style.ApplyFont
 	xCellStyleXf.ApplyFont = style.ApplyFont
@@ -75,6 +75,11 @@ func (style *Style) makeXLSXStyleElements() (xFont xlsxFont, xFill xlsxFill, xBo
 	return
 	return
 }
 }
 
 
+func makeXLSXCellElement() (xCellXf xlsxXf) {
+	xCellXf.NumFmtId = 0
+	return
+}
+
 // Border is a high level structure intended to provide user access to
 // Border is a high level structure intended to provide user access to
 // the contents of Border Style within an Sheet.
 // the contents of Border Style within an Sheet.
 type Border struct {
 type Border struct {
@@ -120,8 +125,21 @@ type Alignment struct {
 	Vertical   string
 	Vertical   string
 }
 }
 
 
+var defaultFontSize int
+var defaultFontName string
+
+func init() {
+	defaultFontSize = 12
+	defaultFontName = "Verdana"
+}
+
+func SetDefaultFont(size int, name string) {
+	defaultFontSize = size
+	defaultFontName = name
+}
+
 func DefaultFont() *Font {
 func DefaultFont() *Font {
-	return NewFont(12, "Verdana")
+	return NewFont(defaultFontSize, defaultFontName)
 }
 }
 
 
 func DefaultFill() *Fill {
 func DefaultFill() *Fill {

+ 8 - 0
xmlStyle.go

@@ -57,6 +57,14 @@ var builtInNumFmt = map[int]string{
 	49: "@",
 	49: "@",
 }
 }
 
 
+const (
+	builtInNumFmtIndex_GENERAL = int(0)
+	builtInNumFmtIndex_INT = int(1)
+	builtInNumFmtIndex_FLOAT = int(2)
+	builtInNumFmtIndex_DATE = int(14)
+	builtInNumFmtIndex_STRING = int(49)
+)
+
 // xlsxStyle directly maps the styleSheet element in the namespace
 // xlsxStyle directly maps the styleSheet element in the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
 // currently I have not checked it for completeness - it does as much
 // currently I have not checked it for completeness - it does as much

+ 6 - 6
xmlWorksheet.go

@@ -192,12 +192,12 @@ type xlsxCols struct {
 // currently I have not checked it for completeness - it does as much
 // currently I have not checked it for completeness - it does as much
 // as I need.
 // as I need.
 type xlsxCol struct {
 type xlsxCol struct {
-	Collapsed bool `xml:"collapsed,attr"`
-	Hidden    bool `xml:"hidden,attr"`
-	Max       int  `xml:"max,attr"`
-	Min       int  `xml:"min,attr"`
-	// Style     int     `xml:"style,attr"`
-	Width float64 `xml:"width,attr"`
+	Collapsed bool    `xml:"collapsed,attr"`
+	Hidden    bool    `xml:"hidden,attr"`
+	Max       int     `xml:"max,attr"`
+	Min       int     `xml:"min,attr"`
+	Style     int     `xml:"style,attr"`
+	Width     float64 `xml:"width,attr"`
 }
 }
 
 
 // xlsxDimension directly maps the dimension element in the namespace
 // xlsxDimension directly maps the dimension element in the namespace

Some files were not shown because too many files changed in this diff