浏览代码

#625, support setting formula for cell in streaming API

xuri 4 年之前
父节点
当前提交
7e12b560ce
共有 4 个文件被更改,包括 55 次插入26 次删除
  1. 3 3
      chart.go
  2. 30 1
      stream.go
  3. 2 2
      stream_test.go
  4. 20 20
      xmlChartSheet.go

+ 3 - 3
chart.go

@@ -1,4 +1,4 @@
-// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2021 The excelize Authors. All rights reserved. Use of
 // this source code is governed by a BSD-style license that can be found in
 // this source code is governed by a BSD-style license that can be found in
 // the LICENSE file.
 // the LICENSE file.
 //
 //
@@ -923,8 +923,8 @@ func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
 		return err
 		return err
 	}
 	}
 	cs := xlsxChartsheet{
 	cs := xlsxChartsheet{
-		SheetViews: []*xlsxChartsheetViews{{
-			SheetView: []*xlsxChartsheetView{{ZoomScaleAttr: 100, ZoomToFitAttr: true}}},
+		SheetViews: &xlsxChartsheetViews{
+			SheetView: []*xlsxChartsheetView{{ZoomScaleAttr: 100, ZoomToFitAttr: true}},
 		},
 		},
 	}
 	}
 	f.SheetCount++
 	f.SheetCount++

+ 30 - 1
stream.go

@@ -71,6 +71,13 @@ type StreamWriter struct {
 //        fmt.Println(err)
 //        fmt.Println(err)
 //    }
 //    }
 //
 //
+// Set cell value and cell formula for a worksheet with stream writer:
+//
+//    err := streamWriter.SetRow("A1", []interface{}{
+//        excelize.Cell{Value: 1},
+//        excelize.Cell{Value: 2},
+//        excelize.Cell{Formula: "SUM(A1,B1)"}});
+//
 func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
 func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
 	sheetID := f.getSheetID(sheet)
 	sheetID := f.getSheetID(sheet)
 	if sheetID == -1 {
 	if sheetID == -1 {
@@ -106,7 +113,14 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
 //
 //
 // Create a table of F2:H6 with format set:
 // Create a table of F2:H6 with format set:
 //
 //
-//    err := sw.AddTable("F2", "H6", `{"table_name":"table","table_style":"TableStyleMedium2","show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
+//    err := sw.AddTable("F2", "H6", `{
+//        "table_name": "table",
+//        "table_style": "TableStyleMedium2",
+//        "show_first_column": true,
+//        "show_last_column": true,
+//        "show_row_stripes": false,
+//        "show_column_stripes": true
+//    }`)
 //
 //
 // Note that the table must be at least two lines including the header. The
 // Note that the table must be at least two lines including the header. The
 // header cells must contain strings and must be unique.
 // header cells must contain strings and must be unique.
@@ -266,6 +280,7 @@ func getRowElement(token xml.Token, hrow int) (startElement xml.StartElement, ok
 // a value.
 // a value.
 type Cell struct {
 type Cell struct {
 	StyleID int
 	StyleID int
+	Formula string
 	Value   interface{}
 	Value   interface{}
 }
 }
 
 
@@ -291,9 +306,11 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}) error {
 		if v, ok := val.(Cell); ok {
 		if v, ok := val.(Cell); ok {
 			c.S = v.StyleID
 			c.S = v.StyleID
 			val = v.Value
 			val = v.Value
+			setCellFormula(&c, v.Formula)
 		} else if v, ok := val.(*Cell); ok && v != nil {
 		} else if v, ok := val.(*Cell); ok && v != nil {
 			c.S = v.StyleID
 			c.S = v.StyleID
 			val = v.Value
 			val = v.Value
+			setCellFormula(&c, v.Formula)
 		}
 		}
 		if err = setCellValFunc(&c, val); err != nil {
 		if err = setCellValFunc(&c, val); err != nil {
 			_, _ = sw.rawData.WriteString(`</row>`)
 			_, _ = sw.rawData.WriteString(`</row>`)
@@ -305,6 +322,13 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}) error {
 	return sw.rawData.Sync()
 	return sw.rawData.Sync()
 }
 }
 
 
+// setCellFormula provides a function to set formula of a cell.
+func setCellFormula(c *xlsxC, formula string) {
+	if formula != "" {
+		c.F = &xlsxF{Content: formula}
+	}
+}
+
 // setCellValFunc provides a function to set value of a cell.
 // setCellValFunc provides a function to set value of a cell.
 func setCellValFunc(c *xlsxC, val interface{}) (err error) {
 func setCellValFunc(c *xlsxC, val interface{}) (err error) {
 	switch val := val.(type) {
 	switch val := val.(type) {
@@ -373,6 +397,11 @@ func writeCell(buf *bufferedWriter, c xlsxC) {
 		fmt.Fprintf(buf, ` t="%s"`, c.T)
 		fmt.Fprintf(buf, ` t="%s"`, c.T)
 	}
 	}
 	_, _ = buf.WriteString(`>`)
 	_, _ = buf.WriteString(`>`)
+	if c.F != nil {
+		_, _ = buf.WriteString(`<f>`)
+		_ = xml.EscapeText(buf, []byte(c.F.Content))
+		_, _ = buf.WriteString(`</f>`)
+	}
 	if c.V != "" {
 	if c.V != "" {
 		_, _ = buf.WriteString(`<v>`)
 		_, _ = buf.WriteString(`<v>`)
 		_ = xml.EscapeText(buf, []byte(c.V))
 		_ = xml.EscapeText(buf, []byte(c.V))

+ 2 - 2
stream_test.go

@@ -55,8 +55,8 @@ func TestStreamWriter(t *testing.T) {
 	// Test set cell with style.
 	// Test set cell with style.
 	styleID, err := file.NewStyle(`{"font":{"color":"#777777"}}`)
 	styleID, err := file.NewStyle(`{"font":{"color":"#777777"}}`)
 	assert.NoError(t, err)
 	assert.NoError(t, err)
-	assert.NoError(t, streamWriter.SetRow("A4", []interface{}{Cell{StyleID: styleID}}))
-	assert.NoError(t, streamWriter.SetRow("A5", []interface{}{&Cell{StyleID: styleID, Value: "cell"}}))
+	assert.NoError(t, streamWriter.SetRow("A4", []interface{}{Cell{StyleID: styleID}, Cell{Formula: "SUM(A10,B10)"}}))
+	assert.NoError(t, streamWriter.SetRow("A5", []interface{}{&Cell{StyleID: styleID, Value: "cell"}, &Cell{Formula: "SUM(A10,B10)"}}))
 	assert.EqualError(t, streamWriter.SetRow("A6", []interface{}{time.Now()}), "only UTC time expected")
 	assert.EqualError(t, streamWriter.SetRow("A6", []interface{}{time.Now()}), "only UTC time expected")
 
 
 	for rowID := 10; rowID <= 51200; rowID++ {
 	for rowID := 10; rowID <= 51200; rowID++ {

+ 20 - 20
xmlChartSheet.go

@@ -1,4 +1,4 @@
-// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2021 The excelize Authors. All rights reserved. Use of
 // this source code is governed by a BSD-style license that can be found in
 // this source code is governed by a BSD-style license that can be found in
 // the LICENSE file.
 // the LICENSE file.
 //
 //
@@ -16,27 +16,27 @@ import "encoding/xml"
 // xlsxChartsheet directly maps the chartsheet element of Chartsheet Parts in
 // xlsxChartsheet directly maps the chartsheet element of Chartsheet Parts in
 // a SpreadsheetML document.
 // a SpreadsheetML document.
 type xlsxChartsheet struct {
 type xlsxChartsheet struct {
-	XMLName          xml.Name                     `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main chartsheet"`
-	SheetPr          []*xlsxChartsheetPr          `xml:"sheetPr"`
-	SheetViews       []*xlsxChartsheetViews       `xml:"sheetViews"`
-	SheetProtection  []*xlsxChartsheetProtection  `xml:"sheetProtection"`
-	CustomSheetViews []*xlsxCustomChartsheetViews `xml:"customSheetViews"`
-	PageMargins      *xlsxPageMargins             `xml:"pageMargins"`
-	PageSetup        []*xlsxPageSetUp             `xml:"pageSetup"`
-	HeaderFooter     *xlsxHeaderFooter            `xml:"headerFooter"`
-	Drawing          *xlsxDrawing                 `xml:"drawing"`
-	DrawingHF        []*xlsxDrawingHF             `xml:"drawingHF"`
-	Picture          []*xlsxPicture               `xml:"picture"`
-	WebPublishItems  []*xlsxInnerXML              `xml:"webPublishItems"`
-	ExtLst           []*xlsxExtLst                `xml:"extLst"`
+	XMLName          xml.Name                   `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main chartsheet"`
+	SheetPr          *xlsxChartsheetPr          `xml:"sheetPr"`
+	SheetViews       *xlsxChartsheetViews       `xml:"sheetViews"`
+	SheetProtection  *xlsxChartsheetProtection  `xml:"sheetProtection"`
+	CustomSheetViews *xlsxCustomChartsheetViews `xml:"customSheetViews"`
+	PageMargins      *xlsxPageMargins           `xml:"pageMargins"`
+	PageSetup        *xlsxPageSetUp             `xml:"pageSetup"`
+	HeaderFooter     *xlsxHeaderFooter          `xml:"headerFooter"`
+	Drawing          *xlsxDrawing               `xml:"drawing"`
+	DrawingHF        *xlsxDrawingHF             `xml:"drawingHF"`
+	Picture          *xlsxPicture               `xml:"picture"`
+	WebPublishItems  *xlsxInnerXML              `xml:"webPublishItems"`
+	ExtLst           *xlsxExtLst                `xml:"extLst"`
 }
 }
 
 
 // xlsxChartsheetPr specifies chart sheet properties.
 // xlsxChartsheetPr specifies chart sheet properties.
 type xlsxChartsheetPr struct {
 type xlsxChartsheetPr struct {
-	XMLName       xml.Name        `xml:"sheetPr"`
-	PublishedAttr bool            `xml:"published,attr,omitempty"`
-	CodeNameAttr  string          `xml:"codeName,attr,omitempty"`
-	TabColor      []*xlsxTabColor `xml:"tabColor"`
+	XMLName       xml.Name      `xml:"sheetPr"`
+	PublishedAttr bool          `xml:"published,attr,omitempty"`
+	CodeNameAttr  string        `xml:"codeName,attr,omitempty"`
+	TabColor      *xlsxTabColor `xml:"tabColor"`
 }
 }
 
 
 // xlsxChartsheetViews specifies chart sheet views.
 // xlsxChartsheetViews specifies chart sheet views.
@@ -71,13 +71,13 @@ type xlsxChartsheetProtection struct {
 // xlsxCustomChartsheetViews collection of custom Chart Sheet View
 // xlsxCustomChartsheetViews collection of custom Chart Sheet View
 // information.
 // information.
 type xlsxCustomChartsheetViews struct {
 type xlsxCustomChartsheetViews struct {
-	XMLName         xml.Name                    `xml:"customChartsheetViews"`
+	XMLName         xml.Name                    `xml:"customSheetViews"`
 	CustomSheetView []*xlsxCustomChartsheetView `xml:"customSheetView"`
 	CustomSheetView []*xlsxCustomChartsheetView `xml:"customSheetView"`
 }
 }
 
 
 // xlsxCustomChartsheetView defines custom view properties for chart sheets.
 // xlsxCustomChartsheetView defines custom view properties for chart sheets.
 type xlsxCustomChartsheetView struct {
 type xlsxCustomChartsheetView struct {
-	XMLName       xml.Name            `xml:"customChartsheetView"`
+	XMLName       xml.Name            `xml:"customSheetView"`
 	GUIDAttr      string              `xml:"guid,attr"`
 	GUIDAttr      string              `xml:"guid,attr"`
 	ScaleAttr     uint32              `xml:"scale,attr,omitempty"`
 	ScaleAttr     uint32              `xml:"scale,attr,omitempty"`
 	StateAttr     string              `xml:"state,attr,omitempty"`
 	StateAttr     string              `xml:"state,attr,omitempty"`