Browse Source

reduce memory usage

Yoshiki Shibukawa 11 years ago
parent
commit
8e750645ea
10 changed files with 44 additions and 31 deletions
  1. 6 6
      cell.go
  2. 5 5
      cell_test.go
  3. 2 2
      file.go
  4. 1 1
      file_test.go
  5. 1 1
      lib.go
  6. 1 1
      row.go
  7. 1 1
      sheet.go
  8. 6 6
      sheet_test.go
  9. 15 2
      xmlStyle.go
  10. 6 6
      xmlStyle_test.go

+ 6 - 6
cell.go

@@ -20,10 +20,10 @@ const (
 // Cell is a high level structure intended to provide user access to
 // the contents of Cell within an xlsx.Row.
 type Cell struct {
-	Row      Row
+	Row      *Row
 	Value    string
 	formula  string
-	style    Style
+	style    *Style
 	numFmt   string
 	date1904 bool
 	Hidden   bool
@@ -36,8 +36,8 @@ type CellInterface interface {
 	FormattedValue() string
 }
 
-func NewCell(r Row) *Cell {
-	return &Cell{style: *NewStyle(), Row: r}
+func NewCell(r *Row) *Cell {
+	return &Cell{style: NewStyle(), Row: r}
 }
 
 func (c *Cell) Type() CellType {
@@ -134,12 +134,12 @@ func (c *Cell) Formula() string {
 }
 
 // GetStyle returns the Style associated with a Cell
-func (c *Cell) GetStyle() Style {
+func (c *Cell) GetStyle() *Style {
 	return c.style
 }
 
 // SetStyle sets the style of a cell.
-func (c *Cell) SetStyle(style Style) {
+func (c *Cell) SetStyle(style *Style) {
 	c.style = style
 }
 

+ 5 - 5
cell_test.go

@@ -22,7 +22,7 @@ func (s *CellSuite) TestValueSet(c *C) {
 // Test that GetStyle correctly converts the xlsxStyle.Fonts.
 func (s *CellSuite) TestGetStyleWithFonts(c *C) {
 	font := NewFont(10, "Calibra")
-	style := *NewStyle()
+	style := NewStyle()
 	style.Font = *font
 
 	cell := &Cell{Value: "123", style: style}
@@ -39,7 +39,7 @@ func (s *CellSuite) TestSetStyleWithFonts(c *C) {
 	row := sheet.AddRow()
 	cell := row.AddCell()
 	font := NewFont(12, "Calibra")
-	style := *NewStyle()
+	style := NewStyle()
 	style.Font = *font
 	cell.SetStyle(style)
 	style = cell.GetStyle()
@@ -51,7 +51,7 @@ func (s *CellSuite) TestSetStyleWithFonts(c *C) {
 // Test that GetStyle correctly converts the xlsxStyle.Fills.
 func (s *CellSuite) TestGetStyleWithFills(c *C) {
 	fill := *NewFill("solid", "FF000000", "00FF0000")
-	style := *NewStyle()
+	style := NewStyle()
 	style.Fill = fill
 	cell := &Cell{Value: "123", style: style}
 	style = cell.GetStyle()
@@ -68,7 +68,7 @@ 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)
 	style = cell.GetStyle()
@@ -82,7 +82,7 @@ func (s *CellSuite) TestSetStyleWithFills(c *C) {
 // Test that GetStyle correctly converts the xlsxStyle.Borders.
 func (s *CellSuite) TestGetStyleWithBorders(c *C) {
 	border := *NewBorder("thin", "thin", "thin", "thin")
-	style := *NewStyle()
+	style := NewStyle()
 	style.Border = border
 	cell := Cell{Value: "123", style: style}
 	style = cell.GetStyle()

+ 2 - 2
file.go

@@ -110,7 +110,7 @@ func (f *File) Write(writer io.Writer) (err error) {
 
 // Add a new Sheet, with the provided name, to a File
 func (f *File) AddSheet(sheetName string) (sheet *Sheet) {
-	sheet = &Sheet{Name: sheetName, File: *f}
+	sheet = &Sheet{Name: sheetName, File: f}
 	f.Sheet[sheetName] = sheet
 	f.Sheets = append(f.Sheets, sheet)
 	return sheet
@@ -170,7 +170,7 @@ func (f *File) MarshallParts() (map[string]string, error) {
 	sheetIndex := 1
 
 	if f.styles == nil {
-		f.styles = &xlsxStyleSheet{}
+		f.styles = newXlsxStyleSheet()
 	}
 	f.styles.reset()
 	for _, sheet := range f.Sheets {

+ 1 - 1
file_test.go

@@ -144,7 +144,7 @@ func (l *FileSuite) TestReadWorkbookRelationsFromZipFile(c *C) {
 func (l *FileSuite) TestGetStyleFromZipFile(c *C) {
 	var xlsxFile *File
 	var err error
-	var style Style
+	var style *Style
 
 	xlsxFile, err = OpenFile("./testdocs/testfile.xlsx")
 	c.Assert(err, IsNil)

+ 1 - 1
lib.go

@@ -545,7 +545,7 @@ func readStylesFromZipFile(f *zip.File) (*xlsxStyleSheet, error) {
 	if error != nil {
 		return nil, error
 	}
-	style = new(xlsxStyleSheet)
+	style = newXlsxStyleSheet()
 	decoder = xml.NewDecoder(rc)
 	error = decoder.Decode(style)
 	if error != nil {

+ 1 - 1
row.go

@@ -7,7 +7,7 @@ type Row struct {
 }
 
 func (r *Row) AddCell() *Cell {
-	cell := NewCell(*r)
+	cell := NewCell(r)
 	r.Cells = append(r.Cells, cell)
 	r.Sheet.maybeAddCol(len(r.Cells))
 	return cell

+ 1 - 1
sheet.go

@@ -9,7 +9,7 @@ import (
 // the contents of a particular sheet within an XLSX file.
 type Sheet struct {
 	Name   string
-	File   File
+	File   *File
 	Rows   []*Row
 	Cols   []*Col
 	MaxRow int

+ 6 - 6
sheet_test.go

@@ -28,7 +28,7 @@ func (s *SheetSuite) TestMakeXLSXSheetFromRows(c *C) {
 	cell := row.AddCell()
 	cell.Value = "A cell!"
 	refTable := NewSharedStringRefTable()
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	xSheet := sheet.makeXLSXSheet(refTable, styles)
 	c.Assert(xSheet.Dimension.Ref, Equals, "A1")
 	c.Assert(xSheet.SheetData.Row, HasLen, 1)
@@ -58,7 +58,7 @@ func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
 
 	cell1 := row.AddCell()
 	cell1.Value = "A cell!"
-	style1 := *NewStyle()
+	style1 := NewStyle()
 	style1.Font = *NewFont(10, "Verdana")
 	style1.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
 	style1.Border = *NewBorder("none", "thin", "none", "thin")
@@ -67,14 +67,14 @@ func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
 	// We need a second style to check that Xfs are populated correctly.
 	cell2 := row.AddCell()
 	cell2.Value = "Another cell!"
-	style2 := *NewStyle()
+	style2 := NewStyle()
 	style2.Font = *NewFont(10, "Verdana")
 	style2.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
 	style2.Border = *NewBorder("none", "thin", "none", "thin")
 	cell2.SetStyle(style2)
 
 	refTable := NewSharedStringRefTable()
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	worksheet := sheet.makeXLSXSheet(refTable, styles)
 
 	c.Assert(styles.Fonts.Count, Equals, 1)
@@ -116,7 +116,7 @@ func (s *SheetSuite) TestMarshalSheet(c *C) {
 	cell := row.AddCell()
 	cell.Value = "A cell!"
 	refTable := NewSharedStringRefTable()
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	xSheet := sheet.makeXLSXSheet(refTable, styles)
 
 	output := bytes.NewBufferString(xml.Header)
@@ -139,7 +139,7 @@ func (s *SheetSuite) TestMarshalSheetWithMultipleCells(c *C) {
 	cell = row.AddCell()
 	cell.Value = "A cell (with value 2)!"
 	refTable := NewSharedStringRefTable()
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	xSheet := sheet.makeXLSXSheet(refTable, styles)
 
 	output := bytes.NewBufferString(xml.Header)

+ 15 - 2
xmlStyle.go

@@ -31,6 +31,14 @@ type xlsxStyleSheet struct {
 	CellStyleXfs xlsxCellStyleXfs `xml:"cellStyleXfs,omitempty"`
 	CellXfs      xlsxCellXfs      `xml:"cellXfs,omitempty"`
 	NumFmts      xlsxNumFmts      `xml:"numFmts,omitempty"`
+
+    styleCache   map[int]*Style   `-`
+}
+
+func newXlsxStyleSheet() *xlsxStyleSheet {
+    stylesheet := new(xlsxStyleSheet)
+    stylesheet.styleCache = make(map[int]*Style)
+    return stylesheet
 }
 
 func (styles *xlsxStyleSheet) buildNumFmtRefTable() (numFmtRefTable map[int]xlsxNumFmt) {
@@ -50,9 +58,13 @@ func (styles *xlsxStyleSheet) reset() {
 	styles.NumFmts = xlsxNumFmts{}
 }
 
-func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style Style) {
+func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style *Style) {
+    style, ok := styles.styleCache[styleIndex]
+    if ok {
+        return
+    }
 	var styleXf xlsxXf
-	style = Style{}
+	style = &Style{}
 	style.Border = Border{}
 	style.Fill = Fill{}
 	style.Font = Font{}
@@ -96,6 +108,7 @@ func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style Style) {
 			style.Font.Family, _ = strconv.Atoi(xfont.Family.Val)
 			style.Font.Charset, _ = strconv.Atoi(xfont.Charset.Val)
 		}
+        styles.styleCache[styleIndex] = style
 	}
 	return style
 

+ 6 - 6
xmlStyle_test.go

@@ -10,7 +10,7 @@ var _ = Suite(&XMLStyleSuite{})
 
 // Test we produce valid output for an empty style file.
 func (x *XMLStyleSuite) TestMarshalEmptyXlsxStyleSheet(c *C) {
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	result, err := styles.Marshal()
 	c.Assert(err, IsNil)
 	c.Assert(string(result), Equals, `<?xml version="1.0" encoding="UTF-8"?>
@@ -19,7 +19,7 @@ func (x *XMLStyleSuite) TestMarshalEmptyXlsxStyleSheet(c *C) {
 
 // Test we produce valid output for a style file with one font definition.
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithAFont(c *C) {
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	styles.Fonts = xlsxFonts{}
 	styles.Fonts.Count = 1
 	styles.Fonts.Font = make([]xlsxFont, 1)
@@ -37,7 +37,7 @@ func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithAFont(c *C) {
 
 // Test we produce valid output for a style file with one fill definition.
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithAFill(c *C) {
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	styles.Fills = xlsxFills{}
 	styles.Fills.Count = 1
 	styles.Fills.Fill = make([]xlsxFill, 1)
@@ -58,7 +58,7 @@ func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithAFill(c *C) {
 
 // Test we produce valid output for a style file with one border definition.
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithABorder(c *C) {
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	styles.Borders = xlsxBorders{}
 	styles.Borders.Count = 1
 	styles.Borders.Border = make([]xlsxBorder, 1)
@@ -76,7 +76,7 @@ func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithABorder(c *C) {
 
 // Test we produce valid output for a style file with one cellStyleXf definition.
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellStyleXf(c *C) {
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	styles.CellStyleXfs = xlsxCellStyleXfs{}
 	styles.CellStyleXfs.Count = 1
 	styles.CellStyleXfs.Xf = make([]xlsxXf, 1)
@@ -109,7 +109,7 @@ func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellStyleXf(c *C) {
 // Test we produce valid output for a style file with one cellXf
 // definition.
 func (x *XMLStyleSuite) TestMarshalXlsxStyleSheetWithACellXf(c *C) {
-	styles := &xlsxStyleSheet{}
+	styles := newXlsxStyleSheet()
 	styles.CellXfs = xlsxCellXfs{}
 	styles.CellXfs.Count = 1
 	styles.CellXfs.Xf = make([]xlsxXf, 1)