Преглед на файлове

Switch to creating style information, for every cell, as we go, instead of
doing this on demand, this makes styles symmetric for read write purposes,
though still Cell oriented in the public UI.

Geoffrey J. Teale преди 11 години
родител
ревизия
b77a8ef11d
променени са 6 файла, в които са добавени 226 реда и са изтрити 248 реда
  1. 9 85
      cell.go
  2. 95 160
      cell_test.go
  3. 4 3
      lib.go
  4. 28 0
      style.go
  5. 11 0
      style_test.go
  6. 79 0
      xmlStyle.go

+ 9 - 85
cell.go

@@ -4,18 +4,16 @@ import (
 	"fmt"
 	"math"
 	"strconv"
-	"strings"
 )
 
 // Cell is a high level structure intended to provide user access to
 // the contents of Cell within an xlsx.Row.
 type Cell struct {
-	Value          string
-	styleIndex     int
-	styles         *xlsxStyles
-	numFmtRefTable map[int]xlsxNumFmt
-	date1904       bool
-	Hidden         bool
+	Value    string
+	style    Style
+	numFmt   string
+	date1904 bool
+	Hidden   bool
 }
 
 // CellInterface defines the public API of the Cell.
@@ -31,63 +29,12 @@ func (c *Cell) String() string {
 
 // GetStyle returns the Style associated with a Cell
 func (c *Cell) GetStyle() Style {
-	var err error
-	style := Style{}
-	style.Border = Border{}
-	style.Fill = Fill{}
-	style.Font = Font{}
-
-	if c.styleIndex > -1 && c.styleIndex <= len(c.styles.CellXfs) {
-		xf := c.styles.CellXfs[c.styleIndex]
-
-		if xf.ApplyBorder {
-			style.Border.Left = c.styles.Borders[xf.BorderId].Left.Style
-			style.Border.Right = c.styles.Borders[xf.BorderId].Right.Style
-			style.Border.Top = c.styles.Borders[xf.BorderId].Top.Style
-			style.Border.Bottom = c.styles.Borders[xf.BorderId].Bottom.Style
-		}
-		// TODO - consider how to handle the fact that
-		// ApplyFill can be missing.  At the moment the XML
-		// unmarshaller simply sets it to false, which creates
-		// a bug.
-
-		// if xf.ApplyFill {
-		if xf.FillId > -1 && xf.FillId < len(c.styles.Fills) {
-			xFill := c.styles.Fills[xf.FillId]
-			style.Fill.PatternType = xFill.PatternFill.PatternType
-			style.Fill.FgColor = xFill.PatternFill.FgColor.RGB
-			style.Fill.BgColor = xFill.PatternFill.BgColor.RGB
-		}
-		// }
-		if xf.ApplyFont {
-			xfont := c.styles.Fonts[xf.FontId]
-			style.Font.Size, err = strconv.Atoi(xfont.Sz.Val)
-			if err != nil {
-				panic(err.Error())
-			}
-			style.Font.Name = xfont.Name.Val
-			style.Font.Family, _ = strconv.Atoi(xfont.Family.Val)
-			style.Font.Charset, _ = strconv.Atoi(xfont.Charset.Val)
-		}
-	}
-	return style
+	return c.style
 }
 
 // The number format string is returnable from a cell.
 func (c *Cell) GetNumberFormat() string {
-	if c.styles == nil {
-		return ""
-	}
-	if c.styles.CellXfs == nil {
-		return ""
-	}
-	var numberFormat string = ""
-	if c.styleIndex > -1 && c.styleIndex <= len(c.styles.CellXfs) {
-		xf := c.styles.CellXfs[c.styleIndex]
-		numFmt := c.numFmtRefTable[xf.NumFmtId]
-		numberFormat = numFmt.FormatCode
-	}
-	return strings.ToLower(numberFormat)
+	return c.numFmt
 }
 
 func (c *Cell) formatToTime(format string) string {
@@ -230,29 +177,6 @@ func (c *Cell) FormattedValue() string {
 	return c.Value
 }
 
-func (c *Cell) SetStyle(style *Style) int {
-	if c.styles == nil {
-		c.styles = &xlsxStyles{}
-	}
-	index := len(c.styles.Fonts)
-	xFont := xlsxFont{}
-	xFill := xlsxFill{}
-	xBorder := xlsxBorder{}
-	xCellStyleXf := xlsxXf{}
-	xCellXf := xlsxXf{}
-	xFont.Sz.Val = strconv.Itoa(style.Font.Size)
-	xFont.Name.Val = style.Font.Name
-	xFont.Family.Val = strconv.Itoa(style.Font.Family)
-	xFont.Charset.Val = strconv.Itoa(style.Font.Charset)
-	xPatternFill := xlsxPatternFill{}
-	xPatternFill.PatternType = style.Fill.PatternType
-	xPatternFill.FgColor.RGB = style.Fill.FgColor
-	xPatternFill.BgColor.RGB = style.Fill.BgColor
-	xFill.PatternFill = xPatternFill
-	c.styles.Fonts = append(c.styles.Fonts, xFont)
-	c.styles.Fills = append(c.styles.Fills, xFill)
-	c.styles.Borders = append(c.styles.Borders, xBorder)
-	c.styles.CellStyleXfs = append(c.styles.CellStyleXfs, xCellStyleXf)
-	c.styles.CellXfs = append(c.styles.CellXfs, xCellXf)
-	return index
+func (c *Cell) SetStyle(style Style) {
+	c.style = style
 }

+ 95 - 160
cell_test.go

@@ -21,71 +21,44 @@ func (s *CellSuite) TestValueSet(c *C) {
 
 // Test that GetStyle correctly converts the xlsxStyle.Fonts.
 func (s *CellSuite) TestGetStyleWithFonts(c *C) {
-	var cell *Cell
-	var style Style
-	var xStyles *xlsxStyles
-	var fonts []xlsxFont
-	var cellXfs []xlsxXf
-
-	fonts = make([]xlsxFont, 1)
-	fonts[0] = xlsxFont{
-		Sz:   xlsxVal{Val: "10"},
-		Name: xlsxVal{Val: "Calibra"}}
-
-	cellXfs = make([]xlsxXf, 1)
-	cellXfs[0] = xlsxXf{ApplyFont: true, FontId: 0}
-
-	xStyles = &xlsxStyles{Fonts: fonts, CellXfs: cellXfs}
+	font := NewFont(10, "Calibra")
+	style := *NewStyle()
+	style.Font = *font
 
-	cell = &Cell{Value: "123", styleIndex: 0, styles: xStyles}
+	cell := &Cell{Value: "123", style: style}
 	style = cell.GetStyle()
 	c.Assert(style, NotNil)
 	c.Assert(style.Font.Size, Equals, 10)
 	c.Assert(style.Font.Name, Equals, "Calibra")
 }
 
-// Test that SetStyle correctly updates the xlsxStyle.Fonts.
+// Test that SetStyle correctly translates into a xlsxFont element
 func (s *CellSuite) TestSetStyleWithFonts(c *C) {
 	file := NewFile()
 	sheet := file.AddSheet("Test")
 	row := sheet.AddRow()
 	cell := row.AddCell()
 	font := NewFont(12, "Calibra")
-	style := NewStyle()
+	style := *NewStyle()
 	style.Font = *font
 	cell.SetStyle(style)
-	c.Assert(cell.styleIndex, Equals, 0)
-	c.Assert(cell.styles.Fonts, HasLen, 1)
-	xFont := cell.styles.Fonts[0]
+	style = cell.GetStyle()
+	xFont, _, _, _, _ := style.makeXLSXStyleElements()
 	c.Assert(xFont.Sz.Val, Equals, "12")
 	c.Assert(xFont.Name.Val, Equals, "Calibra")
 }
 
 // Test that GetStyle correctly converts the xlsxStyle.Fills.
 func (s *CellSuite) TestGetStyleWithFills(c *C) {
-	var cell *Cell
-	var style Style
-	var xStyles *xlsxStyles
-	var fills []xlsxFill
-	var cellXfs []xlsxXf
-
-	fills = make([]xlsxFill, 1)
-	fills[0] = xlsxFill{
-		PatternFill: xlsxPatternFill{
-			PatternType: "solid",
-			FgColor:     xlsxColor{RGB: "FF000000"},
-			BgColor:     xlsxColor{RGB: "00FF0000"}}}
-	cellXfs = make([]xlsxXf, 1)
-	cellXfs[0] = xlsxXf{ApplyFill: true, FillId: 0}
-
-	xStyles = &xlsxStyles{Fills: fills, CellXfs: cellXfs}
-
-	cell = &Cell{Value: "123", styleIndex: 0, styles: xStyles}
+	fill := *NewFill("solid", "FF000000", "00FF0000")
+	style := *NewStyle()
+	style.Fill = fill
+	cell := &Cell{Value: "123", style: style}
 	style = cell.GetStyle()
-	fill := style.Fill
-	c.Assert(fill.PatternType, Equals, "solid")
-	c.Assert(fill.BgColor, Equals, "00FF0000")
-	c.Assert(fill.FgColor, Equals, "FF000000")
+	_, xFill, _, _, _ := style.makeXLSXStyleElements()
+	c.Assert(xFill.PatternFill.PatternType, Equals, "solid")
+	c.Assert(xFill.PatternFill.BgColor.RGB, Equals, "00FF0000")
+	c.Assert(xFill.PatternFill.FgColor.RGB, Equals, "FF000000")
 }
 
 // Test that SetStyle correctly updates xlsxStyle.Fills.
@@ -95,12 +68,11 @@ func (s *CellSuite) TestSetStyleWithFills(c *C) {
 	row := sheet.AddRow()
 	cell := row.AddCell()
 	fill := NewFill("solid", "00FF0000", "FF000000")
-	style := NewStyle()
+	style := *NewStyle()
 	style.Fill = *fill
 	cell.SetStyle(style)
-	c.Assert(cell.styleIndex, Equals, 0)
-	c.Assert(cell.styles.Fills, HasLen, 1)
-	xFill := cell.styles.Fills[0]
+	style = cell.GetStyle()
+	_, xFill, _, _, _ := style.makeXLSXStyleElements()
 	xPatternFill := xFill.PatternFill
 	c.Assert(xPatternFill.PatternType, Equals, "solid")
 	c.Assert(xPatternFill.FgColor.RGB, Equals, "00FF0000")
@@ -109,214 +81,177 @@ func (s *CellSuite) TestSetStyleWithFills(c *C) {
 
 // Test that GetStyle correctly converts the xlsxStyle.Borders.
 func (s *CellSuite) TestGetStyleWithBorders(c *C) {
-	var cell *Cell
-	var style Style
-	var xStyles *xlsxStyles
-	var borders []xlsxBorder
-	var cellXfs []xlsxXf
-
-	borders = make([]xlsxBorder, 1)
-	borders[0] = xlsxBorder{
-		Left:   xlsxLine{Style: "thin"},
-		Right:  xlsxLine{Style: "thin"},
-		Top:    xlsxLine{Style: "thin"},
-		Bottom: xlsxLine{Style: "thin"}}
-
-	cellXfs = make([]xlsxXf, 1)
-	cellXfs[0] = xlsxXf{ApplyBorder: true, BorderId: 0}
-
-	xStyles = &xlsxStyles{Borders: borders, CellXfs: cellXfs}
-
-	cell = &Cell{Value: "123", styleIndex: 0, styles: xStyles}
+	border := *NewBorder("thin", "thin", "thin", "thin")
+	style := *NewStyle()
+	style.Border = border
+	cell := Cell{Value: "123", style: style}
 	style = cell.GetStyle()
-	border := style.Border
-	c.Assert(border.Left, Equals, "thin")
-	c.Assert(border.Right, Equals, "thin")
-	c.Assert(border.Top, Equals, "thin")
-	c.Assert(border.Bottom, Equals, "thin")
-}
-
-func (s *CellSuite) TestGetNumberFormat(c *C) {
-	var cell *Cell
-	var cellXfs []xlsxXf
-	var numFmt xlsxNumFmt
-	var numFmts []xlsxNumFmt
-	var xStyles *xlsxStyles
-	var numFmtRefTable map[int]xlsxNumFmt
-
-	cellXfs = make([]xlsxXf, 1)
-	cellXfs[0] = xlsxXf{NumFmtId: 0}
-
-	numFmts = make([]xlsxNumFmt, 1)
-	numFmtRefTable = make(map[int]xlsxNumFmt)
-
-	xStyles = &xlsxStyles{NumFmts: numFmts, CellXfs: cellXfs}
-
-	cell = &Cell{Value: "123.123", numFmtRefTable: numFmtRefTable, styleIndex: 0, styles: xStyles}
-
-	numFmt = xlsxNumFmt{NumFmtId: 0, FormatCode: "dd/mm/yy"}
-	numFmts[0] = numFmt
-	numFmtRefTable[0] = numFmt
-	c.Assert(cell.GetNumberFormat(), Equals, "dd/mm/yy")
+	_, _, xBorder, _, _ := style.makeXLSXStyleElements()
+	c.Assert(xBorder.Left.Style, Equals, "thin")
+	c.Assert(xBorder.Right.Style, Equals, "thin")
+	c.Assert(xBorder.Top.Style, Equals, "thin")
+	c.Assert(xBorder.Bottom.Style, Equals, "thin")
 }
 
 // We can return a string representation of the formatted data
 func (l *CellSuite) TestFormattedValue(c *C) {
-	var cell, earlyCell, negativeCell, smallCell *Cell
-	var cellXfs []xlsxXf
-	var numFmt xlsxNumFmt
-	var numFmts []xlsxNumFmt
-	var xStyles *xlsxStyles
-	var numFmtRefTable map[int]xlsxNumFmt
-
-	cellXfs = make([]xlsxXf, 1)
-	cellXfs[0] = xlsxXf{NumFmtId: 1}
-
-	numFmts = make([]xlsxNumFmt, 1)
-	numFmtRefTable = make(map[int]xlsxNumFmt)
-
-	xStyles = &xlsxStyles{NumFmts: numFmts, CellXfs: cellXfs}
-	cell = &Cell{Value: "37947.7500001", numFmtRefTable: numFmtRefTable, styleIndex: 0, styles: xStyles}
-	negativeCell = &Cell{Value: "-37947.7500001", numFmtRefTable: numFmtRefTable, styleIndex: 0, styles: xStyles}
-	smallCell = &Cell{Value: "0.007", numFmtRefTable: numFmtRefTable, styleIndex: 0, styles: xStyles}
-	earlyCell = &Cell{Value: "2.1", numFmtRefTable: numFmtRefTable, styleIndex: 0, styles: xStyles}
-	setCode := func(code string) {
-		numFmt = xlsxNumFmt{NumFmtId: 1, FormatCode: code}
-		numFmts[0] = numFmt
-		numFmtRefTable[1] = numFmt
-	}
-
-	setCode("general")
+	cell := Cell{Value: "37947.7500001"}
+	negativeCell := Cell{Value: "-37947.7500001"}
+	smallCell := Cell{Value: "0.007"}
+	earlyCell := Cell{Value: "2.1"}
+
+	cell.numFmt = "general"
 	c.Assert(cell.FormattedValue(), Equals, "37947.7500001")
+	negativeCell.numFmt = "general"
 	c.Assert(negativeCell.FormattedValue(), Equals, "-37947.7500001")
 
-	setCode("0")
+	cell.numFmt = "0"
 	c.Assert(cell.FormattedValue(), Equals, "37947")
 
-	setCode("#,##0") // For the time being we're not doing this
-	// comma formatting, so it'll fall back to
-	// the related non-comma form.
+	cell.numFmt = "#,##0" // For the time being we're not doing
+	// this comma formatting, so it'll fall back to the related
+	// non-comma form.
 	c.Assert(cell.FormattedValue(), Equals, "37947")
 
-	setCode("0.00")
+	cell.numFmt = "0.00"
 	c.Assert(cell.FormattedValue(), Equals, "37947.75")
 
-	setCode("#,##0.00") // For the time being we're not doing this
-	// comma formatting, so it'll fall back to
-	// the related non-comma form.
+	cell.numFmt = "#,##0.00" // For the time being we're not doing
+	// this comma formatting, so it'll fall back to the related
+	// non-comma form.
 	c.Assert(cell.FormattedValue(), Equals, "37947.75")
 
-	setCode("#,##0 ;(#,##0)")
+	cell.numFmt = "#,##0 ;(#,##0)"
 	c.Assert(cell.FormattedValue(), Equals, "37947")
+	negativeCell.numFmt = "#,##0 ;(#,##0)"
 	c.Assert(negativeCell.FormattedValue(), Equals, "(37947)")
 
-	setCode("#,##0 ;[red](#,##0)")
+	cell.numFmt = "#,##0 ;[red](#,##0)"
 	c.Assert(cell.FormattedValue(), Equals, "37947")
+	negativeCell.numFmt = "#,##0 ;[red](#,##0)"
 	c.Assert(negativeCell.FormattedValue(), Equals, "(37947)")
 
-	setCode("0%")
+	cell.numFmt = "0%"
 	c.Assert(cell.FormattedValue(), Equals, "3794775%")
 
-	setCode("0.00%")
+	cell.numFmt = "0.00%"
 	c.Assert(cell.FormattedValue(), Equals, "3794775.00%")
 
-	setCode("0.00e+00")
+	cell.numFmt = "0.00e+00"
 	c.Assert(cell.FormattedValue(), Equals, "3.794775e+04")
 
-	setCode("##0.0e+0") // This is wrong, but we'll use it for now.
+	cell.numFmt = "##0.0e+0" // This is wrong, but we'll use it for now.
 	c.Assert(cell.FormattedValue(), Equals, "3.794775e+04")
 
-	setCode("mm-dd-yy")
+	cell.numFmt = "mm-dd-yy"
 	c.Assert(cell.FormattedValue(), Equals, "11-22-03")
 
-	setCode("d-mmm-yy")
+	cell.numFmt = "d-mmm-yy"
 	c.Assert(cell.FormattedValue(), Equals, "22-Nov-03")
+	earlyCell.numFmt = "d-mmm-yy"
 	c.Assert(earlyCell.FormattedValue(), Equals, "1-Jan-00")
 
-	setCode("d-mmm")
+	cell.numFmt = "d-mmm"
 	c.Assert(cell.FormattedValue(), Equals, "22-Nov")
+	earlyCell.numFmt = "d-mmm"
 	c.Assert(earlyCell.FormattedValue(), Equals, "1-Jan")
 
-	setCode("mmm-yy")
+	cell.numFmt = "mmm-yy"
 	c.Assert(cell.FormattedValue(), Equals, "Nov-03")
 
-	setCode("h:mm am/pm")
+	cell.numFmt = "h:mm am/pm"
 	c.Assert(cell.FormattedValue(), Equals, "6:00 pm")
+	smallCell.numFmt = "h:mm am/pm"
 	c.Assert(smallCell.FormattedValue(), Equals, "12:14 am")
 
-	setCode("h:mm:ss am/pm")
+	cell.numFmt = "h:mm:ss am/pm"
 	c.Assert(cell.FormattedValue(), Equals, "6:00:00 pm")
+	smallCell.numFmt = "h:mm:ss am/pm"
 	c.Assert(smallCell.FormattedValue(), Equals, "12:14:47 am")
 
-	setCode("h:mm")
+	cell.numFmt = "h:mm"
 	c.Assert(cell.FormattedValue(), Equals, "18:00")
+	smallCell.numFmt = "h:mm"
 	c.Assert(smallCell.FormattedValue(), Equals, "00:14")
 
-	setCode("h:mm:ss")
+	cell.numFmt = "h:mm:ss"
 	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
 	// This is wrong, but there's no eary way aroud it in Go right now, AFAICT.
+	smallCell.numFmt = "h:mm:ss"
 	c.Assert(smallCell.FormattedValue(), Equals, "00:14:47")
 
-	setCode("m/d/yy h:mm")
+	cell.numFmt = "m/d/yy h:mm"
 	c.Assert(cell.FormattedValue(), Equals, "11/22/03 18:00")
+	smallCell.numFmt = "m/d/yy h:mm"
 	c.Assert(smallCell.FormattedValue(), Equals, "12/30/99 00:14") // Note, that's 1899
-	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/00 02:24")   // and 1900
+	earlyCell.numFmt = "m/d/yy h:mm"
+	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/00 02:24") // and 1900
 
-	setCode("mm:ss")
+	cell.numFmt = "mm:ss"
 	c.Assert(cell.FormattedValue(), Equals, "00:00")
+	smallCell.numFmt = "mm:ss"
 	c.Assert(smallCell.FormattedValue(), Equals, "14:47")
 
-	setCode("[h]:mm:ss")
+	cell.numFmt = "[h]:mm:ss"
 	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
+	smallCell.numFmt = "[h]:mm:ss"
 	c.Assert(smallCell.FormattedValue(), Equals, "14:47")
 
-	setCode("mmss.0") // I'm not sure about these.
+	cell.numFmt = "mmss.0" // I'm not sure about these.
 	c.Assert(cell.FormattedValue(), Equals, "00.8640")
+	smallCell.numFmt = "mmss.0"
 	c.Assert(smallCell.FormattedValue(), Equals, "1447.999997")
 
-	setCode("yyyy\\-mm\\-dd")
+	cell.numFmt = "yyyy\\-mm\\-dd"
 	c.Assert(cell.FormattedValue(), Equals, "2003\\-11\\-22")
 
-	setCode("dd/mm/yy")
+	cell.numFmt = "dd/mm/yy"
 	c.Assert(cell.FormattedValue(), Equals, "22/11/03")
+	earlyCell.numFmt = "dd/mm/yy"
 	c.Assert(earlyCell.FormattedValue(), Equals, "01/01/00")
 
-	setCode("hh:mm:ss")
+	cell.numFmt = "hh:mm:ss"
 	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
+	smallCell.numFmt = "hh:mm:ss"
 	c.Assert(smallCell.FormattedValue(), Equals, "00:14:47")
 
-	setCode("dd/mm/yy\\ hh:mm")
+	cell.numFmt = "dd/mm/yy\\ hh:mm"
 	c.Assert(cell.FormattedValue(), Equals, "22/11/03\\ 18:00")
 
-	setCode("yy-mm-dd")
+	cell.numFmt = "yy-mm-dd"
 	c.Assert(cell.FormattedValue(), Equals, "03-11-22")
 
-	setCode("d-mmm-yyyy")
+	cell.numFmt = "d-mmm-yyyy"
 	c.Assert(cell.FormattedValue(), Equals, "22-Nov-2003")
+	earlyCell.numFmt = "d-mmm-yyyy"
 	c.Assert(earlyCell.FormattedValue(), Equals, "1-Jan-1900")
 
-	setCode("m/d/yy")
+	cell.numFmt = "m/d/yy"
 	c.Assert(cell.FormattedValue(), Equals, "11/22/03")
+	earlyCell.numFmt = "m/d/yy"
 	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/00")
 
-	setCode("m/d/yyyy")
+	cell.numFmt = "m/d/yyyy"
 	c.Assert(cell.FormattedValue(), Equals, "11/22/2003")
+	earlyCell.numFmt = "m/d/yyyy"
 	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/1900")
 
-	setCode("dd-mmm-yyyy")
+	cell.numFmt = "dd-mmm-yyyy"
 	c.Assert(cell.FormattedValue(), Equals, "22-Nov-2003")
 
-	setCode("dd/mm/yyyy")
+	cell.numFmt = "dd/mm/yyyy"
 	c.Assert(cell.FormattedValue(), Equals, "22/11/2003")
 
-	setCode("mm/dd/yy hh:mm am/pm")
+	cell.numFmt = "mm/dd/yy hh:mm am/pm"
 	c.Assert(cell.FormattedValue(), Equals, "11/22/03 06:00 pm")
 
-	setCode("mm/dd/yyyy hh:mm:ss")
+	cell.numFmt = "mm/dd/yyyy hh:mm:ss"
 	c.Assert(cell.FormattedValue(), Equals, "11/22/2003 18:00:00")
+	smallCell.numFmt = "mm/dd/yyyy hh:mm:ss"
 	c.Assert(smallCell.FormattedValue(), Equals, "12/30/1899 00:14:47")
 
-	setCode("yyyy-mm-dd hh:mm:ss")
+	cell.numFmt = "yyyy-mm-dd hh:mm:ss"
 	c.Assert(cell.FormattedValue(), Equals, "2003-11-22 18:00:00")
+	smallCell.numFmt = "yyyy-mm-dd hh:mm:ss"
 	c.Assert(smallCell.FormattedValue(), Equals, "1899-12-30 00:14:47")
 }

+ 4 - 3
lib.go

@@ -396,9 +396,10 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, int, int)
 			}
 			cellX := insertColIndex - minCol
 			row.Cells[cellX].Value = getValueFromCellData(rawcell, reftable)
-			row.Cells[cellX].styleIndex = rawcell.S
-			row.Cells[cellX].styles = file.styles
-			row.Cells[cellX].numFmtRefTable = file.numFmtRefTable
+			if file.styles != nil {
+				row.Cells[cellX].style = file.styles.getStyle(rawcell.S)
+				row.Cells[cellX].numFmt = file.styles.getNumberFormat(rawcell.S, file.numFmtRefTable)
+			}
 			row.Cells[cellX].date1904 = file.Date1904
 			row.Cells[cellX].Hidden = rawrow.Hidden || cols[cellX].Hidden
 			insertColIndex++

+ 28 - 0
style.go

@@ -1,5 +1,7 @@
 package xlsx
 
+import "strconv"
+
 // Style is a high level structure intended to provide user access to
 // the contents of Style within an XLSX file.
 type Style struct {
@@ -12,6 +14,28 @@ func NewStyle() *Style {
 	return &Style{}
 }
 
+func (style *Style) makeXLSXStyleElements() (xFont xlsxFont, xFill xlsxFill, xBorder xlsxBorder, xCellStyleXf xlsxXf, xCellXf xlsxXf) {
+	xFont = xlsxFont{}
+	xFill = xlsxFill{}
+	xBorder = xlsxBorder{}
+	xCellStyleXf = xlsxXf{}
+	xCellXf = xlsxXf{}
+	xFont.Sz.Val = strconv.Itoa(style.Font.Size)
+	xFont.Name.Val = style.Font.Name
+	xFont.Family.Val = strconv.Itoa(style.Font.Family)
+	xFont.Charset.Val = strconv.Itoa(style.Font.Charset)
+	xPatternFill := xlsxPatternFill{}
+	xPatternFill.PatternType = style.Fill.PatternType
+	xPatternFill.FgColor.RGB = style.Fill.FgColor
+	xPatternFill.BgColor.RGB = style.Fill.BgColor
+	xFill.PatternFill = xPatternFill
+	xBorder.Left = xlsxLine{Style: style.Border.Left}
+	xBorder.Right = xlsxLine{Style: style.Border.Right}
+	xBorder.Top = xlsxLine{Style: style.Border.Top}
+	xBorder.Bottom = xlsxLine{Style: style.Border.Bottom}
+	return
+}
+
 // Border is a high level structure intended to provide user access to
 // the contents of Border Style within an Sheet.
 type Border struct {
@@ -21,6 +45,10 @@ type Border struct {
 	Bottom string
 }
 
+func NewBorder(left, right, top, bottom string) *Border {
+	return &Border{Left: left, Right: right, Top: top, Bottom: bottom}
+}
+
 // Fill is a high level structure intended to provide user access to
 // the contents of background and foreground color index within an Sheet.
 type Fill struct {

+ 11 - 0
style_test.go

@@ -13,6 +13,17 @@ func (s *StyleSuite) TestNewStyle(c *C) {
 	c.Assert(style, NotNil)
 }
 
+func (s *StyleSuite) TestMakeXLSXStyleElements(c *C) {
+	style := NewStyle()
+	font := *NewFont(12, "Verdana")
+	style.Font = font
+	xFont, _, _, _, _ := style.makeXLSXStyleElements()
+	// HERE YOU ARE!
+	c.Assert(xFont.Sz.Val, Equals, "12")
+	c.Assert(xFont.Name.Val, Equals, "Verdana")
+
+}
+
 type FontSuite struct{}
 
 var _ = Suite(&FontSuite{})

+ 79 - 0
xmlStyle.go

@@ -7,6 +7,11 @@
 
 package xlsx
 
+import (
+	"strconv"
+	"strings"
+)
+
 // xlsxStyle directly maps the style element in the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
 // currently I have not checked it for completeness - it does as much
@@ -119,3 +124,77 @@ type xlsxAlignment struct {
 	Vertical     string `xml:"vertical,attr"`
 	WrapText     bool   `xml:"wrapText,attr"`
 }
+
+func (styles *xlsxStyles) getStyle(styleIndex int) (style Style) {
+	style = Style{}
+	style.Border = Border{}
+	style.Fill = Fill{}
+	style.Font = Font{}
+
+	xfCount := len(styles.CellXfs)
+	if styleIndex > -1 && xfCount > 0 && styleIndex <= xfCount {
+		xf := styles.CellXfs[styleIndex]
+
+		if xf.ApplyBorder {
+			style.Border.Left = styles.Borders[xf.BorderId].Left.Style
+			style.Border.Right = styles.Borders[xf.BorderId].Right.Style
+			style.Border.Top = styles.Borders[xf.BorderId].Top.Style
+			style.Border.Bottom = styles.Borders[xf.BorderId].Bottom.Style
+		}
+		// TODO - consider how to handle the fact that
+		// ApplyFill can be missing.  At the moment the XML
+		// unmarshaller simply sets it to false, which creates
+		// a bug.
+
+		// if xf.ApplyFill {
+		if xf.FillId > -1 && xf.FillId < len(styles.Fills) {
+			xFill := styles.Fills[xf.FillId]
+			style.Fill.PatternType = xFill.PatternFill.PatternType
+			style.Fill.FgColor = xFill.PatternFill.FgColor.RGB
+			style.Fill.BgColor = xFill.PatternFill.BgColor.RGB
+		}
+		// }
+		if xf.ApplyFont {
+			xfont := styles.Fonts[xf.FontId]
+			style.Font.Size, _ = strconv.Atoi(xfont.Sz.Val)
+			style.Font.Name = xfont.Name.Val
+			style.Font.Family, _ = strconv.Atoi(xfont.Family.Val)
+			style.Font.Charset, _ = strconv.Atoi(xfont.Charset.Val)
+		}
+	}
+	return style
+
+}
+
+func (styles *xlsxStyles) getNumberFormat(styleIndex int, numFmtRefTable map[int]xlsxNumFmt) string {
+	if styles.CellXfs == nil {
+		return ""
+	}
+	var numberFormat string = ""
+	if styleIndex > -1 && styleIndex <= len(styles.CellXfs) {
+		xf := styles.CellXfs[styleIndex]
+		numFmt := numFmtRefTable[xf.NumFmtId]
+		numberFormat = numFmt.FormatCode
+	}
+	return strings.ToLower(numberFormat)
+}
+
+func (styles *xlsxStyles) addFont(xFont xlsxFont) {
+	styles.Fonts = append(styles.Fonts, xFont)
+}
+
+func (styles *xlsxStyles) addFill(xFill xlsxFill) {
+	styles.Fills = append(styles.Fills, xFill)
+}
+
+func (styles *xlsxStyles) addBorder(xBorder xlsxBorder) {
+	styles.Borders = append(styles.Borders, xBorder)
+}
+
+func (styles *xlsxStyles) addCellStyleXfs(xCellStyleXf xlsxXf) {
+	styles.CellStyleXfs = append(styles.CellStyleXfs, xCellStyleXf)
+}
+
+func (styles *xlsxStyles) addCellXf(xCellXf xlsxXf) {
+	styles.CellXfs = append(styles.CellXfs, xCellXf)
+}