Using the specialized name in a variable and making comments clear

- Add JSON tags for `AppProperties`, `PivotTableOption` and `PivotTableField` structure
This commit is contained in:
xuri 2022-09-18 00:07:15 +08:00
parent 73cc4bd449
commit 3f702999e6
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
31 changed files with 470 additions and 470 deletions

View File

@ -248,8 +248,8 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
}
// adjustAutoFilterHelper provides a function for adjusting auto filter to
// compare and calculate cell axis by the given adjust direction, operation
// axis and offset.
// compare and calculate cell reference by the given adjust direction, operation
// reference and offset.
func (f *File) adjustAutoFilterHelper(dir adjustDirection, coordinates []int, num, offset int) []int {
if dir == rows {
if coordinates[1] >= num {
@ -314,7 +314,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
}
// adjustMergeCellsHelper provides a function for adjusting merge cells to
// compare and calculate cell axis by the given pivot, operation axis and
// compare and calculate cell reference by the given pivot, operation reference and
// offset.
func (f *File) adjustMergeCellsHelper(p1, p2, num, offset int) (int, int) {
if p2 < p1 {

View File

@ -10,7 +10,7 @@ import (
func TestAdjustMergeCells(t *testing.T) {
f := NewFile()
// testing adjustAutoFilter with illegal cell coordinates.
// testing adjustAutoFilter with illegal cell reference.
assert.EqualError(t, f.adjustMergeCells(&xlsxWorksheet{
MergeCells: &xlsxMergeCells{
Cells: []*xlsxMergeCell{
@ -283,7 +283,7 @@ func TestAdjustAutoFilter(t *testing.T) {
Ref: "A1:A3",
},
}, rows, 1, -1))
// Test adjustAutoFilter with illegal cell coordinates.
// Test adjustAutoFilter with illegal cell reference.
assert.EqualError(t, f.adjustAutoFilter(&xlsxWorksheet{
AutoFilter: &xlsxAutoFilter{
Ref: "A:B1",
@ -335,7 +335,7 @@ func TestAdjustHelper(t *testing.T) {
f.Sheet.Store("xl/worksheets/sheet2.xml", &xlsxWorksheet{
AutoFilter: &xlsxAutoFilter{Ref: "A1:B"},
})
// Test adjustHelper with illegal cell coordinates.
// Test adjustHelper with illegal cell reference.
assert.EqualError(t, f.adjustHelper("Sheet1", rows, 0, 0), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.EqualError(t, f.adjustHelper("Sheet2", rows, 0, 0), newCellNameToCoordinatesError("B", newInvalidCellNameError("B")).Error())
// Test adjustHelper on not exists worksheet.

View File

@ -1408,7 +1408,7 @@ func (f *File) parseReference(ctx *calcContext, sheet, reference string) (arg fo
cr := cellRef{}
if len(tokens) == 2 { // have a worksheet name
cr.Sheet = tokens[0]
// cast to cell coordinates
// cast to cell reference
if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[1]); err != nil {
// cast to column
if cr.Col, err = ColumnNameToNumber(tokens[1]); err != nil {
@ -1428,7 +1428,7 @@ func (f *File) parseReference(ctx *calcContext, sheet, reference string) (arg fo
refs.PushBack(cr)
continue
}
// cast to cell coordinates
// cast to cell reference
if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[0]); err != nil {
// cast to column
if cr.Col, err = ColumnNameToNumber(tokens[0]); err != nil {

View File

@ -45,11 +45,11 @@ func (f *File) calcChainWriter() {
// deleteCalcChain provides a function to remove cell reference on the
// calculation chain.
func (f *File) deleteCalcChain(index int, axis string) {
func (f *File) deleteCalcChain(index int, cell string) {
calc := f.calcChainReader()
if calc != nil {
calc.C = xlsxCalcChainCollection(calc.C).Filter(func(c xlsxCalcChainC) bool {
return !((c.I == index && c.R == axis) || (c.I == index && axis == "") || (c.I == 0 && c.R == axis))
return !((c.I == index && c.R == cell) || (c.I == index && cell == "") || (c.I == 0 && c.R == cell))
})
}
if len(calc.C) == 0 {

271
cell.go
View File

@ -57,26 +57,27 @@ var cellTypes = map[string]CellType{
}
// GetCellValue provides a function to get formatted value from cell by given
// worksheet name and axis in spreadsheet file. If it is possible to apply a
// format to the cell value, it will do so, if not then an error will be
// returned, along with the raw value of the cell. All cells' values will be
// the same in a merged range. This function is concurrency safe.
func (f *File) GetCellValue(sheet, axis string, opts ...Options) (string, error) {
return f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
// worksheet name and cell reference in spreadsheet. The return value is
// converted to the 'string' data type. This function is concurrency safe. If
// the cell format can be applied to the value of a cell, the applied value
// will be returned, otherwise the original value will be returned. All cells'
// values will be the same in a merged range.
func (f *File) GetCellValue(sheet, cell string, opts ...Options) (string, error) {
return f.getCellStringFunc(sheet, cell, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
val, err := c.getValueFrom(f, f.sharedStringsReader(), parseOptions(opts...).RawCellValue)
return val, true, err
})
}
// GetCellType provides a function to get the cell's data type by given
// worksheet name and axis in spreadsheet file.
func (f *File) GetCellType(sheet, axis string) (CellType, error) {
// worksheet name and cell reference in spreadsheet file.
func (f *File) GetCellType(sheet, cell string) (CellType, error) {
var (
err error
cellTypeStr string
cellType CellType
)
if cellTypeStr, err = f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
if cellTypeStr, err = f.getCellStringFunc(sheet, cell, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
return c.T, true, nil
}); err != nil {
return CellTypeUnset, err
@ -110,39 +111,39 @@ func (f *File) GetCellType(sheet, axis string) (CellType, error) {
// nil
//
// Note that default date format is m/d/yy h:mm of time.Time type value. You
// can set numbers format by SetCellStyle() method. If you need to set the
// can set numbers format by the SetCellStyle function. If you need to set the
// specialized date in Excel like January 0, 1900 or February 29, 1900, these
// times can not representation in Go language time.Time data type. Please set
// the cell value as number 0 or 60, then create and bind the date-time number
// format style for the cell.
func (f *File) SetCellValue(sheet, axis string, value interface{}) error {
func (f *File) SetCellValue(sheet, cell string, value interface{}) error {
var err error
switch v := value.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
err = f.setCellIntFunc(sheet, axis, v)
err = f.setCellIntFunc(sheet, cell, v)
case float32:
err = f.SetCellFloat(sheet, axis, float64(v), -1, 32)
err = f.SetCellFloat(sheet, cell, float64(v), -1, 32)
case float64:
err = f.SetCellFloat(sheet, axis, v, -1, 64)
err = f.SetCellFloat(sheet, cell, v, -1, 64)
case string:
err = f.SetCellStr(sheet, axis, v)
err = f.SetCellStr(sheet, cell, v)
case []byte:
err = f.SetCellStr(sheet, axis, string(v))
err = f.SetCellStr(sheet, cell, string(v))
case time.Duration:
_, d := setCellDuration(v)
err = f.SetCellDefault(sheet, axis, d)
err = f.SetCellDefault(sheet, cell, d)
if err != nil {
return err
}
err = f.setDefaultTimeStyle(sheet, axis, 21)
err = f.setDefaultTimeStyle(sheet, cell, 21)
case time.Time:
err = f.setCellTimeFunc(sheet, axis, v)
err = f.setCellTimeFunc(sheet, cell, v)
case bool:
err = f.SetCellBool(sheet, axis, v)
err = f.SetCellBool(sheet, cell, v)
case nil:
err = f.SetCellDefault(sheet, axis, "")
err = f.SetCellDefault(sheet, cell, "")
default:
err = f.SetCellStr(sheet, axis, fmt.Sprint(value))
err = f.SetCellStr(sheet, cell, fmt.Sprint(value))
}
return err
}
@ -188,58 +189,58 @@ func (f *File) removeFormula(c *xlsxC, ws *xlsxWorksheet, sheet string) {
}
// setCellIntFunc is a wrapper of SetCellInt.
func (f *File) setCellIntFunc(sheet, axis string, value interface{}) error {
func (f *File) setCellIntFunc(sheet, cell string, value interface{}) error {
var err error
switch v := value.(type) {
case int:
err = f.SetCellInt(sheet, axis, v)
err = f.SetCellInt(sheet, cell, v)
case int8:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case int16:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case int32:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case int64:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case uint:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case uint8:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case uint16:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case uint32:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
case uint64:
err = f.SetCellInt(sheet, axis, int(v))
err = f.SetCellInt(sheet, cell, int(v))
}
return err
}
// setCellTimeFunc provides a method to process time type of value for
// SetCellValue.
func (f *File) setCellTimeFunc(sheet, axis string, value time.Time) error {
func (f *File) setCellTimeFunc(sheet, cell string, value time.Time) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
ws.Lock()
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
c.S = f.prepareCellStyle(ws, col, row, c.S)
ws.Unlock()
date1904, wb := false, f.workbookReader()
if wb != nil && wb.WorkbookPr != nil {
date1904 = wb.WorkbookPr.Date1904
}
var isNum bool
cellData.T, cellData.V, isNum, err = setCellTime(value, date1904)
c.T, c.V, isNum, err = setCellTime(value, date1904)
if err != nil {
return err
}
if isNum {
_ = f.setDefaultTimeStyle(sheet, axis, 22)
_ = f.setDefaultTimeStyle(sheet, cell, 22)
}
return err
}
@ -270,22 +271,22 @@ func setCellDuration(value time.Duration) (t string, v string) {
}
// SetCellInt provides a function to set int type value of a cell by given
// worksheet name, cell coordinates and cell value.
func (f *File) SetCellInt(sheet, axis string, value int) error {
// worksheet name, cell reference and cell value.
func (f *File) SetCellInt(sheet, cell string, value int) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
ws.Lock()
defer ws.Unlock()
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
cellData.T, cellData.V = setCellInt(value)
cellData.IS = nil
f.removeFormula(cellData, ws, sheet)
c.S = f.prepareCellStyle(ws, col, row, c.S)
c.T, c.V = setCellInt(value)
c.IS = nil
f.removeFormula(c, ws, sheet)
return err
}
@ -297,22 +298,22 @@ func setCellInt(value int) (t string, v string) {
}
// SetCellBool provides a function to set bool type value of a cell by given
// worksheet name, cell name and cell value.
func (f *File) SetCellBool(sheet, axis string, value bool) error {
// worksheet name, cell reference and cell value.
func (f *File) SetCellBool(sheet, cell string, value bool) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
ws.Lock()
defer ws.Unlock()
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
cellData.T, cellData.V = setCellBool(value)
cellData.IS = nil
f.removeFormula(cellData, ws, sheet)
c.S = f.prepareCellStyle(ws, col, row, c.S)
c.T, c.V = setCellBool(value)
c.IS = nil
f.removeFormula(c, ws, sheet)
return err
}
@ -328,29 +329,29 @@ func setCellBool(value bool) (t string, v string) {
return
}
// SetCellFloat sets a floating point value into a cell. The precision parameter
// specifies how many places after the decimal will be shown while -1 is a
// special value that will use as many decimal places as necessary to
// represent the number. bitSize is 32 or 64 depending on if a float32 or
// float64 was originally used for the value. For Example:
// SetCellFloat sets a floating point value into a cell. The precision
// parameter specifies how many places after the decimal will be shown
// while -1 is a special value that will use as many decimal places as
// necessary to represent the number. bitSize is 32 or 64 depending on if a
// float32 or float64 was originally used for the value. For Example:
//
// var x float32 = 1.325
// f.SetCellFloat("Sheet1", "A1", float64(x), 2, 32)
func (f *File) SetCellFloat(sheet, axis string, value float64, precision, bitSize int) error {
func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSize int) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
ws.Lock()
defer ws.Unlock()
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
cellData.T, cellData.V = setCellFloat(value, precision, bitSize)
cellData.IS = nil
f.removeFormula(cellData, ws, sheet)
c.S = f.prepareCellStyle(ws, col, row, c.S)
c.T, c.V = setCellFloat(value, precision, bitSize)
c.IS = nil
f.removeFormula(c, ws, sheet)
return err
}
@ -363,21 +364,21 @@ func setCellFloat(value float64, precision, bitSize int) (t string, v string) {
// SetCellStr provides a function to set string type value of a cell. Total
// number of characters that a cell can contain 32767 characters.
func (f *File) SetCellStr(sheet, axis, value string) error {
func (f *File) SetCellStr(sheet, cell, value string) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
ws.Lock()
defer ws.Unlock()
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
cellData.T, cellData.V, err = f.setCellString(value)
cellData.IS = nil
f.removeFormula(cellData, ws, sheet)
c.S = f.prepareCellStyle(ws, col, row, c.S)
c.T, c.V, err = f.setCellString(value)
c.IS = nil
f.removeFormula(c, ws, sheet)
return err
}
@ -463,21 +464,21 @@ func setCellStr(value string) (t string, v string, ns xml.Attr) {
// SetCellDefault provides a function to set string type value of a cell as
// default format without escaping the cell.
func (f *File) SetCellDefault(sheet, axis, value string) error {
func (f *File) SetCellDefault(sheet, cell, value string) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
ws.Lock()
defer ws.Unlock()
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
cellData.T, cellData.V = setCellDefault(value)
cellData.IS = nil
f.removeFormula(cellData, ws, sheet)
c.S = f.prepareCellStyle(ws, col, row, c.S)
c.T, c.V = setCellDefault(value)
c.IS = nil
f.removeFormula(c, ws, sheet)
return err
}
@ -492,9 +493,9 @@ func setCellDefault(value string) (t string, v string) {
}
// GetCellFormula provides a function to get formula from cell by given
// worksheet name and axis in XLSX file.
func (f *File) GetCellFormula(sheet, axis string) (string, error) {
return f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
// worksheet name and cell reference in spreadsheet.
func (f *File) GetCellFormula(sheet, cell string) (string, error) {
return f.getCellStringFunc(sheet, cell, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
if c.F == nil {
return "", false, nil
}
@ -587,44 +588,44 @@ type FormulaOpts struct {
// fmt.Println(err)
// }
// }
func (f *File) SetCellFormula(sheet, axis, formula string, opts ...FormulaOpts) error {
func (f *File) SetCellFormula(sheet, cell, formula string, opts ...FormulaOpts) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
cellData, _, _, err := f.prepareCell(ws, axis)
c, _, _, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
if formula == "" {
cellData.F = nil
f.deleteCalcChain(f.getSheetID(sheet), axis)
c.F = nil
f.deleteCalcChain(f.getSheetID(sheet), cell)
return err
}
if cellData.F != nil {
cellData.F.Content = formula
if c.F != nil {
c.F.Content = formula
} else {
cellData.F = &xlsxF{Content: formula}
c.F = &xlsxF{Content: formula}
}
for _, o := range opts {
if o.Type != nil {
if *o.Type == STCellFormulaTypeDataTable {
for _, opt := range opts {
if opt.Type != nil {
if *opt.Type == STCellFormulaTypeDataTable {
return err
}
cellData.F.T = *o.Type
if cellData.F.T == STCellFormulaTypeShared {
if err = ws.setSharedFormula(*o.Ref); err != nil {
c.F.T = *opt.Type
if c.F.T == STCellFormulaTypeShared {
if err = ws.setSharedFormula(*opt.Ref); err != nil {
return err
}
}
}
if o.Ref != nil {
cellData.F.Ref = *o.Ref
if opt.Ref != nil {
c.F.Ref = *opt.Ref
}
}
cellData.IS = nil
c.IS = nil
return err
}
@ -663,28 +664,28 @@ func (ws *xlsxWorksheet) countSharedFormula() (count int) {
}
// GetCellHyperLink gets a cell hyperlink based on the given worksheet name and
// cell coordinates. If the cell has a hyperlink, it will return 'true' and
// cell reference. If the cell has a hyperlink, it will return 'true' and
// the link address, otherwise it will return 'false' and an empty link
// address.
//
// For example, get a hyperlink to a 'H6' cell on a worksheet named 'Sheet1':
//
// link, target, err := f.GetCellHyperLink("Sheet1", "H6")
func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error) {
func (f *File) GetCellHyperLink(sheet, cell string) (bool, string, error) {
// Check for correct cell name
if _, _, err := SplitCellName(axis); err != nil {
if _, _, err := SplitCellName(cell); err != nil {
return false, "", err
}
ws, err := f.workSheetReader(sheet)
if err != nil {
return false, "", err
}
if axis, err = f.mergeCellsParser(ws, axis); err != nil {
if cell, err = f.mergeCellsParser(ws, cell); err != nil {
return false, "", err
}
if ws.Hyperlinks != nil {
for _, link := range ws.Hyperlinks.Hyperlink {
if link.Ref == axis {
if link.Ref == cell {
if link.RID != "" {
return true, f.getSheetRelationshipsTargetByID(sheet, link.RID), err
}
@ -731,9 +732,9 @@ type HyperlinkOpts struct {
// This is another example for "Location":
//
// err := f.SetCellHyperLink("Sheet1", "A3", "Sheet1!A40", "Location")
func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...HyperlinkOpts) error {
func (f *File) SetCellHyperLink(sheet, cell, link, linkType string, opts ...HyperlinkOpts) error {
// Check for correct cell name
if _, _, err := SplitCellName(axis); err != nil {
if _, _, err := SplitCellName(cell); err != nil {
return err
}
@ -741,7 +742,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
if err != nil {
return err
}
if axis, err = f.mergeCellsParser(ws, axis); err != nil {
if cell, err = f.mergeCellsParser(ws, cell); err != nil {
return err
}
@ -751,7 +752,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
ws.Hyperlinks = new(xlsxHyperlinks)
}
for i, hyperlink := range ws.Hyperlinks.Hyperlink {
if hyperlink.Ref == axis {
if hyperlink.Ref == cell {
idx = i
linkData = hyperlink
break
@ -768,13 +769,13 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.setRels(linkData.RID, sheetRels, SourceRelationshipHyperLink, link, linkType)
linkData = xlsxHyperlink{
Ref: axis,
Ref: cell,
}
linkData.RID = "rId" + strconv.Itoa(rID)
f.addSheetNameSpace(sheet, SourceRelationship)
case "Location":
linkData = xlsxHyperlink{
Ref: axis,
Ref: cell,
Location: link,
}
default:
@ -837,12 +838,12 @@ func (f *File) GetCellRichText(sheet, cell string) (runs []RichTextRun, err erro
if err != nil {
return
}
cellData, _, _, err := f.prepareCell(ws, cell)
c, _, _, err := f.prepareCell(ws, cell)
if err != nil {
return
}
siIdx, err := strconv.Atoi(cellData.V)
if err != nil || cellData.T != "s" {
siIdx, err := strconv.Atoi(c.V)
if err != nil || c.T != "s" {
return
}
sst := f.sharedStringsReader()
@ -1007,14 +1008,14 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
if err != nil {
return err
}
cellData, col, row, err := f.prepareCell(ws, cell)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return err
}
if err := f.sharedStringsLoader(); err != nil {
return err
}
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
c.S = f.prepareCellStyle(ws, col, row, c.S)
si := xlsxSI{}
sst := f.sharedStringsReader()
var textRuns []xlsxR
@ -1035,39 +1036,39 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
si.R = textRuns
for idx, strItem := range sst.SI {
if reflect.DeepEqual(strItem, si) {
cellData.T, cellData.V = "s", strconv.Itoa(idx)
c.T, c.V = "s", strconv.Itoa(idx)
return err
}
}
sst.SI = append(sst.SI, si)
sst.Count++
sst.UniqueCount++
cellData.T, cellData.V = "s", strconv.Itoa(len(sst.SI)-1)
c.T, c.V = "s", strconv.Itoa(len(sst.SI)-1)
return err
}
// SetSheetRow writes an array to row by given worksheet name, starting
// coordinate and a pointer to array type 'slice'. This function is
// cell reference and a pointer to array type 'slice'. This function is
// concurrency safe. For example, writes an array to row 6 start with the cell
// B6 on Sheet1:
//
// err := f.SetSheetRow("Sheet1", "B6", &[]interface{}{"1", nil, 2})
func (f *File) SetSheetRow(sheet, axis string, slice interface{}) error {
return f.setSheetCells(sheet, axis, slice, rows)
func (f *File) SetSheetRow(sheet, cell string, slice interface{}) error {
return f.setSheetCells(sheet, cell, slice, rows)
}
// SetSheetCol writes an array to column by given worksheet name, starting
// coordinate and a pointer to array type 'slice'. For example, writes an
// cell reference and a pointer to array type 'slice'. For example, writes an
// array to column B start with the cell B6 on Sheet1:
//
// err := f.SetSheetCol("Sheet1", "B6", &[]interface{}{"1", nil, 2})
func (f *File) SetSheetCol(sheet, axis string, slice interface{}) error {
return f.setSheetCells(sheet, axis, slice, columns)
func (f *File) SetSheetCol(sheet, cell string, slice interface{}) error {
return f.setSheetCells(sheet, cell, slice, columns)
}
// setSheetCells provides a function to set worksheet cells value.
func (f *File) setSheetCells(sheet, axis string, slice interface{}, dir adjustDirection) error {
col, row, err := CellNameToCoordinates(axis)
func (f *File) setSheetCells(sheet, cell string, slice interface{}, dir adjustDirection) error {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return err
}
@ -1117,16 +1118,16 @@ func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, er
// getCellStringFunc does common value extraction workflow for all GetCell*
// methods. Passed function implements specific part of required logic.
func (f *File) getCellStringFunc(sheet, axis string, fn func(x *xlsxWorksheet, c *xlsxC) (string, bool, error)) (string, error) {
func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c *xlsxC) (string, bool, error)) (string, error) {
ws, err := f.workSheetReader(sheet)
if err != nil {
return "", err
}
axis, err = f.mergeCellsParser(ws, axis)
cell, err = f.mergeCellsParser(ws, cell)
if err != nil {
return "", err
}
_, row, err := CellNameToCoordinates(axis)
_, row, err := CellNameToCoordinates(cell)
if err != nil {
return "", err
}
@ -1151,7 +1152,7 @@ func (f *File) getCellStringFunc(sheet, axis string, fn func(x *xlsxWorksheet, c
}
for colIdx := range rowData.C {
colData := &rowData.C[colIdx]
if axis != colData.R {
if cell != colData.R {
continue
}
val, ok, err := fn(ws, colData)
@ -1224,9 +1225,9 @@ func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
}
// mergeCellsParser provides a function to check merged cells in worksheet by
// given axis.
func (f *File) mergeCellsParser(ws *xlsxWorksheet, axis string) (string, error) {
axis = strings.ToUpper(axis)
// given cell reference.
func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error) {
cell = strings.ToUpper(cell)
if ws.MergeCells != nil {
for i := 0; i < len(ws.MergeCells.Cells); i++ {
if ws.MergeCells.Cells[i] == nil {
@ -1234,20 +1235,20 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, axis string) (string, error)
i--
continue
}
ok, err := f.checkCellInArea(axis, ws.MergeCells.Cells[i].Ref)
ok, err := f.checkCellInArea(cell, ws.MergeCells.Cells[i].Ref)
if err != nil {
return axis, err
return cell, err
}
if ok {
axis = strings.Split(ws.MergeCells.Cells[i].Ref, ":")[0]
cell = strings.Split(ws.MergeCells.Cells[i].Ref, ":")[0]
}
}
}
return axis, nil
return cell, nil
}
// checkCellInArea provides a function to determine if a given coordinate is
// within an area.
// checkCellInArea provides a function to determine if a given cell reference
// in a range.
func (f *File) checkCellInArea(cell, area string) (bool, error) {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
@ -1333,11 +1334,11 @@ func parseSharedFormula(dCol, dRow int, orig []byte) (res string, start int) {
//
// Note that this function not validate ref tag to check the cell whether in
// allow area, and always return origin shared formula.
func getSharedFormula(ws *xlsxWorksheet, si int, axis string) string {
func getSharedFormula(ws *xlsxWorksheet, si int, cell string) string {
for _, r := range ws.SheetData.Row {
for _, c := range r.C {
if c.F != nil && c.F.Ref != "" && c.F.T == STCellFormulaTypeShared && c.F.Si != nil && *c.F.Si == si {
col, row, _ := CellNameToCoordinates(axis)
col, row, _ := CellNameToCoordinates(cell)
sharedCol, sharedRow, _ := CellNameToCoordinates(c.R)
dCol := col - sharedCol
dRow := row - sharedRow

View File

@ -573,7 +573,7 @@ func TestGetCellRichText(t *testing.T) {
// Test set cell rich text on not exists worksheet
_, err = f.GetCellRichText("SheetN", "A1")
assert.EqualError(t, err, "sheet SheetN does not exist")
// Test set cell rich text with illegal cell coordinates
// Test set cell rich text with illegal cell reference
_, err = f.GetCellRichText("Sheet1", "A")
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
}
@ -670,7 +670,7 @@ func TestSetCellRichText(t *testing.T) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellRichText.xlsx")))
// Test set cell rich text on not exists worksheet
assert.EqualError(t, f.SetCellRichText("SheetN", "A1", richTextRun), "sheet SheetN does not exist")
// Test set cell rich text with illegal cell coordinates
// Test set cell rich text with illegal cell reference
assert.EqualError(t, f.SetCellRichText("Sheet1", "A", richTextRun), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
richTextRun = []RichTextRun{{Text: strings.Repeat("s", TotalCellChars+1)}}
// Test set cell rich text with characters over the maximum limit

View File

@ -984,8 +984,8 @@ func (f *File) getFormatChart(format string, combo []string) (*formatChart, []*f
return formatSet, comboCharts, err
}
// DeleteChart provides a function to delete chart in XLSX by given worksheet
// and cell name.
// DeleteChart provides a function to delete chart in spreadsheet by given
// worksheet name and cell reference.
func (f *File) DeleteChart(sheet, cell string) (err error) {
col, row, err := CellNameToCoordinates(cell)
if err != nil {

View File

@ -198,7 +198,7 @@ func TestAddChart(t *testing.T) {
assert.NoError(t, f.AddChart("Combo Charts", axis, fmt.Sprintf(`{"type":"areaStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"%s"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, props[1]), fmt.Sprintf(`{"type":"%s","series":[{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, props[0])))
}
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddChart.xlsx")))
// Test with illegal cell coordinates
// Test with illegal cell reference
assert.EqualError(t, f.AddChart("Sheet2", "A", `{"type":"col","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"2D Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
// Test with unsupported chart type
assert.EqualError(t, f.AddChart("Sheet2", "BD32", `{"type":"unknown","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Bubble 3D Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`), "unsupported chart type unknown")

View File

@ -207,7 +207,7 @@ func TestColumnVisibility(t *testing.T) {
_, err = f.GetColVisible("SheetN", "F")
assert.EqualError(t, err, "sheet SheetN does not exist")
// Test get column visible with illegal cell coordinates.
// Test get column visible with illegal cell reference.
_, err = f.GetColVisible("Sheet1", "*")
assert.EqualError(t, err, newInvalidColumnNameError("*").Error())
assert.EqualError(t, f.SetColVisible("Sheet1", "*", false), newInvalidColumnNameError("*").Error())
@ -258,7 +258,7 @@ func TestOutlineLevel(t *testing.T) {
_, err = f.GetRowOutlineLevel("SheetN", 1)
assert.EqualError(t, err, "sheet SheetN does not exist")
// Test set and get column outline level with illegal cell coordinates.
// Test set and get column outline level with illegal cell reference.
assert.EqualError(t, f.SetColOutlineLevel("Sheet1", "*", 1), newInvalidColumnNameError("*").Error())
_, err = f.GetColOutlineLevel("Sheet1", "*")
assert.EqualError(t, err, newInvalidColumnNameError("*").Error())
@ -329,7 +329,7 @@ func TestColWidth(t *testing.T) {
assert.Equal(t, defaultColWidth, width)
assert.NoError(t, err)
// Test set and get column width with illegal cell coordinates.
// Test set and get column width with illegal cell reference.
width, err = f.GetColWidth("Sheet1", "*")
assert.Equal(t, defaultColWidth, width)
assert.EqualError(t, err, newInvalidColumnNameError("*").Error())
@ -373,7 +373,7 @@ func TestInsertCols(t *testing.T) {
assert.NoError(t, f.AutoFilter(sheet1, "A2", "B2", `{"column":"B","expression":"x != blanks"}`))
assert.NoError(t, f.InsertCols(sheet1, "A", 1))
// Test insert column with illegal cell coordinates.
// Test insert column with illegal cell reference.
assert.EqualError(t, f.InsertCols(sheet1, "*", 1), newInvalidColumnNameError("*").Error())
assert.EqualError(t, f.InsertCols(sheet1, "A", 0), ErrColumnNumber.Error())
@ -398,7 +398,7 @@ func TestRemoveCol(t *testing.T) {
assert.NoError(t, f.RemoveCol(sheet1, "A"))
assert.NoError(t, f.RemoveCol(sheet1, "A"))
// Test remove column with illegal cell coordinates.
// Test remove column with illegal cell reference.
assert.EqualError(t, f.RemoveCol("Sheet1", "*"), newInvalidColumnNameError("*").Error())
// Test remove column on not exists worksheet.

View File

@ -141,7 +141,7 @@ func (f *File) AddComment(sheet, cell, format string) error {
}
// DeleteComment provides the method to delete comment in a sheet by given
// worksheet. For example, delete the comment in Sheet1!$A$30:
// worksheet name. For example, delete the comment in Sheet1!$A$30:
//
// err := f.DeleteComment("Sheet1", "A30")
func (f *File) DeleteComment(sheet, cell string) (err error) {

View File

@ -32,7 +32,7 @@ func TestAddComments(t *testing.T) {
// Test add comment on not exists worksheet.
assert.EqualError(t, f.AddComment("SheetN", "B7", `{"author":"Excelize: ","text":"This is a comment."}`), "sheet SheetN does not exist")
// Test add comment on with illegal cell coordinates
// Test add comment on with illegal cell reference
assert.EqualError(t, f.AddComment("Sheet1", "A", `{"author":"Excelize: ","text":"This is a comment."}`), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
if assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
assert.Len(t, f.GetComments(), 2)

View File

@ -139,7 +139,7 @@ type encryption struct {
// Decrypt API decrypts the CFB file format with ECMA-376 agile encryption and
// standard encryption. Support cryptographic algorithm: MD4, MD5, RIPEMD-160,
// SHA1, SHA256, SHA384 and SHA512 currently.
func Decrypt(raw []byte, opt *Options) (packageBuf []byte, err error) {
func Decrypt(raw []byte, opts *Options) (packageBuf []byte, err error) {
doc, err := mscfb.New(bytes.NewReader(raw))
if err != nil {
return
@ -150,13 +150,13 @@ func Decrypt(raw []byte, opt *Options) (packageBuf []byte, err error) {
return
}
if mechanism == "agile" {
return agileDecrypt(encryptionInfoBuf, encryptedPackageBuf, opt)
return agileDecrypt(encryptionInfoBuf, encryptedPackageBuf, opts)
}
return standardDecrypt(encryptionInfoBuf, encryptedPackageBuf, opt)
return standardDecrypt(encryptionInfoBuf, encryptedPackageBuf, opts)
}
// Encrypt API encrypt data with the password.
func Encrypt(raw []byte, opt *Options) ([]byte, error) {
func Encrypt(raw []byte, opts *Options) ([]byte, error) {
encryptor := encryption{
EncryptedVerifierHashInput: make([]byte, 16),
EncryptedVerifierHashValue: make([]byte, 32),
@ -166,7 +166,7 @@ func Encrypt(raw []byte, opt *Options) ([]byte, error) {
SaltSize: 16,
}
// Key Encryption
encryptionInfoBuffer, err := encryptor.standardKeyEncryption(opt.Password)
encryptionInfoBuffer, err := encryptor.standardKeyEncryption(opts.Password)
if err != nil {
return nil, err
}
@ -228,7 +228,7 @@ func encryptionMechanism(buffer []byte) (mechanism string, err error) {
// ECMA-376 Standard Encryption
// standardDecrypt decrypt the CFB file format with ECMA-376 standard encryption.
func standardDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options) ([]byte, error) {
func standardDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opts *Options) ([]byte, error) {
encryptionHeaderSize := binary.LittleEndian.Uint32(encryptionInfoBuf[8:12])
block := encryptionInfoBuf[12 : 12+encryptionHeaderSize]
header := StandardEncryptionHeader{
@ -254,7 +254,7 @@ func standardDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options
algorithm = "RC4"
}
verifier := standardEncryptionVerifier(algorithm, block)
secretKey, err := standardConvertPasswdToKey(header, verifier, opt)
secretKey, err := standardConvertPasswdToKey(header, verifier, opts)
if err != nil {
return nil, err
}
@ -289,9 +289,9 @@ func standardEncryptionVerifier(algorithm string, blob []byte) StandardEncryptio
}
// standardConvertPasswdToKey generate intermediate key from given password.
func standardConvertPasswdToKey(header StandardEncryptionHeader, verifier StandardEncryptionVerifier, opt *Options) ([]byte, error) {
func standardConvertPasswdToKey(header StandardEncryptionHeader, verifier StandardEncryptionVerifier, opts *Options) ([]byte, error) {
encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
passwordBuffer, err := encoder.Bytes([]byte(opt.Password))
passwordBuffer, err := encoder.Bytes([]byte(opts.Password))
if err != nil {
return nil, err
}
@ -395,13 +395,13 @@ func (e *encryption) standardKeyEncryption(password string) ([]byte, error) {
// agileDecrypt decrypt the CFB file format with ECMA-376 agile encryption.
// Support cryptographic algorithm: MD4, MD5, RIPEMD-160, SHA1, SHA256,
// SHA384 and SHA512.
func agileDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opt *Options) (packageBuf []byte, err error) {
func agileDecrypt(encryptionInfoBuf, encryptedPackageBuf []byte, opts *Options) (packageBuf []byte, err error) {
var encryptionInfo Encryption
if encryptionInfo, err = parseEncryptionInfo(encryptionInfoBuf[8:]); err != nil {
return
}
// Convert the password into an encryption key.
key, err := convertPasswdToKey(opt.Password, blockKey, encryptionInfo)
key, err := convertPasswdToKey(opts.Password, blockKey, encryptionInfo)
if err != nil {
return
}

View File

@ -98,12 +98,12 @@ type Options struct {
// }
//
// Close the file by Close function after opening the spreadsheet.
func OpenFile(filename string, opt ...Options) (*File, error) {
func OpenFile(filename string, opts ...Options) (*File, error) {
file, err := os.Open(filepath.Clean(filename))
if err != nil {
return nil, err
}
f, err := OpenReader(file, opt...)
f, err := OpenReader(file, opts...)
if err != nil {
closeErr := file.Close()
if closeErr == nil {
@ -188,11 +188,11 @@ func OpenReader(r io.Reader, opts ...Options) (*File, error) {
// parseOptions provides a function to parse the optional settings for open
// and reading spreadsheet.
func parseOptions(opts ...Options) *Options {
opt := &Options{}
for _, o := range opts {
opt = &o
options := &Options{}
for _, opt := range opts {
options = &opt
}
return opt
return options
}
// CharsetTranscoder Set user defined codepage transcoder function for open
@ -207,16 +207,16 @@ func (f *File) xmlNewDecoder(rdr io.Reader) (ret *xml.Decoder) {
}
// setDefaultTimeStyle provides a function to set default numbers format for
// time.Time type cell value by given worksheet name, cell coordinates and
// time.Time type cell value by given worksheet name, cell reference and
// number format code.
func (f *File) setDefaultTimeStyle(sheet, axis string, format int) error {
s, err := f.GetCellStyle(sheet, axis)
func (f *File) setDefaultTimeStyle(sheet, cell string, format int) error {
s, err := f.GetCellStyle(sheet, cell)
if err != nil {
return err
}
if s == 0 {
style, _ := f.NewStyle(&Style{NumFmt: format})
err = f.SetCellStyle(sheet, axis, axis, style)
err = f.SetCellStyle(sheet, cell, cell, style)
}
return err
}

View File

@ -165,7 +165,7 @@ func TestOpenFile(t *testing.T) {
assert.NoError(t, f.SetCellValue("Sheet2", "G5", time.Duration(1e13)))
// Test completion column.
assert.NoError(t, f.SetCellValue("Sheet2", "M2", nil))
// Test read cell value with given axis large than exists row.
// Test read cell value with given cell reference large than exists row.
_, err = f.GetCellValue("Sheet2", "E231")
assert.NoError(t, err)
// Test get active worksheet of spreadsheet and get worksheet name of spreadsheet by given worksheet index.
@ -336,7 +336,7 @@ func TestNewFile(t *testing.T) {
}
func TestAddDrawingVML(t *testing.T) {
// Test addDrawingVML with illegal cell coordinates.
// Test addDrawingVML with illegal cell reference.
f := NewFile()
assert.EqualError(t, f.addDrawingVML(0, "", "*", 0, 0), newCellNameToCoordinatesError("*", newInvalidCellNameError("*")).Error())
}

22
lib.go
View File

@ -261,7 +261,7 @@ func CellNameToCoordinates(cell string) (int, int, error) {
// excelize.CoordinatesToCellName(1, 1, true) // returns "$A$1", nil
func CoordinatesToCellName(col, row int, abs ...bool) (string, error) {
if col < 1 || row < 1 {
return "", fmt.Errorf("invalid cell coordinates [%d, %d]", col, row)
return "", fmt.Errorf("invalid cell reference [%d, %d]", col, row)
}
sign := ""
for _, a := range abs {
@ -273,7 +273,7 @@ func CoordinatesToCellName(col, row int, abs ...bool) (string, error) {
return sign + colName + sign + strconv.Itoa(row), err
}
// areaRefToCoordinates provides a function to convert area reference to a
// areaRefToCoordinates provides a function to convert range reference to a
// pair of coordinates.
func areaRefToCoordinates(ref string) ([]int, error) {
rng := strings.Split(strings.ReplaceAll(ref, "$", ""), ":")
@ -296,7 +296,7 @@ func areaRangeToCoordinates(firstCell, lastCell string) ([]int, error) {
return coordinates, err
}
// sortCoordinates provides a function to correct the coordinate area, such
// sortCoordinates provides a function to correct the cell range, such
// correct C1:B3 to B1:C3.
func sortCoordinates(coordinates []int) error {
if len(coordinates) != 4 {
@ -349,7 +349,7 @@ func (f *File) getDefinedNameRefTo(definedNameName string, currentSheet string)
return
}
// flatSqref convert reference sequence to cell coordinates list.
// flatSqref convert reference sequence to cell reference list.
func (f *File) flatSqref(sqref string) (cells map[int][][]int, err error) {
var coordinates []int
cells = make(map[int][][]int)
@ -524,14 +524,14 @@ func namespaceStrictToTransitional(content []byte) []byte {
return content
}
// bytesReplace replace old bytes with given new.
func bytesReplace(s, old, new []byte, n int) []byte {
// bytesReplace replace source bytes with given target.
func bytesReplace(s, source, target []byte, n int) []byte {
if n == 0 {
return s
}
if len(old) < len(new) {
return bytes.Replace(s, old, new, n)
if len(source) < len(target) {
return bytes.Replace(s, source, target, n)
}
if n < 0 {
@ -540,14 +540,14 @@ func bytesReplace(s, old, new []byte, n int) []byte {
var wid, i, j, w int
for i, j = 0, 0; i < len(s) && j < n; j++ {
wid = bytes.Index(s[i:], old)
wid = bytes.Index(s[i:], source)
if wid < 0 {
break
}
w += copy(s[w:], s[i:i+wid])
w += copy(s[w:], new)
i += wid + len(old)
w += copy(s[w:], target)
i += wid + len(source)
}
w += copy(s[w:], s[i:])

View File

@ -222,9 +222,9 @@ func TestCoordinatesToAreaRef(t *testing.T) {
_, err := f.coordinatesToAreaRef([]int{})
assert.EqualError(t, err, ErrCoordinates.Error())
_, err = f.coordinatesToAreaRef([]int{1, -1, 1, 1})
assert.EqualError(t, err, "invalid cell coordinates [1, -1]")
assert.EqualError(t, err, "invalid cell reference [1, -1]")
_, err = f.coordinatesToAreaRef([]int{1, 1, 1, -1})
assert.EqualError(t, err, "invalid cell coordinates [1, -1]")
assert.EqualError(t, err, "invalid cell reference [1, -1]")
ref, err := f.coordinatesToAreaRef([]int{1, 1, 1, 1})
assert.NoError(t, err)
assert.EqualValues(t, ref, "A1:A1")

View File

@ -22,7 +22,7 @@ func (mc *xlsxMergeCell) Rect() ([]int, error) {
return mc.rect, err
}
// MergeCell provides a function to merge cells by given coordinate area and
// MergeCell provides a function to merge cells by given range reference and
// sheet name. Merging cells only keeps the upper-left cell value, and
// discards the other values. For example create a merged cell of D3:E9 on
// Sheet1:
@ -30,7 +30,7 @@ func (mc *xlsxMergeCell) Rect() ([]int, error) {
// err := f.MergeCell("Sheet1", "D3", "E9")
//
// If you create a merged cell that overlaps with another existing merged cell,
// those merged cells that already exist will be removed. The cell coordinates
// those merged cells that already exist will be removed. The cell references
// tuple after merging in the following range will be: A1(x3,y1) D1(x2,y1)
// A8(x3,y4) D8(x2,y4)
//
@ -50,7 +50,7 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
if err != nil {
return err
}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
// Correct the range reference, such correct C1:B3 to B1:C3.
_ = sortCoordinates(rect)
hCell, _ = CoordinatesToCellName(rect[0], rect[1])
@ -72,13 +72,13 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
return err
}
// UnmergeCell provides a function to unmerge a given coordinate area.
// UnmergeCell provides a function to unmerge a given range reference.
// For example unmerge area D3:E9 on Sheet1:
//
// err := f.UnmergeCell("Sheet1", "D3", "E9")
//
// Attention: overlapped areas will also be unmerged.
func (f *File) UnmergeCell(sheet string, hCell, vCell string) error {
func (f *File) UnmergeCell(sheet, hCell, vCell string) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
@ -90,7 +90,7 @@ func (f *File) UnmergeCell(sheet string, hCell, vCell string) error {
return err
}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
// Correct the range reference, such correct C1:B3 to B1:C3.
_ = sortCoordinates(rect1)
// return nil since no MergeCells in the sheet
@ -135,8 +135,8 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
mergeCells = make([]MergeCell, 0, len(ws.MergeCells.Cells))
for i := range ws.MergeCells.Cells {
ref := ws.MergeCells.Cells[i].Ref
axis := strings.Split(ref, ":")[0]
val, _ := f.GetCellValue(sheet, axis)
cell := strings.Split(ref, ":")[0]
val, _ := f.GetCellValue(sheet, cell)
mergeCells = append(mergeCells, []string{ref, val})
}
}
@ -272,16 +272,14 @@ func (m *MergeCell) GetCellValue() string {
return (*m)[1]
}
// GetStartAxis returns the top left cell coordinates of merged range, for
// GetStartAxis returns the top left cell reference of merged range, for
// example: "C2".
func (m *MergeCell) GetStartAxis() string {
axis := strings.Split((*m)[0], ":")
return axis[0]
return strings.Split((*m)[0], ":")[0]
}
// GetEndAxis returns the bottom right cell coordinates of merged range, for
// GetEndAxis returns the bottom right cell reference of merged range, for
// example: "D4".
func (m *MergeCell) GetEndAxis() string {
axis := strings.Split((*m)[0], ":")
return axis[1]
return strings.Split((*m)[0], ":")[1]
}

View File

@ -512,8 +512,8 @@ func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {
}
// DeletePicture provides a function to delete charts in spreadsheet by given
// worksheet and cell name. Note that the image file won't be deleted from the
// document currently.
// worksheet name and cell reference. Note that the image file won't be deleted
// from the document currently.
func (f *File) DeletePicture(sheet, cell string) (err error) {
col, row, err := CellNameToCoordinates(cell)
if err != nil {

View File

@ -57,7 +57,7 @@ func TestAddPicture(t *testing.T) {
// Test add picture to worksheet from bytes.
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".png", file))
// Test add picture to worksheet from bytes with illegal cell coordinates.
// Test add picture to worksheet from bytes with illegal cell reference.
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", "", "Excel Logo", ".png", file), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.NoError(t, f.AddPicture("Sheet1", "Q8", filepath.Join("test", "images", "excel.gif"), ""))
@ -118,7 +118,7 @@ func TestGetPicture(t *testing.T) {
t.FailNow()
}
// Try to get picture from a worksheet with illegal cell coordinates.
// Try to get picture from a worksheet with illegal cell reference.
_, _, err = f.GetPicture("Sheet1", "A")
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
@ -173,7 +173,7 @@ func TestGetPicture(t *testing.T) {
}
func TestAddDrawingPicture(t *testing.T) {
// Test addDrawingPicture with illegal cell coordinates.
// Test addDrawingPicture with illegal cell reference.
f := NewFile()
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", 0, 0, 0, 0, nil), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
}

View File

@ -27,26 +27,26 @@ import (
// PivotStyleDark1 - PivotStyleDark28
type PivotTableOption struct {
pivotTableSheetName string
DataRange string
PivotTableRange string
Rows []PivotTableField
Columns []PivotTableField
Data []PivotTableField
Filter []PivotTableField
RowGrandTotals bool
ColGrandTotals bool
ShowDrill bool
UseAutoFormatting bool
PageOverThenDown bool
MergeItem bool
CompactData bool
ShowError bool
ShowRowHeaders bool
ShowColHeaders bool
ShowRowStripes bool
ShowColStripes bool
ShowLastColumn bool
PivotTableStyleName string
DataRange string `json:"data_range"`
PivotTableRange string `json:"pivot_table_range"`
Rows []PivotTableField `json:"rows"`
Columns []PivotTableField `json:"columns"`
Data []PivotTableField `json:"data"`
Filter []PivotTableField `json:"filter"`
RowGrandTotals bool `json:"row_grand_totals"`
ColGrandTotals bool `json:"col_grand_totals"`
ShowDrill bool `json:"show_drill"`
UseAutoFormatting bool `json:"use_auto_formatting"`
PageOverThenDown bool `json:"page_over_then_down"`
MergeItem bool `json:"merge_item"`
CompactData bool `json:"compact_data"`
ShowError bool `json:"show_error"`
ShowRowHeaders bool `json:"show_row_headers"`
ShowColHeaders bool `json:"show_col_headers"`
ShowRowStripes bool `json:"show_row_stripes"`
ShowColStripes bool `json:"show_col_stripes"`
ShowLastColumn bool `json:"show_last_column"`
PivotTableStyleName string `json:"pivot_table_style_name"`
}
// PivotTableField directly maps the field settings of the pivot table.
@ -69,12 +69,12 @@ type PivotTableOption struct {
// Name specifies the name of the data field. Maximum 255 characters
// are allowed in data field name, excess characters will be truncated.
type PivotTableField struct {
Compact bool
Data string
Name string
Outline bool
Subtotal string
DefaultSubtotal bool
Compact bool `json:"compact"`
Data string `json:"data"`
Name string `json:"name"`
Outline bool `json:"outline"`
Subtotal string `json:"subtotal"`
DefaultSubtotal bool `json:"default_subtotal"`
}
// AddPivotTable provides the method to add pivot table by given pivot table
@ -128,9 +128,9 @@ type PivotTableField struct {
// fmt.Println(err)
// }
// }
func (f *File) AddPivotTable(opt *PivotTableOption) error {
func (f *File) AddPivotTable(opts *PivotTableOption) error {
// parameter validation
_, pivotTableSheetPath, err := f.parseFormatPivotTableSet(opt)
_, pivotTableSheetPath, err := f.parseFormatPivotTableSet(opts)
if err != nil {
return err
}
@ -141,7 +141,7 @@ func (f *File) AddPivotTable(opt *PivotTableOption) error {
sheetRelationshipsPivotTableXML := "../pivotTables/pivotTable" + strconv.Itoa(pivotTableID) + ".xml"
pivotTableXML := strings.ReplaceAll(sheetRelationshipsPivotTableXML, "..", "xl")
pivotCacheXML := "xl/pivotCache/pivotCacheDefinition" + strconv.Itoa(pivotCacheID) + ".xml"
err = f.addPivotCache(pivotCacheXML, opt)
err = f.addPivotCache(pivotCacheXML, opts)
if err != nil {
return err
}
@ -153,7 +153,7 @@ func (f *File) AddPivotTable(opt *PivotTableOption) error {
pivotCacheRels := "xl/pivotTables/_rels/pivotTable" + strconv.Itoa(pivotTableID) + ".xml.rels"
// rId not used
_ = f.addRels(pivotCacheRels, SourceRelationshipPivotCache, fmt.Sprintf("../pivotCache/pivotCacheDefinition%d.xml", pivotCacheID), "")
err = f.addPivotTable(cacheID, pivotTableID, pivotTableXML, opt)
err = f.addPivotTable(cacheID, pivotTableID, pivotTableXML, opts)
if err != nil {
return err
}
@ -167,18 +167,18 @@ func (f *File) AddPivotTable(opt *PivotTableOption) error {
// parseFormatPivotTableSet provides a function to validate pivot table
// properties.
func (f *File) parseFormatPivotTableSet(opt *PivotTableOption) (*xlsxWorksheet, string, error) {
if opt == nil {
func (f *File) parseFormatPivotTableSet(opts *PivotTableOption) (*xlsxWorksheet, string, error) {
if opts == nil {
return nil, "", ErrParameterRequired
}
pivotTableSheetName, _, err := f.adjustRange(opt.PivotTableRange)
pivotTableSheetName, _, err := f.adjustRange(opts.PivotTableRange)
if err != nil {
return nil, "", fmt.Errorf("parameter 'PivotTableRange' parsing error: %s", err.Error())
}
opt.pivotTableSheetName = pivotTableSheetName
dataRange := f.getDefinedNameRefTo(opt.DataRange, pivotTableSheetName)
opts.pivotTableSheetName = pivotTableSheetName
dataRange := f.getDefinedNameRefTo(opts.DataRange, pivotTableSheetName)
if dataRange == "" {
dataRange = opt.DataRange
dataRange = opts.DataRange
}
dataSheetName, _, err := f.adjustRange(dataRange)
if err != nil {
@ -214,7 +214,7 @@ func (f *File) adjustRange(rangeStr string) (string, []int, error) {
return rng[0], []int{}, ErrParameterInvalid
}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
// Correct the range, such correct C1:B3 to B1:C3.
if x2 < x1 {
x1, x2 = x2, x1
}
@ -227,11 +227,11 @@ func (f *File) adjustRange(rangeStr string) (string, []int, error) {
// getPivotFieldsOrder provides a function to get order list of pivot table
// fields.
func (f *File) getPivotFieldsOrder(opt *PivotTableOption) ([]string, error) {
func (f *File) getPivotFieldsOrder(opts *PivotTableOption) ([]string, error) {
var order []string
dataRange := f.getDefinedNameRefTo(opt.DataRange, opt.pivotTableSheetName)
dataRange := f.getDefinedNameRefTo(opts.DataRange, opts.pivotTableSheetName)
if dataRange == "" {
dataRange = opt.DataRange
dataRange = opts.DataRange
}
dataSheet, coordinates, err := f.adjustRange(dataRange)
if err != nil {
@ -249,20 +249,20 @@ func (f *File) getPivotFieldsOrder(opt *PivotTableOption) ([]string, error) {
}
// addPivotCache provides a function to create a pivot cache by given properties.
func (f *File) addPivotCache(pivotCacheXML string, opt *PivotTableOption) error {
func (f *File) addPivotCache(pivotCacheXML string, opts *PivotTableOption) error {
// validate data range
definedNameRef := true
dataRange := f.getDefinedNameRefTo(opt.DataRange, opt.pivotTableSheetName)
dataRange := f.getDefinedNameRefTo(opts.DataRange, opts.pivotTableSheetName)
if dataRange == "" {
definedNameRef = false
dataRange = opt.DataRange
dataRange = opts.DataRange
}
dataSheet, coordinates, err := f.adjustRange(dataRange)
if err != nil {
return fmt.Errorf("parameter 'DataRange' parsing error: %s", err.Error())
}
// data range has been checked
order, _ := f.getPivotFieldsOrder(opt)
order, _ := f.getPivotFieldsOrder(opts)
hCell, _ := CoordinatesToCellName(coordinates[0], coordinates[1])
vCell, _ := CoordinatesToCellName(coordinates[2], coordinates[3])
pc := xlsxPivotCacheDefinition{
@ -281,11 +281,11 @@ func (f *File) addPivotCache(pivotCacheXML string, opt *PivotTableOption) error
CacheFields: &xlsxCacheFields{},
}
if definedNameRef {
pc.CacheSource.WorksheetSource = &xlsxWorksheetSource{Name: opt.DataRange}
pc.CacheSource.WorksheetSource = &xlsxWorksheetSource{Name: opts.DataRange}
}
for _, name := range order {
rowOptions, rowOk := f.getPivotTableFieldOptions(name, opt.Rows)
columnOptions, colOk := f.getPivotTableFieldOptions(name, opt.Columns)
rowOptions, rowOk := f.getPivotTableFieldOptions(name, opts.Rows)
columnOptions, colOk := f.getPivotTableFieldOptions(name, opts.Columns)
sharedItems := xlsxSharedItems{
Count: 0,
}
@ -311,9 +311,9 @@ func (f *File) addPivotCache(pivotCacheXML string, opt *PivotTableOption) error
// addPivotTable provides a function to create a pivot table by given pivot
// table ID and properties.
func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, opt *PivotTableOption) error {
func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, opts *PivotTableOption) error {
// validate pivot table range
_, coordinates, err := f.adjustRange(opt.PivotTableRange)
_, coordinates, err := f.adjustRange(opts.PivotTableRange)
if err != nil {
return fmt.Errorf("parameter 'PivotTableRange' parsing error: %s", err.Error())
}
@ -322,25 +322,25 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
vCell, _ := CoordinatesToCellName(coordinates[2], coordinates[3])
pivotTableStyle := func() string {
if opt.PivotTableStyleName == "" {
if opts.PivotTableStyleName == "" {
return "PivotStyleLight16"
}
return opt.PivotTableStyleName
return opts.PivotTableStyleName
}
pt := xlsxPivotTableDefinition{
Name: fmt.Sprintf("Pivot Table%d", pivotTableID),
CacheID: cacheID,
RowGrandTotals: &opt.RowGrandTotals,
ColGrandTotals: &opt.ColGrandTotals,
RowGrandTotals: &opts.RowGrandTotals,
ColGrandTotals: &opts.ColGrandTotals,
UpdatedVersion: pivotTableVersion,
MinRefreshableVersion: pivotTableVersion,
ShowDrill: &opt.ShowDrill,
UseAutoFormatting: &opt.UseAutoFormatting,
PageOverThenDown: &opt.PageOverThenDown,
MergeItem: &opt.MergeItem,
ShowDrill: &opts.ShowDrill,
UseAutoFormatting: &opts.UseAutoFormatting,
PageOverThenDown: &opts.PageOverThenDown,
MergeItem: &opts.MergeItem,
CreatedVersion: pivotTableVersion,
CompactData: &opt.CompactData,
ShowError: &opt.ShowError,
CompactData: &opts.CompactData,
ShowError: &opts.ShowError,
DataCaption: "Values",
Location: &xlsxLocation{
Ref: hCell + ":" + vCell,
@ -363,25 +363,25 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
},
PivotTableStyleInfo: &xlsxPivotTableStyleInfo{
Name: pivotTableStyle(),
ShowRowHeaders: opt.ShowRowHeaders,
ShowColHeaders: opt.ShowColHeaders,
ShowRowStripes: opt.ShowRowStripes,
ShowColStripes: opt.ShowColStripes,
ShowLastColumn: opt.ShowLastColumn,
ShowRowHeaders: opts.ShowRowHeaders,
ShowColHeaders: opts.ShowColHeaders,
ShowRowStripes: opts.ShowRowStripes,
ShowColStripes: opts.ShowColStripes,
ShowLastColumn: opts.ShowLastColumn,
},
}
// pivot fields
_ = f.addPivotFields(&pt, opt)
_ = f.addPivotFields(&pt, opts)
// count pivot fields
pt.PivotFields.Count = len(pt.PivotFields.PivotField)
// data range has been checked
_ = f.addPivotRowFields(&pt, opt)
_ = f.addPivotColFields(&pt, opt)
_ = f.addPivotPageFields(&pt, opt)
_ = f.addPivotDataFields(&pt, opt)
_ = f.addPivotRowFields(&pt, opts)
_ = f.addPivotColFields(&pt, opts)
_ = f.addPivotPageFields(&pt, opts)
_ = f.addPivotDataFields(&pt, opts)
pivotTable, err := xml.Marshal(pt)
f.saveFileList(pivotTableXML, pivotTable)
@ -390,9 +390,9 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
// addPivotRowFields provides a method to add row fields for pivot table by
// given pivot table options.
func (f *File) addPivotRowFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
func (f *File) addPivotRowFields(pt *xlsxPivotTableDefinition, opts *PivotTableOption) error {
// row fields
rowFieldsIndex, err := f.getPivotFieldsIndex(opt.Rows, opt)
rowFieldsIndex, err := f.getPivotFieldsIndex(opts.Rows, opts)
if err != nil {
return err
}
@ -414,13 +414,13 @@ func (f *File) addPivotRowFields(pt *xlsxPivotTableDefinition, opt *PivotTableOp
// addPivotPageFields provides a method to add page fields for pivot table by
// given pivot table options.
func (f *File) addPivotPageFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
func (f *File) addPivotPageFields(pt *xlsxPivotTableDefinition, opts *PivotTableOption) error {
// page fields
pageFieldsIndex, err := f.getPivotFieldsIndex(opt.Filter, opt)
pageFieldsIndex, err := f.getPivotFieldsIndex(opts.Filter, opts)
if err != nil {
return err
}
pageFieldsName := f.getPivotTableFieldsName(opt.Filter)
pageFieldsName := f.getPivotTableFieldsName(opts.Filter)
for idx, pageField := range pageFieldsIndex {
if pt.PageFields == nil {
pt.PageFields = &xlsxPageFields{}
@ -440,14 +440,14 @@ func (f *File) addPivotPageFields(pt *xlsxPivotTableDefinition, opt *PivotTableO
// addPivotDataFields provides a method to add data fields for pivot table by
// given pivot table options.
func (f *File) addPivotDataFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
func (f *File) addPivotDataFields(pt *xlsxPivotTableDefinition, opts *PivotTableOption) error {
// data fields
dataFieldsIndex, err := f.getPivotFieldsIndex(opt.Data, opt)
dataFieldsIndex, err := f.getPivotFieldsIndex(opts.Data, opts)
if err != nil {
return err
}
dataFieldsSubtotals := f.getPivotTableFieldsSubtotal(opt.Data)
dataFieldsName := f.getPivotTableFieldsName(opt.Data)
dataFieldsSubtotals := f.getPivotTableFieldsSubtotal(opts.Data)
dataFieldsName := f.getPivotTableFieldsName(opts.Data)
for idx, dataField := range dataFieldsIndex {
if pt.DataFields == nil {
pt.DataFields = &xlsxDataFields{}
@ -480,9 +480,9 @@ func inPivotTableField(a []PivotTableField, x string) int {
// addPivotColFields create pivot column fields by given pivot table
// definition and option.
func (f *File) addPivotColFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
if len(opt.Columns) == 0 {
if len(opt.Data) <= 1 {
func (f *File) addPivotColFields(pt *xlsxPivotTableDefinition, opts *PivotTableOption) error {
if len(opts.Columns) == 0 {
if len(opts.Data) <= 1 {
return nil
}
pt.ColFields = &xlsxColFields{}
@ -497,7 +497,7 @@ func (f *File) addPivotColFields(pt *xlsxPivotTableDefinition, opt *PivotTableOp
pt.ColFields = &xlsxColFields{}
// col fields
colFieldsIndex, err := f.getPivotFieldsIndex(opt.Columns, opt)
colFieldsIndex, err := f.getPivotFieldsIndex(opts.Columns, opts)
if err != nil {
return err
}
@ -508,7 +508,7 @@ func (f *File) addPivotColFields(pt *xlsxPivotTableDefinition, opt *PivotTableOp
}
// in order to create pivot in case there is many Columns and Data
if len(opt.Data) > 1 {
if len(opts.Data) > 1 {
pt.ColFields.Field = append(pt.ColFields.Field, &xlsxField{
X: -2,
})
@ -521,15 +521,15 @@ func (f *File) addPivotColFields(pt *xlsxPivotTableDefinition, opt *PivotTableOp
// addPivotFields create pivot fields based on the column order of the first
// row in the data region by given pivot table definition and option.
func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
order, err := f.getPivotFieldsOrder(opt)
func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opts *PivotTableOption) error {
order, err := f.getPivotFieldsOrder(opts)
if err != nil {
return err
}
x := 0
for _, name := range order {
if inPivotTableField(opt.Rows, name) != -1 {
rowOptions, ok := f.getPivotTableFieldOptions(name, opt.Rows)
if inPivotTableField(opts.Rows, name) != -1 {
rowOptions, ok := f.getPivotTableFieldOptions(name, opts.Rows)
var items []*xlsxItem
if !ok || !rowOptions.DefaultSubtotal {
items = append(items, &xlsxItem{X: &x})
@ -538,9 +538,9 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
}
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
Name: f.getPivotTableFieldName(name, opt.Rows),
Name: f.getPivotTableFieldName(name, opts.Rows),
Axis: "axisRow",
DataField: inPivotTableField(opt.Data, name) != -1,
DataField: inPivotTableField(opts.Data, name) != -1,
Compact: &rowOptions.Compact,
Outline: &rowOptions.Outline,
DefaultSubtotal: &rowOptions.DefaultSubtotal,
@ -551,11 +551,11 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
})
continue
}
if inPivotTableField(opt.Filter, name) != -1 {
if inPivotTableField(opts.Filter, name) != -1 {
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
Axis: "axisPage",
DataField: inPivotTableField(opt.Data, name) != -1,
Name: f.getPivotTableFieldName(name, opt.Columns),
DataField: inPivotTableField(opts.Data, name) != -1,
Name: f.getPivotTableFieldName(name, opts.Columns),
Items: &xlsxItems{
Count: 1,
Item: []*xlsxItem{
@ -565,8 +565,8 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
})
continue
}
if inPivotTableField(opt.Columns, name) != -1 {
columnOptions, ok := f.getPivotTableFieldOptions(name, opt.Columns)
if inPivotTableField(opts.Columns, name) != -1 {
columnOptions, ok := f.getPivotTableFieldOptions(name, opts.Columns)
var items []*xlsxItem
if !ok || !columnOptions.DefaultSubtotal {
items = append(items, &xlsxItem{X: &x})
@ -574,9 +574,9 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
items = append(items, &xlsxItem{T: "default"})
}
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
Name: f.getPivotTableFieldName(name, opt.Columns),
Name: f.getPivotTableFieldName(name, opts.Columns),
Axis: "axisCol",
DataField: inPivotTableField(opt.Data, name) != -1,
DataField: inPivotTableField(opts.Data, name) != -1,
Compact: &columnOptions.Compact,
Outline: &columnOptions.Outline,
DefaultSubtotal: &columnOptions.DefaultSubtotal,
@ -587,7 +587,7 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
})
continue
}
if inPivotTableField(opt.Data, name) != -1 {
if inPivotTableField(opts.Data, name) != -1 {
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
DataField: true,
})
@ -626,9 +626,9 @@ func (f *File) countPivotCache() int {
// getPivotFieldsIndex convert the column of the first row in the data region
// to a sequential index by given fields and pivot option.
func (f *File) getPivotFieldsIndex(fields []PivotTableField, opt *PivotTableOption) ([]int, error) {
func (f *File) getPivotFieldsIndex(fields []PivotTableField, opts *PivotTableOption) ([]int, error) {
var pivotFieldsIndex []int
orders, err := f.getPivotFieldsOrder(opt)
orders, err := f.getPivotFieldsOrder(opts)
if err != nil {
return pivotFieldsIndex, err
}

View File

@ -880,7 +880,7 @@ func TestDuplicateRowTo(t *testing.T) {
assert.Equal(t, nil, f.DuplicateRowTo(sheetName, 1, 1))
// Test duplicate row on the blank worksheet
assert.Equal(t, nil, f.DuplicateRowTo(sheetName, 1, 2))
// Test duplicate row on the worksheet with illegal cell coordinates
// Test duplicate row on the worksheet with illegal cell reference
f.Sheet.Store("xl/worksheets/sheet1.xml", &xlsxWorksheet{
MergeCells: &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:B1"}}},
})

View File

@ -329,23 +329,23 @@ func (f *File) getActiveSheetID() int {
return 0
}
// SetSheetName provides a function to set the worksheet name by given old and
// new worksheet names. Maximum 31 characters are allowed in sheet title and
// SetSheetName provides a function to set the worksheet name by given source and
// target worksheet names. Maximum 31 characters are allowed in sheet title and
// this function only changes the name of the sheet and will not update the
// sheet name in the formula or reference associated with the cell. So there
// may be problem formula error or reference missing.
func (f *File) SetSheetName(oldName, newName string) {
oldName = trimSheetName(oldName)
newName = trimSheetName(newName)
if strings.EqualFold(newName, oldName) {
func (f *File) SetSheetName(source, target string) {
source = trimSheetName(source)
target = trimSheetName(target)
if strings.EqualFold(target, source) {
return
}
content := f.workbookReader()
for k, v := range content.Sheets.Sheet {
if v.Name == oldName {
content.Sheets.Sheet[k].Name = newName
f.sheetMap[newName] = f.sheetMap[oldName]
delete(f.sheetMap, oldName)
if v.Name == source {
content.Sheets.Sheet[k].Name = target
f.sheetMap[target] = f.sheetMap[source]
delete(f.sheetMap, source)
}
}
}
@ -815,17 +815,17 @@ func (f *File) GetSheetVisible(sheet string) bool {
return visible
}
// SearchSheet provides a function to get coordinates by given worksheet name,
// SearchSheet provides a function to get cell reference by given worksheet name,
// cell value, and regular expression. The function doesn't support searching
// on the calculated result, formatted numbers and conditional lookup
// currently. If it is a merged cell, it will return the coordinates of the
// upper left corner of the merged area.
// currently. If it is a merged cell, it will return the cell reference of the
// upper left cell of the merged range reference.
//
// An example of search the coordinates of the value of "100" on Sheet1:
// An example of search the cell reference of the value of "100" on Sheet1:
//
// result, err := f.SearchSheet("Sheet1", "100")
//
// An example of search the coordinates where the numerical value in the range
// An example of search the cell reference where the numerical value in the range
// of "0-9" of Sheet1 is described:
//
// result, err := f.SearchSheet("Sheet1", "[0-9]", true)
@ -849,8 +849,8 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) {
return f.searchSheet(name, value, regSearch)
}
// searchSheet provides a function to get coordinates by given worksheet name,
// cell value, and regular expression.
// searchSheet provides a function to get cell reference by given worksheet
// name, cell value, and regular expression.
func (f *File) searchSheet(name, value string, regSearch bool) (result []string, err error) {
var (
cellName, inElement string
@ -1684,7 +1684,7 @@ func (f *File) UngroupSheets() error {
}
// InsertPageBreak create a page break to determine where the printed page
// ends and where begins the next one by given worksheet name and axis, so the
// ends and where begins the next one by given worksheet name and cell reference, so the
// content before the page break will be printed on one page and after the
// page break on another.
func (f *File) InsertPageBreak(sheet, cell string) (err error) {
@ -1741,7 +1741,8 @@ func (f *File) InsertPageBreak(sheet, cell string) (err error) {
return
}
// RemovePageBreak remove a page break by given worksheet name and axis.
// RemovePageBreak remove a page break by given worksheet name and cell
// reference.
func (f *File) RemovePageBreak(sheet, cell string) (err error) {
var ws *xlsxWorksheet
var row, col int

View File

@ -130,8 +130,8 @@ func TestPageLayoutOption(t *testing.T) {
for i, test := range testData {
t.Run(fmt.Sprintf("TestData%d", i), func(t *testing.T) {
opt := test.nonDefault
t.Logf("option %T", opt)
opts := test.nonDefault
t.Logf("option %T", opts)
def := deepcopy.Copy(test.container).(PageLayoutOptionPtr)
val1 := deepcopy.Copy(def).(PageLayoutOptionPtr)
@ -139,34 +139,34 @@ func TestPageLayoutOption(t *testing.T) {
f := NewFile()
// Get the default value
assert.NoError(t, f.GetPageLayout(sheet, def), opt)
assert.NoError(t, f.GetPageLayout(sheet, def), opts)
// Get again and check
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
if !assert.Equal(t, val1, def, opt) {
assert.NoError(t, f.GetPageLayout(sheet, val1), opts)
if !assert.Equal(t, val1, def, opts) {
t.FailNow()
}
// Set the same value
assert.NoError(t, f.SetPageLayout(sheet, val1), opt)
assert.NoError(t, f.SetPageLayout(sheet, val1), opts)
// Get again and check
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetPageLayout(sheet, val1), opts)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opts) {
t.FailNow()
}
// Set a different value
assert.NoError(t, f.SetPageLayout(sheet, test.nonDefault), opt)
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
assert.NoError(t, f.SetPageLayout(sheet, test.nonDefault), opts)
assert.NoError(t, f.GetPageLayout(sheet, val1), opts)
// Get again and compare
assert.NoError(t, f.GetPageLayout(sheet, val2), opt)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetPageLayout(sheet, val2), opts)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opts) {
t.FailNow()
}
// Value should not be the same as the default
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opt) {
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opts) {
t.FailNow()
}
// Restore the default value
assert.NoError(t, f.SetPageLayout(sheet, def), opt)
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
assert.NoError(t, f.SetPageLayout(sheet, def), opts)
assert.NoError(t, f.GetPageLayout(sheet, val1), opts)
if !assert.Equal(t, def, val1) {
t.FailNow()
}
@ -218,7 +218,7 @@ func TestSearchSheet(t *testing.T) {
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(`<worksheet><sheetData><row r="0"><c r="A1" t="str"><v>A</v></c></row></sheetData></worksheet>`))
result, err = f.SearchSheet("Sheet1", "A")
assert.EqualError(t, err, "invalid cell coordinates [1, 0]")
assert.EqualError(t, err, "invalid cell reference [1, 0]")
assert.Equal(t, []string(nil), result)
}

View File

@ -132,8 +132,8 @@ func TestSheetPrOptions(t *testing.T) {
for i, test := range testData {
t.Run(fmt.Sprintf("TestData%d", i), func(t *testing.T) {
opt := test.nonDefault
t.Logf("option %T", opt)
opts := test.nonDefault
t.Logf("option %T", opts)
def := deepcopy.Copy(test.container).(SheetPrOptionPtr)
val1 := deepcopy.Copy(def).(SheetPrOptionPtr)
@ -141,34 +141,34 @@ func TestSheetPrOptions(t *testing.T) {
f := NewFile()
// Get the default value
assert.NoError(t, f.GetSheetPrOptions(sheet, def), opt)
assert.NoError(t, f.GetSheetPrOptions(sheet, def), opts)
// Get again and check
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opt)
if !assert.Equal(t, val1, def, opt) {
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opts)
if !assert.Equal(t, val1, def, opts) {
t.FailNow()
}
// Set the same value
assert.NoError(t, f.SetSheetPrOptions(sheet, val1), opt)
assert.NoError(t, f.SetSheetPrOptions(sheet, val1), opts)
// Get again and check
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opt)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opts)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opts) {
t.FailNow()
}
// Set a different value
assert.NoError(t, f.SetSheetPrOptions(sheet, test.nonDefault), opt)
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opt)
assert.NoError(t, f.SetSheetPrOptions(sheet, test.nonDefault), opts)
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opts)
// Get again and compare
assert.NoError(t, f.GetSheetPrOptions(sheet, val2), opt)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetSheetPrOptions(sheet, val2), opts)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opts) {
t.FailNow()
}
// Value should not be the same as the default
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opt) {
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opts) {
t.FailNow()
}
// Restore the default value
assert.NoError(t, f.SetSheetPrOptions(sheet, def), opt)
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opt)
assert.NoError(t, f.SetSheetPrOptions(sheet, def), opts)
assert.NoError(t, f.GetSheetPrOptions(sheet, val1), opts)
if !assert.Equal(t, def, val1) {
t.FailNow()
}
@ -281,8 +281,8 @@ func TestPageMarginsOption(t *testing.T) {
for i, test := range testData {
t.Run(fmt.Sprintf("TestData%d", i), func(t *testing.T) {
opt := test.nonDefault
t.Logf("option %T", opt)
opts := test.nonDefault
t.Logf("option %T", opts)
def := deepcopy.Copy(test.container).(PageMarginsOptionsPtr)
val1 := deepcopy.Copy(def).(PageMarginsOptionsPtr)
@ -290,34 +290,34 @@ func TestPageMarginsOption(t *testing.T) {
f := NewFile()
// Get the default value
assert.NoError(t, f.GetPageMargins(sheet, def), opt)
assert.NoError(t, f.GetPageMargins(sheet, def), opts)
// Get again and check
assert.NoError(t, f.GetPageMargins(sheet, val1), opt)
if !assert.Equal(t, val1, def, opt) {
assert.NoError(t, f.GetPageMargins(sheet, val1), opts)
if !assert.Equal(t, val1, def, opts) {
t.FailNow()
}
// Set the same value
assert.NoError(t, f.SetPageMargins(sheet, val1), opt)
assert.NoError(t, f.SetPageMargins(sheet, val1), opts)
// Get again and check
assert.NoError(t, f.GetPageMargins(sheet, val1), opt)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetPageMargins(sheet, val1), opts)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opts) {
t.FailNow()
}
// Set a different value
assert.NoError(t, f.SetPageMargins(sheet, test.nonDefault), opt)
assert.NoError(t, f.GetPageMargins(sheet, val1), opt)
assert.NoError(t, f.SetPageMargins(sheet, test.nonDefault), opts)
assert.NoError(t, f.GetPageMargins(sheet, val1), opts)
// Get again and compare
assert.NoError(t, f.GetPageMargins(sheet, val2), opt)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetPageMargins(sheet, val2), opts)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opts) {
t.FailNow()
}
// Value should not be the same as the default
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opt) {
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opts) {
t.FailNow()
}
// Restore the default value
assert.NoError(t, f.SetPageMargins(sheet, def), opt)
assert.NoError(t, f.GetPageMargins(sheet, val1), opt)
assert.NoError(t, f.SetPageMargins(sheet, def), opts)
assert.NoError(t, f.GetPageMargins(sheet, val1), opts)
if !assert.Equal(t, def, val1) {
t.FailNow()
}
@ -417,8 +417,8 @@ func TestSheetFormatPrOptions(t *testing.T) {
for i, test := range testData {
t.Run(fmt.Sprintf("TestData%d", i), func(t *testing.T) {
opt := test.nonDefault
t.Logf("option %T", opt)
opts := test.nonDefault
t.Logf("option %T", opts)
def := deepcopy.Copy(test.container).(SheetFormatPrOptionsPtr)
val1 := deepcopy.Copy(def).(SheetFormatPrOptionsPtr)
@ -426,34 +426,34 @@ func TestSheetFormatPrOptions(t *testing.T) {
f := NewFile()
// Get the default value
assert.NoError(t, f.GetSheetFormatPr(sheet, def), opt)
assert.NoError(t, f.GetSheetFormatPr(sheet, def), opts)
// Get again and check
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opt)
if !assert.Equal(t, val1, def, opt) {
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opts)
if !assert.Equal(t, val1, def, opts) {
t.FailNow()
}
// Set the same value
assert.NoError(t, f.SetSheetFormatPr(sheet, val1), opt)
assert.NoError(t, f.SetSheetFormatPr(sheet, val1), opts)
// Get again and check
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opt)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opts)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opts) {
t.FailNow()
}
// Set a different value
assert.NoError(t, f.SetSheetFormatPr(sheet, test.nonDefault), opt)
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opt)
assert.NoError(t, f.SetSheetFormatPr(sheet, test.nonDefault), opts)
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opts)
// Get again and compare
assert.NoError(t, f.GetSheetFormatPr(sheet, val2), opt)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) {
assert.NoError(t, f.GetSheetFormatPr(sheet, val2), opts)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opts) {
t.FailNow()
}
// Value should not be the same as the default
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opt) {
if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opts) {
t.FailNow()
}
// Restore the default value
assert.NoError(t, f.SetSheetFormatPr(sheet, def), opt)
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opt)
assert.NoError(t, f.SetSheetFormatPr(sheet, def), opts)
assert.NoError(t, f.GetSheetFormatPr(sheet, val1), opts)
if !assert.Equal(t, def, val1) {
t.FailNow()
}

View File

@ -387,7 +387,7 @@ func (f *File) addSparklineGroupByStyle(ID int) *xlsxX14SparklineGroup {
// Markers | Toggle sparkline markers
// ColorAxis | An RGB Color is specified as RRGGBB
// Axis | Show sparkline axis
func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
func (f *File) AddSparkline(sheet string, opts *SparklineOption) (err error) {
var (
ws *xlsxWorksheet
sparkType string
@ -400,39 +400,39 @@ func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
)
// parameter validation
if ws, err = f.parseFormatAddSparklineSet(sheet, opt); err != nil {
if ws, err = f.parseFormatAddSparklineSet(sheet, opts); err != nil {
return
}
// Handle the sparkline type
sparkType = "line"
sparkTypes = map[string]string{"line": "line", "column": "column", "win_loss": "stacked"}
if opt.Type != "" {
if specifiedSparkTypes, ok = sparkTypes[opt.Type]; !ok {
if opts.Type != "" {
if specifiedSparkTypes, ok = sparkTypes[opts.Type]; !ok {
err = ErrSparklineType
return
}
sparkType = specifiedSparkTypes
}
group = f.addSparklineGroupByStyle(opt.Style)
group = f.addSparklineGroupByStyle(opts.Style)
group.Type = sparkType
group.ColorAxis = &xlsxColor{RGB: "FF000000"}
group.DisplayEmptyCellsAs = "gap"
group.High = opt.High
group.Low = opt.Low
group.First = opt.First
group.Last = opt.Last
group.Negative = opt.Negative
group.DisplayXAxis = opt.Axis
group.Markers = opt.Markers
if opt.SeriesColor != "" {
group.High = opts.High
group.Low = opts.Low
group.First = opts.First
group.Last = opts.Last
group.Negative = opts.Negative
group.DisplayXAxis = opts.Axis
group.Markers = opts.Markers
if opts.SeriesColor != "" {
group.ColorSeries = &xlsxTabColor{
RGB: getPaletteColor(opt.SeriesColor),
RGB: getPaletteColor(opts.SeriesColor),
}
}
if opt.Reverse {
group.RightToLeft = opt.Reverse
if opts.Reverse {
group.RightToLeft = opts.Reverse
}
f.addSparkline(opt, group)
f.addSparkline(opts, group)
if ws.ExtLst.Ext != "" { // append mode ext
if err = f.appendSparkline(ws, group, groups); err != nil {
return
@ -459,25 +459,25 @@ func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
// parseFormatAddSparklineSet provides a function to validate sparkline
// properties.
func (f *File) parseFormatAddSparklineSet(sheet string, opt *SparklineOption) (*xlsxWorksheet, error) {
func (f *File) parseFormatAddSparklineSet(sheet string, opts *SparklineOption) (*xlsxWorksheet, error) {
ws, err := f.workSheetReader(sheet)
if err != nil {
return ws, err
}
if opt == nil {
if opts == nil {
return ws, ErrParameterRequired
}
if len(opt.Location) < 1 {
if len(opts.Location) < 1 {
return ws, ErrSparklineLocation
}
if len(opt.Range) < 1 {
if len(opts.Range) < 1 {
return ws, ErrSparklineRange
}
// The ranges and locations must match.\
if len(opt.Location) != len(opt.Range) {
// The range and locations must match
if len(opts.Location) != len(opts.Range) {
return ws, ErrSparkline
}
if opt.Style < 0 || opt.Style > 35 {
if opts.Style < 0 || opts.Style > 35 {
return ws, ErrSparklineStyle
}
if ws.ExtLst == nil {
@ -488,10 +488,10 @@ func (f *File) parseFormatAddSparklineSet(sheet string, opt *SparklineOption) (*
// addSparkline provides a function to create a sparkline in a sparkline group
// by given properties.
func (f *File) addSparkline(opt *SparklineOption, group *xlsxX14SparklineGroup) {
for idx, location := range opt.Location {
func (f *File) addSparkline(opts *SparklineOption, group *xlsxX14SparklineGroup) {
for idx, location := range opts.Location {
group.Sparklines.Sparkline = append(group.Sparklines.Sparkline, &xlsxX14Sparkline{
F: opt.Range[idx],
F: opts.Range[idx],
Sqref: location,
})
}

View File

@ -117,7 +117,7 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
}
// AddTable creates an Excel table for the StreamWriter using the given
// coordinate area and format set. For example, create a table of A1:D5:
// cell range and format set. For example, create a table of A1:D5:
//
// err := sw.AddTable("A1", "D5", "")
//
@ -156,7 +156,7 @@ func (sw *StreamWriter) AddTable(hCell, vCell, format string) error {
coordinates[3]++
}
// Correct table reference coordinate area, such correct C1:B3 to B1:C3.
// Correct table reference range, such correct C1:B3 to B1:C3.
ref, err := sw.File.coordinatesToAreaRef(coordinates)
if err != nil {
return err
@ -308,8 +308,8 @@ type RowOpts struct {
//
// As a special case, if Cell is used as a value, then the Cell.StyleID will be
// applied to that cell.
func (sw *StreamWriter) SetRow(axis string, values []interface{}, opts ...RowOpts) error {
col, row, err := CellNameToCoordinates(axis)
func (sw *StreamWriter) SetRow(cell string, values []interface{}, opts ...RowOpts) error {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return err
}
@ -329,11 +329,11 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}, opts ...RowOpt
if val == nil {
continue
}
axis, err := CoordinatesToCellName(col+i, row)
ref, err := CoordinatesToCellName(col+i, row)
if err != nil {
return err
}
c := xlsxC{R: axis}
c := xlsxC{R: ref}
if v, ok := val.(Cell); ok {
c.S = v.StyleID
val = v.Value
@ -355,24 +355,24 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}, opts ...RowOpt
// marshalRowAttrs prepare attributes of the row by given options.
func marshalRowAttrs(opts ...RowOpts) (attrs string, err error) {
var opt *RowOpts
var options *RowOpts
for i := range opts {
opt = &opts[i]
options = &opts[i]
}
if opt == nil {
if options == nil {
return
}
if opt.Height > MaxRowHeight {
if options.Height > MaxRowHeight {
err = ErrMaxRowHeight
return
}
if opt.StyleID > 0 {
attrs += fmt.Sprintf(` s="%d" customFormat="true"`, opt.StyleID)
if options.StyleID > 0 {
attrs += fmt.Sprintf(` s="%d" customFormat="true"`, options.StyleID)
}
if opt.Height > 0 {
attrs += fmt.Sprintf(` ht="%v" customHeight="true"`, opt.Height)
if options.Height > 0 {
attrs += fmt.Sprintf(` ht="%v" customHeight="true"`, options.Height)
}
if opt.Hidden {
if options.Hidden {
attrs += ` hidden="true"`
}
return
@ -401,7 +401,7 @@ func (sw *StreamWriter) SetColWidth(min, max int, width float64) error {
return nil
}
// MergeCell provides a function to merge cells by a given coordinate area for
// MergeCell provides a function to merge cells by a given range reference for
// the StreamWriter. Don't create a merged cell that overlaps with another
// existing merged cell.
func (sw *StreamWriter) MergeCell(hCell, vCell string) error {

View File

@ -175,7 +175,7 @@ func TestStreamTable(t *testing.T) {
// Test add table with illegal formatset.
assert.EqualError(t, streamWriter.AddTable("B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
// Test add table with illegal cell coordinates.
// Test add table with illegal cell reference.
assert.EqualError(t, streamWriter.AddTable("A", "B1", `{}`), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.EqualError(t, streamWriter.AddTable("A1", "B", `{}`), newCellNameToCoordinatesError("B", newInvalidCellNameError("B")).Error())
}
@ -185,7 +185,7 @@ func TestStreamMergeCells(t *testing.T) {
streamWriter, err := file.NewStreamWriter("Sheet1")
assert.NoError(t, err)
assert.NoError(t, streamWriter.MergeCell("A1", "D1"))
// Test merge cells with illegal cell coordinates.
// Test merge cells with illegal cell reference.
assert.EqualError(t, streamWriter.MergeCell("A", "D1"), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.NoError(t, streamWriter.Flush())
// Save spreadsheet by the given path.

View File

@ -1992,9 +1992,9 @@ func (f *File) getStyleID(ss *xlsxStyleSheet, style *Style) (styleID int) {
}
// NewConditionalStyle provides a function to create style for conditional
// format by given style format. The parameters are the same as function
// NewStyle(). Note that the color field uses RGB color code and only support
// to set font, fills, alignment and borders currently.
// format by given style format. The parameters are the same with the NewStyle
// function. Note that the color field uses RGB color code and only support to
// set font, fills, alignment and borders currently.
func (f *File) NewConditionalStyle(style string) (int, error) {
s := f.stylesReader()
fs, err := parseFormatStyleSet(style)
@ -2480,23 +2480,23 @@ func setCellXfs(style *xlsxStyleSheet, fontID, numFmtID, fillID, borderID int, a
}
// GetCellStyle provides a function to get cell style index by given worksheet
// name and cell coordinates.
func (f *File) GetCellStyle(sheet, axis string) (int, error) {
// name and cell reference.
func (f *File) GetCellStyle(sheet, cell string) (int, error) {
ws, err := f.workSheetReader(sheet)
if err != nil {
return 0, err
}
cellData, col, row, err := f.prepareCell(ws, axis)
c, col, row, err := f.prepareCell(ws, cell)
if err != nil {
return 0, err
}
return f.prepareCellStyle(ws, col, row, cellData.S), err
return f.prepareCellStyle(ws, col, row, c.S), err
}
// SetCellStyle provides a function to add style attribute for cells by given
// worksheet name, coordinate area and style ID. This function is concurrency
// worksheet name, range reference and style ID. This function is concurrency
// safe. Note that diagonalDown and diagonalUp type border should be use same
// color in the same coordinate area. SetCellStyle will overwrite the existing
// color in the same range. SetCellStyle will overwrite the existing
// styles for the cell, it won't append or merge style with existing styles.
//
// For example create a borders of cell H9 on Sheet1:
@ -2607,7 +2607,7 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
return err
}
// Normalize the coordinate area, such correct C1:B3 to B1:C3.
// Normalize the range, such correct C1:B3 to B1:C3.
if vCol < hCol {
vCol, hCol = hCol, vCol
}
@ -3050,14 +3050,14 @@ func (f *File) GetConditionalFormats(sheet string) (map[string]string, error) {
}
// UnsetConditionalFormat provides a function to unset the conditional format
// by given worksheet name and range.
func (f *File) UnsetConditionalFormat(sheet, area string) error {
// by given worksheet name and range reference.
func (f *File) UnsetConditionalFormat(sheet, reference string) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
for i, cf := range ws.ConditionalFormatting {
if cf.SQRef == area {
if cf.SQRef == reference {
ws.ConditionalFormatting = append(ws.ConditionalFormatting[:i], ws.ConditionalFormatting[i+1:]...)
return nil
}

View File

@ -29,7 +29,7 @@ func parseFormatTableSet(formatSet string) (*formatTable, error) {
}
// AddTable provides the method to add table in a worksheet by given worksheet
// name, coordinate area and format set. For example, create a table of A1:D5
// name, range reference and format set. For example, create a table of A1:D5
// on Sheet1:
//
// err := f.AddTable("Sheet1", "A1", "D5", "")
@ -159,14 +159,14 @@ func (f *File) setTableHeader(sheet string, x1, y1, x2 int) ([]*xlsxTableColumn,
}
// addTable provides a function to add table by given worksheet name,
// coordinate area and format set.
// range reference and format set.
func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, formatSet *formatTable) error {
// Correct the minimum number of rows, the table at least two lines.
if y1 == y2 {
y2++
}
// Correct table reference coordinate area, such correct C1:B3 to B1:C3.
// Correct table range reference, such correct C1:B3 to B1:C3.
ref, err := f.coordinatesToAreaRef([]int{x1, y1, x2, y2})
if err != nil {
return err
@ -211,17 +211,17 @@ func parseAutoFilterSet(formatSet string) (*formatAutoFilter, error) {
}
// AutoFilter provides the method to add auto filter in a worksheet by given
// worksheet name, coordinate area and settings. An autofilter in Excel is a
// worksheet name, range reference and settings. An auto filter in Excel is a
// way of filtering a 2D range of data based on some simple criteria. For
// example applying an autofilter to a cell range A1:D4 in the Sheet1:
// example applying an auto filter to a cell range A1:D4 in the Sheet1:
//
// err := f.AutoFilter("Sheet1", "A1", "D4", "")
//
// Filter data in an autofilter:
// Filter data in an auto filter:
//
// err := f.AutoFilter("Sheet1", "A1", "D4", `{"column":"B","expression":"x != blanks"}`)
//
// column defines the filter columns in a autofilter range based on simple
// column defines the filter columns in a auto filter range based on simple
// criteria
//
// It isn't sufficient to just specify the filter condition. You must also

View File

@ -33,22 +33,22 @@ func TestAddTable(t *testing.T) {
assert.EqualError(t, f.AddTable("SheetN", "B26", "A21", `{}`), "sheet SheetN does not exist")
// Test add table with illegal formatset.
assert.EqualError(t, f.AddTable("Sheet1", "B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
// Test add table with illegal cell coordinates.
// Test add table with illegal cell reference.
assert.EqualError(t, f.AddTable("Sheet1", "A", "B1", `{}`), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.EqualError(t, f.AddTable("Sheet1", "A1", "B", `{}`), newCellNameToCoordinatesError("B", newInvalidCellNameError("B")).Error())
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddTable.xlsx")))
// Test addTable with illegal cell coordinates.
// Test addTable with illegal cell reference.
f = NewFile()
assert.EqualError(t, f.addTable("sheet1", "", 0, 0, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
assert.EqualError(t, f.addTable("sheet1", "", 1, 1, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
assert.EqualError(t, f.addTable("sheet1", "", 0, 0, 0, 0, 0, nil), "invalid cell reference [0, 0]")
assert.EqualError(t, f.addTable("sheet1", "", 1, 1, 0, 0, 0, nil), "invalid cell reference [0, 0]")
}
func TestSetTableHeader(t *testing.T) {
f := NewFile()
_, err := f.setTableHeader("Sheet1", 1, 0, 1)
assert.EqualError(t, err, "invalid cell coordinates [1, 0]")
assert.EqualError(t, err, "invalid cell reference [1, 0]")
}
func TestAutoFilter(t *testing.T) {
@ -78,7 +78,7 @@ func TestAutoFilter(t *testing.T) {
})
}
// Test AutoFilter with illegal cell coordinates.
// Test AutoFilter with illegal cell reference.
assert.EqualError(t, f.AutoFilter("Sheet1", "A", "B1", ""), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.EqualError(t, f.AutoFilter("Sheet1", "A1", "B", ""), newCellNameToCoordinatesError("B", newInvalidCellNameError("B")).Error())
}

View File

@ -15,13 +15,13 @@ import "encoding/xml"
// AppProperties directly maps the document application properties.
type AppProperties struct {
Application string
ScaleCrop bool
DocSecurity int
Company string
LinksUpToDate bool
HyperlinksChanged bool
AppVersion string
Application string `json:"application"`
ScaleCrop bool `json:"scale_crop"`
DocSecurity int `json:"doc_security"`
Company string `json:"company"`
LinksUpToDate bool `json:"links_up_to_date"`
HyperlinksChanged bool `json:"hyperlinks_changed"`
AppVersion string `json:"app_version"`
}
// xlsxProperties specifies to an OOXML document properties such as the