2019-12-29 16:02:31 +08:00
|
|
|
// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
|
2018-09-14 00:44:23 +08:00
|
|
|
// this source code is governed by a BSD-style license that can be found in
|
|
|
|
// the LICENSE file.
|
|
|
|
//
|
|
|
|
// Package excelize providing a set of functions that allow you to write to
|
|
|
|
// and read from XLSX files. Support reads and writes XLSX file generated by
|
|
|
|
// Microsoft Excel™ 2007 and later. Support save file without losing original
|
2019-08-11 00:36:14 +08:00
|
|
|
// charts of XLSX. This library needs Go version 1.10 or later.
|
2018-09-14 00:58:48 +08:00
|
|
|
|
2016-08-30 21:54:28 +08:00
|
|
|
package excelize
|
|
|
|
|
|
|
|
import (
|
2017-07-24 10:26:02 +08:00
|
|
|
"encoding/xml"
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
"errors"
|
2017-07-24 10:26:02 +08:00
|
|
|
"fmt"
|
2018-03-12 20:14:39 +08:00
|
|
|
"reflect"
|
2016-08-30 21:54:28 +08:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2019-11-14 14:30:25 +08:00
|
|
|
"sync"
|
2017-07-24 10:26:02 +08:00
|
|
|
"time"
|
2016-08-30 21:54:28 +08:00
|
|
|
)
|
|
|
|
|
2018-05-26 16:23:15 +08:00
|
|
|
const (
|
|
|
|
// STCellFormulaTypeArray defined the formula is an array formula.
|
|
|
|
STCellFormulaTypeArray = "array"
|
|
|
|
// STCellFormulaTypeDataTable defined the formula is a data table formula.
|
|
|
|
STCellFormulaTypeDataTable = "dataTable"
|
|
|
|
// STCellFormulaTypeNormal defined the formula is a regular cell formula.
|
|
|
|
STCellFormulaTypeNormal = "normal"
|
|
|
|
// STCellFormulaTypeShared defined the formula is part of a shared formula.
|
|
|
|
STCellFormulaTypeShared = "shared"
|
|
|
|
)
|
|
|
|
|
2019-11-14 14:30:25 +08:00
|
|
|
var rwMutex sync.RWMutex
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// GetCellValue provides a function to get formatted value from cell by given
|
|
|
|
// worksheet name and axis in XLSX 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.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) GetCellValue(sheet, axis string) (string, error) {
|
|
|
|
return f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
val, err := c.getValueFrom(f, f.sharedStringsReader())
|
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return val, false, err
|
2017-01-25 18:13:11 +08:00
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return val, true, err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
})
|
2017-05-24 14:17:35 +08:00
|
|
|
}
|
|
|
|
|
2019-12-25 00:00:50 +08:00
|
|
|
// SetCellValue provides a function to set value of a cell. The specified
|
|
|
|
// coordinates should not be in the first row of the table. The following
|
2018-08-06 10:21:24 +08:00
|
|
|
// shows the supported data types:
|
2017-07-24 10:26:02 +08:00
|
|
|
//
|
|
|
|
// int
|
|
|
|
// int8
|
|
|
|
// int16
|
|
|
|
// int32
|
|
|
|
// int64
|
2017-10-18 18:42:20 +08:00
|
|
|
// uint
|
|
|
|
// uint8
|
|
|
|
// uint16
|
|
|
|
// uint32
|
|
|
|
// uint64
|
2017-07-24 10:26:02 +08:00
|
|
|
// float32
|
|
|
|
// float64
|
|
|
|
// string
|
|
|
|
// []byte
|
2018-01-05 09:39:31 +08:00
|
|
|
// time.Duration
|
2017-07-24 10:26:02 +08:00
|
|
|
// time.Time
|
2018-01-26 01:06:40 +08:00
|
|
|
// bool
|
2017-07-24 10:26:02 +08:00
|
|
|
// 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.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellValue(sheet, axis string, value interface{}) error {
|
2019-04-16 10:57:21 +08:00
|
|
|
var err error
|
|
|
|
switch v := value.(type) {
|
|
|
|
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
|
|
|
err = f.setCellIntFunc(sheet, axis, v)
|
|
|
|
case float32:
|
|
|
|
err = f.SetCellFloat(sheet, axis, float64(v), -1, 32)
|
|
|
|
case float64:
|
|
|
|
err = f.SetCellFloat(sheet, axis, v, -1, 64)
|
|
|
|
case string:
|
|
|
|
err = f.SetCellStr(sheet, axis, v)
|
|
|
|
case []byte:
|
|
|
|
err = f.SetCellStr(sheet, axis, string(v))
|
|
|
|
case time.Duration:
|
2019-12-29 12:45:10 +08:00
|
|
|
_, d := setCellDuration(v)
|
|
|
|
err = f.SetCellDefault(sheet, axis, d)
|
2019-04-16 10:57:21 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = f.setDefaultTimeStyle(sheet, axis, 21)
|
|
|
|
case time.Time:
|
|
|
|
err = f.setCellTimeFunc(sheet, axis, v)
|
|
|
|
case bool:
|
|
|
|
err = f.SetCellBool(sheet, axis, v)
|
|
|
|
case nil:
|
|
|
|
err = f.SetCellStr(sheet, axis, "")
|
|
|
|
default:
|
2019-08-13 21:39:12 +08:00
|
|
|
err = f.SetCellStr(sheet, axis, fmt.Sprint(value))
|
2019-04-16 10:57:21 +08:00
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// setCellIntFunc is a wrapper of SetCellInt.
|
|
|
|
func (f *File) setCellIntFunc(sheet, axis string, value interface{}) error {
|
2019-04-15 11:22:57 +08:00
|
|
|
var err error
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
switch v := value.(type) {
|
2017-07-24 10:26:02 +08:00
|
|
|
case int:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, v)
|
2017-07-24 10:26:02 +08:00
|
|
|
case int8:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-07-24 10:26:02 +08:00
|
|
|
case int16:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-07-24 10:26:02 +08:00
|
|
|
case int32:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-07-24 10:26:02 +08:00
|
|
|
case int64:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-10-18 18:42:20 +08:00
|
|
|
case uint:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-10-18 18:42:20 +08:00
|
|
|
case uint8:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-10-18 18:42:20 +08:00
|
|
|
case uint16:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-10-18 18:42:20 +08:00
|
|
|
case uint32:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2017-10-18 18:42:20 +08:00
|
|
|
case uint64:
|
2019-04-15 11:22:57 +08:00
|
|
|
err = f.SetCellInt(sheet, axis, int(v))
|
2019-04-16 10:57:21 +08:00
|
|
|
}
|
|
|
|
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 {
|
2019-12-29 12:45:10 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
2019-04-16 10:57:21 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-12-29 12:45:10 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
|
|
|
|
|
|
|
|
var isNum bool
|
|
|
|
cellData.T, cellData.V, isNum, err = setCellTime(value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if isNum {
|
2019-04-16 10:57:21 +08:00
|
|
|
err = f.setDefaultTimeStyle(sheet, axis, 22)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
2019-04-15 11:22:57 +08:00
|
|
|
return err
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
|
|
|
|
2019-12-29 12:45:10 +08:00
|
|
|
func setCellTime(value time.Time) (t string, b string, isNum bool, err error) {
|
|
|
|
var excelTime float64
|
|
|
|
excelTime, err = timeToExcelTime(value)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
isNum = excelTime > 0
|
|
|
|
if isNum {
|
|
|
|
t, b = setCellDefault(strconv.FormatFloat(excelTime, 'f', -1, 64))
|
|
|
|
} else {
|
|
|
|
t, b = setCellDefault(value.Format(time.RFC3339Nano))
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func setCellDuration(value time.Duration) (t string, v string) {
|
|
|
|
v = strconv.FormatFloat(value.Seconds()/86400.0, 'f', -1, 32)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// SetCellInt provides a function to set int type value of a cell by given
|
2018-01-26 01:06:40 +08:00
|
|
|
// worksheet name, cell coordinates and cell value.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellInt(sheet, axis string, value int) error {
|
2019-11-14 14:30:25 +08:00
|
|
|
rwMutex.Lock()
|
|
|
|
defer rwMutex.Unlock()
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
|
2019-12-29 12:45:10 +08:00
|
|
|
cellData.T, cellData.V = setCellInt(value)
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2018-01-26 01:06:40 +08:00
|
|
|
|
2019-12-29 12:45:10 +08:00
|
|
|
func setCellInt(value int) (t string, v string) {
|
|
|
|
v = strconv.Itoa(value)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// SetCellBool provides a function to set bool type value of a cell by given
|
|
|
|
// worksheet name, cell name and cell value.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellBool(sheet, axis string, value bool) error {
|
2019-11-14 14:30:25 +08:00
|
|
|
rwMutex.Lock()
|
|
|
|
defer rwMutex.Unlock()
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
|
2019-12-29 12:45:10 +08:00
|
|
|
cellData.T, cellData.V = setCellBool(value)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func setCellBool(value bool) (t string, v string) {
|
|
|
|
t = "b"
|
2018-01-26 01:06:40 +08:00
|
|
|
if value {
|
2019-12-29 12:45:10 +08:00
|
|
|
v = "1"
|
2018-01-26 01:06:40 +08:00
|
|
|
} else {
|
2019-12-29 12:45:10 +08:00
|
|
|
v = "0"
|
2018-01-26 01:06:40 +08:00
|
|
|
}
|
2019-12-29 12:45:10 +08:00
|
|
|
return
|
2018-01-26 01:06:40 +08:00
|
|
|
}
|
|
|
|
|
2019-03-21 11:41:46 +08:00
|
|
|
// SetCellFloat sets a floating point value into a cell. The prec parameter
|
2019-03-21 14:09:25 +08:00
|
|
|
// 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)
|
|
|
|
//
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellFloat(sheet, axis string, value float64, prec, bitSize int) error {
|
2019-11-14 14:30:25 +08:00
|
|
|
rwMutex.Lock()
|
|
|
|
defer rwMutex.Unlock()
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-21 11:41:46 +08:00
|
|
|
cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
|
2019-12-29 12:45:10 +08:00
|
|
|
cellData.T, cellData.V = setCellFloat(value, prec, bitSize)
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2019-03-21 11:41:46 +08:00
|
|
|
}
|
|
|
|
|
2019-12-29 12:45:10 +08:00
|
|
|
func setCellFloat(value float64, prec, bitSize int) (t string, v string) {
|
|
|
|
v = strconv.FormatFloat(value, 'f', prec, bitSize)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// SetCellStr provides a function to set string type value of a cell. Total
|
|
|
|
// number of characters that a cell can contain 32767 characters.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellStr(sheet, axis, value string) error {
|
2019-11-14 14:30:25 +08:00
|
|
|
rwMutex.Lock()
|
|
|
|
defer rwMutex.Unlock()
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-12-29 12:45:10 +08:00
|
|
|
cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
|
2020-05-26 02:09:39 +08:00
|
|
|
cellData.T, cellData.V, cellData.XMLSpace = f.setCellString(value)
|
2019-12-29 12:45:10 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-05-26 02:09:39 +08:00
|
|
|
// setCellString provides a function to set string type to shared string
|
|
|
|
// table.
|
|
|
|
func (f *File) setCellString(value string) (t string, v string, ns xml.Attr) {
|
|
|
|
if len(value) > 32767 {
|
|
|
|
value = value[0:32767]
|
|
|
|
}
|
|
|
|
// Leading and ending space(s) character detection.
|
|
|
|
if len(value) > 0 && (value[0] == 32 || value[len(value)-1] == 32) {
|
|
|
|
ns = xml.Attr{
|
|
|
|
Name: xml.Name{Space: NameSpaceXML, Local: "space"},
|
|
|
|
Value: "preserve",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t = "s"
|
|
|
|
v = strconv.Itoa(f.setSharedString(value))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// setSharedString provides a function to add string to the share string table.
|
|
|
|
func (f *File) setSharedString(val string) int {
|
|
|
|
sst := f.sharedStringsReader()
|
|
|
|
for i, si := range sst.SI {
|
|
|
|
if si.T == val {
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sst.Count++
|
|
|
|
sst.UniqueCount++
|
|
|
|
sst.SI = append(sst.SI, xlsxSI{T: val})
|
|
|
|
return sst.UniqueCount - 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// setCellStr provides a function to set string type to cell.
|
2019-12-29 12:45:10 +08:00
|
|
|
func setCellStr(value string) (t string, v string, ns xml.Attr) {
|
2019-04-14 12:55:44 +08:00
|
|
|
if len(value) > 32767 {
|
|
|
|
value = value[0:32767]
|
|
|
|
}
|
2019-10-16 01:03:29 +08:00
|
|
|
// Leading and ending space(s) character detection.
|
2019-10-10 20:04:33 +08:00
|
|
|
if len(value) > 0 && (value[0] == 32 || value[len(value)-1] == 32) {
|
2019-12-29 12:45:10 +08:00
|
|
|
ns = xml.Attr{
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
Name: xml.Name{Space: NameSpaceXML, Local: "space"},
|
|
|
|
Value: "preserve",
|
2016-12-24 22:47:36 +08:00
|
|
|
}
|
|
|
|
}
|
2019-12-29 12:45:10 +08:00
|
|
|
t = "str"
|
|
|
|
v = value
|
|
|
|
return
|
2017-05-05 14:40:28 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// SetCellDefault provides a function to set string type value of a cell as
|
|
|
|
// default format without escaping the cell.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellDefault(sheet, axis, value string) error {
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
|
2019-12-29 12:45:10 +08:00
|
|
|
cellData.T, cellData.V = setCellDefault(value)
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
|
|
|
|
2019-12-29 12:45:10 +08:00
|
|
|
func setCellDefault(value string) (t string, v string) {
|
|
|
|
v = value
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-06 10:21:24 +08:00
|
|
|
// GetCellFormula provides a function to get formula from cell by given
|
|
|
|
// worksheet name and axis in XLSX file.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) GetCellFormula(sheet, axis string) (string, error) {
|
|
|
|
return f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if c.F == nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return "", false, nil
|
2016-08-30 21:54:28 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if c.F.T == STCellFormulaTypeShared {
|
2019-03-23 20:08:06 +08:00
|
|
|
return getSharedForumula(x, c.F.Si), true, nil
|
2018-05-26 16:23:15 +08:00
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return c.F.Content, true, nil
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
})
|
2018-05-26 16:23:15 +08:00
|
|
|
}
|
|
|
|
|
2019-09-22 20:52:01 +08:00
|
|
|
// FormulaOpts can be passed to SetCellFormula to use other formula types.
|
|
|
|
type FormulaOpts struct {
|
|
|
|
Type *string // Formula type
|
|
|
|
Ref *string // Shared formula ref
|
|
|
|
}
|
|
|
|
|
2018-08-06 10:21:24 +08:00
|
|
|
// SetCellFormula provides a function to set cell formula by given string and
|
2017-10-31 16:33:36 +08:00
|
|
|
// worksheet name.
|
2019-09-22 20:52:01 +08:00
|
|
|
func (f *File) SetCellFormula(sheet, axis, formula string, opts ...FormulaOpts) error {
|
2019-11-14 14:30:25 +08:00
|
|
|
rwMutex.Lock()
|
|
|
|
defer rwMutex.Unlock()
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
cellData, _, _, err := f.prepareCell(xlsx, sheet, axis)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-02-22 22:17:38 +08:00
|
|
|
if formula == "" {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
cellData.F = nil
|
2020-04-23 02:01:14 +08:00
|
|
|
f.deleteCalcChain(f.getSheetID(sheet), axis)
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2019-02-22 22:17:38 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
|
|
|
|
if cellData.F != nil {
|
|
|
|
cellData.F.Content = formula
|
2017-01-19 14:05:32 +08:00
|
|
|
} else {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
cellData.F = &xlsxF{Content: formula}
|
|
|
|
}
|
2019-09-22 20:52:01 +08:00
|
|
|
|
|
|
|
for _, o := range opts {
|
|
|
|
if o.Type != nil {
|
|
|
|
cellData.F.T = *o.Type
|
|
|
|
}
|
|
|
|
|
|
|
|
if o.Ref != nil {
|
|
|
|
cellData.F.Ref = *o.Ref
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetCellHyperLink provides a function to get cell hyperlink by given
|
|
|
|
// worksheet name and axis. Boolean type value link will be ture if the cell
|
|
|
|
// has a hyperlink and the target is the address of the hyperlink. Otherwise,
|
|
|
|
// the value of link will be false and the value of the target will be a blank
|
|
|
|
// string. For example get hyperlink of Sheet1!H6:
|
|
|
|
//
|
2019-04-20 14:57:50 +08:00
|
|
|
// link, target, err := f.GetCellHyperLink("Sheet1", "H6")
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
//
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error) {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// Check for correct cell name
|
|
|
|
if _, _, err := SplitCellName(axis); err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return false, "", err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return false, "", err
|
|
|
|
}
|
|
|
|
axis, err = f.mergeCellsParser(xlsx, axis)
|
2019-03-23 20:08:06 +08:00
|
|
|
if err != nil {
|
|
|
|
return false, "", err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if xlsx.Hyperlinks != nil {
|
|
|
|
for _, link := range xlsx.Hyperlinks.Hyperlink {
|
|
|
|
if link.Ref == axis {
|
|
|
|
if link.RID != "" {
|
2019-03-23 20:08:06 +08:00
|
|
|
return true, f.getSheetRelationshipsTargetByID(sheet, link.RID), err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return true, link.Location, err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2017-01-19 14:05:32 +08:00
|
|
|
}
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return false, "", err
|
2017-01-19 14:05:32 +08:00
|
|
|
}
|
2017-01-23 16:15:01 +08:00
|
|
|
|
2018-08-06 10:21:24 +08:00
|
|
|
// SetCellHyperLink provides a function to set cell hyperlink by given
|
|
|
|
// worksheet name and link URL address. LinkType defines two types of
|
|
|
|
// hyperlink "External" for web site or "Location" for moving to one of cell
|
2019-04-21 00:04:42 +08:00
|
|
|
// in this workbook. Maximum limit hyperlinks in a worksheet is 65530. The
|
|
|
|
// below is example for external link.
|
2017-07-26 18:37:00 +08:00
|
|
|
//
|
2019-04-20 14:57:50 +08:00
|
|
|
// err := f.SetCellHyperLink("Sheet1", "A3", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
|
2017-07-26 18:37:00 +08:00
|
|
|
// // Set underline and font color style for the cell.
|
2019-04-20 14:57:50 +08:00
|
|
|
// style, err := f.NewStyle(`{"font":{"color":"#1265BE","underline":"single"}}`)
|
|
|
|
// err = f.SetCellStyle("Sheet1", "A3", "A3", style)
|
2017-07-26 18:37:00 +08:00
|
|
|
//
|
2017-07-30 15:46:04 +08:00
|
|
|
// A this is another example for "Location":
|
2017-07-30 13:52:37 +08:00
|
|
|
//
|
2019-04-20 14:57:50 +08:00
|
|
|
// err := f.SetCellHyperLink("Sheet1", "A3", "Sheet1!A40", "Location")
|
2017-07-30 15:46:04 +08:00
|
|
|
//
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetCellHyperLink(sheet, axis, link, linkType string) error {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// Check for correct cell name
|
|
|
|
if _, _, err := SplitCellName(axis); err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2017-07-30 15:46:04 +08:00
|
|
|
}
|
2017-01-25 15:44:18 +08:00
|
|
|
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
axis, err = f.mergeCellsParser(xlsx, axis)
|
2019-03-23 20:08:06 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
|
|
|
|
var linkData xlsxHyperlink
|
|
|
|
|
2019-04-21 00:04:42 +08:00
|
|
|
if xlsx.Hyperlinks == nil {
|
|
|
|
xlsx.Hyperlinks = new(xlsxHyperlinks)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(xlsx.Hyperlinks.Hyperlink) > 65529 {
|
|
|
|
return errors.New("over maximum limit hyperlinks in a worksheet")
|
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
switch linkType {
|
|
|
|
case "External":
|
|
|
|
linkData = xlsxHyperlink{
|
|
|
|
Ref: axis,
|
2017-08-08 20:08:54 +08:00
|
|
|
}
|
2019-12-23 00:07:40 +08:00
|
|
|
sheetPath := f.sheetMap[trimSheetName(sheet)]
|
2019-09-16 01:17:35 +08:00
|
|
|
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
|
|
|
|
rID := f.addRels(sheetRels, SourceRelationshipHyperLink, link, linkType)
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
linkData.RID = "rId" + strconv.Itoa(rID)
|
|
|
|
case "Location":
|
|
|
|
linkData = xlsxHyperlink{
|
|
|
|
Ref: axis,
|
|
|
|
Location: link,
|
|
|
|
}
|
|
|
|
default:
|
2019-03-23 20:08:06 +08:00
|
|
|
return fmt.Errorf("invalid link type %q", linkType)
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
xlsx.Hyperlinks.Hyperlink = append(xlsx.Hyperlinks.Hyperlink, linkData)
|
2019-03-23 20:08:06 +08:00
|
|
|
return nil
|
2017-08-08 20:08:54 +08:00
|
|
|
}
|
|
|
|
|
2020-04-06 00:23:27 +08:00
|
|
|
// SetCellRichText provides a function to set cell with rich text by given
|
2020-04-09 01:00:14 +08:00
|
|
|
// worksheet. For example, set rich text on the A1 cell of the worksheet named
|
|
|
|
// Sheet1:
|
2017-01-25 15:44:18 +08:00
|
|
|
//
|
2020-04-06 00:23:27 +08:00
|
|
|
// package main
|
2017-01-25 15:44:18 +08:00
|
|
|
//
|
2020-04-06 00:23:27 +08:00
|
|
|
// import (
|
|
|
|
// "fmt"
|
|
|
|
//
|
|
|
|
// "github.com/360EntSecGroup-Skylar/excelize"
|
|
|
|
// )
|
|
|
|
//
|
|
|
|
// func main() {
|
|
|
|
// f := excelize.NewFile()
|
|
|
|
// if err := f.SetRowHeight("Sheet1", 1, 35); err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// if err := f.SetColWidth("Sheet1", "A", "A", 44); err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// if err := f.SetCellRichText("Sheet1", "A1", []excelize.RichTextRun{
|
|
|
|
// {
|
|
|
|
// Text: "blod",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Bold: true,
|
|
|
|
// Color: "2354e8",
|
|
|
|
// Family: "Times New Roman",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: " and ",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Family: "Times New Roman",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: " italic",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Bold: true,
|
|
|
|
// Color: "e83723",
|
|
|
|
// Italic: true,
|
|
|
|
// Family: "Times New Roman",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: "text with color and font-family,",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Bold: true,
|
|
|
|
// Color: "2354e8",
|
|
|
|
// Family: "Times New Roman",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: "\r\nlarge text with ",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Size: 14,
|
|
|
|
// Color: "ad23e8",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: "strike",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Color: "e89923",
|
|
|
|
// Strike: true,
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: " and ",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Size: 14,
|
|
|
|
// Color: "ad23e8",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Text: "underline.",
|
|
|
|
// Font: &excelize.Font{
|
|
|
|
// Color: "23e833",
|
|
|
|
// Underline: "single",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// }); err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// style, err := f.NewStyle(&excelize.Style{
|
|
|
|
// Alignment: &excelize.Alignment{
|
|
|
|
// WrapText: true,
|
|
|
|
// },
|
|
|
|
// })
|
|
|
|
// if err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// if err := f.SetCellStyle("Sheet1", "A1", "A1", style); err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// if err := f.SaveAs("Book1.xlsx"); err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
|
|
|
|
ws, err := f.workSheetReader(sheet)
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2020-04-06 00:23:27 +08:00
|
|
|
cellData, col, _, err := f.prepareCell(ws, sheet, cell)
|
2019-04-15 11:22:57 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-04-06 00:23:27 +08:00
|
|
|
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
|
|
|
si := xlsxSI{}
|
|
|
|
sst := f.sharedStringsReader()
|
|
|
|
textRuns := []xlsxR{}
|
|
|
|
for _, textRun := range runs {
|
|
|
|
run := xlsxR{T: &xlsxT{Val: textRun.Text}}
|
|
|
|
if strings.ContainsAny(textRun.Text, "\r\n ") {
|
2020-05-26 02:09:39 +08:00
|
|
|
run.T.Space = xml.Attr{Name: xml.Name{Space: NameSpaceXML, Local: "space"}, Value: "preserve"}
|
2020-04-06 00:23:27 +08:00
|
|
|
}
|
|
|
|
fnt := textRun.Font
|
|
|
|
if fnt != nil {
|
|
|
|
rpr := xlsxRPr{}
|
|
|
|
if fnt.Bold {
|
|
|
|
rpr.B = " "
|
|
|
|
}
|
|
|
|
if fnt.Italic {
|
|
|
|
rpr.I = " "
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2020-04-06 00:23:27 +08:00
|
|
|
if fnt.Strike {
|
|
|
|
rpr.Strike = " "
|
2017-01-25 15:44:18 +08:00
|
|
|
}
|
2020-04-06 00:23:27 +08:00
|
|
|
if fnt.Underline != "" {
|
|
|
|
rpr.U = &attrValString{Val: &fnt.Underline}
|
|
|
|
}
|
|
|
|
if fnt.Family != "" {
|
|
|
|
rpr.RFont = &attrValString{Val: &fnt.Family}
|
|
|
|
}
|
|
|
|
if fnt.Size > 0.0 {
|
|
|
|
rpr.Sz = &attrValFloat{Val: &fnt.Size}
|
|
|
|
}
|
|
|
|
if fnt.Color != "" {
|
|
|
|
rpr.Color = &xlsxColor{RGB: getPaletteColor(fnt.Color)}
|
|
|
|
}
|
|
|
|
run.RPr = &rpr
|
|
|
|
}
|
|
|
|
textRuns = append(textRuns, run)
|
|
|
|
}
|
|
|
|
si.R = textRuns
|
|
|
|
sst.SI = append(sst.SI, si)
|
|
|
|
sst.Count++
|
|
|
|
sst.UniqueCount++
|
|
|
|
cellData.T, cellData.V = "s", strconv.Itoa(len(sst.SI)-1)
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2017-01-25 15:44:18 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// SetSheetRow writes an array to row by given worksheet name, starting
|
|
|
|
// coordinate and a pointer to array type 'slice'. For example, writes an
|
|
|
|
// array to row 6 start with the cell B6 on Sheet1:
|
|
|
|
//
|
2019-04-20 14:57:50 +08:00
|
|
|
// err := f.SetSheetRow("Sheet1", "B6", &[]interface{}{"1", nil, 2})
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
//
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) SetSheetRow(sheet, axis string, slice interface{}) error {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
col, row, err := CellNameToCoordinates(axis)
|
2017-09-19 11:59:33 +08:00
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2017-09-19 11:59:33 +08:00
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// Make sure 'slice' is a Ptr to Slice
|
|
|
|
v := reflect.ValueOf(slice)
|
|
|
|
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Slice {
|
2019-03-23 20:08:06 +08:00
|
|
|
return errors.New("pointer to slice expected")
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
v = v.Elem()
|
2017-07-24 10:26:02 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
for i := 0; i < v.Len(); i++ {
|
|
|
|
cell, err := CoordinatesToCellName(col+i, row)
|
2019-08-19 15:53:56 +08:00
|
|
|
// Error should never happens here. But keep checking to early detect regresions
|
|
|
|
// if it will be introduced in future.
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
2019-08-19 15:53:56 +08:00
|
|
|
if err := f.SetCellValue(sheet, cell, v.Index(i).Interface()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return err
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// getCellInfo does common preparation for all SetCell* methods.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) prepareCell(xlsx *xlsxWorksheet, sheet, cell string) (*xlsxC, int, int, error) {
|
|
|
|
var err error
|
|
|
|
cell, err = f.mergeCellsParser(xlsx, cell)
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, 0, err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
col, row, err := CellNameToCoordinates(cell)
|
2017-09-19 11:59:33 +08:00
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return nil, 0, 0, err
|
2017-09-19 11:59:33 +08:00
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
prepareSheetXML(xlsx, col, row)
|
2017-07-24 10:26:02 +08:00
|
|
|
|
2019-03-23 20:08:06 +08:00
|
|
|
return &xlsx.SheetData.Row[row-1].C[col-1], col, row, err
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
|
|
|
|
2019-03-23 20:08:06 +08:00
|
|
|
// 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) {
|
2019-04-15 11:22:57 +08:00
|
|
|
xlsx, err := f.workSheetReader(sheet)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
axis, err = f.mergeCellsParser(xlsx, axis)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
_, row, err := CellNameToCoordinates(axis)
|
2017-09-19 11:59:33 +08:00
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return "", err
|
2017-09-19 11:59:33 +08:00
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
lastRowNum := 0
|
|
|
|
if l := len(xlsx.SheetData.Row); l > 0 {
|
|
|
|
lastRowNum = xlsx.SheetData.Row[l-1].R
|
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// keep in mind: row starts from 1
|
|
|
|
if row > lastRowNum {
|
2019-03-23 20:08:06 +08:00
|
|
|
return "", nil
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2017-07-24 10:26:02 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
for rowIdx := range xlsx.SheetData.Row {
|
|
|
|
rowData := &xlsx.SheetData.Row[rowIdx]
|
|
|
|
if rowData.R != row {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for colIdx := range rowData.C {
|
|
|
|
colData := &rowData.C[colIdx]
|
|
|
|
if axis != colData.R {
|
|
|
|
continue
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
val, ok, err := fn(xlsx, colData)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if ok {
|
|
|
|
return val, nil
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return "", nil
|
2017-07-24 10:26:02 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// formattedValue provides a function to returns a value after formatted. 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.
|
|
|
|
func (f *File) formattedValue(s int, v string) string {
|
|
|
|
if s == 0 {
|
|
|
|
return v
|
2018-03-12 20:14:39 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
styleSheet := f.stylesReader()
|
2020-05-10 16:56:08 +08:00
|
|
|
ok := builtInNumFmtFunc[*styleSheet.CellXfs.Xf[s].NumFmtID]
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
if ok != nil {
|
2020-05-10 16:56:08 +08:00
|
|
|
return ok(*styleSheet.CellXfs.Xf[s].NumFmtID, v)
|
2018-03-12 20:14:39 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
return v
|
|
|
|
}
|
2018-03-12 20:14:39 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// prepareCellStyle provides a function to prepare style index of cell in
|
|
|
|
// worksheet by given column index and style index.
|
|
|
|
func (f *File) prepareCellStyle(xlsx *xlsxWorksheet, col, style int) int {
|
|
|
|
if xlsx.Cols != nil && style == 0 {
|
|
|
|
for _, c := range xlsx.Cols.Col {
|
|
|
|
if c.Min <= col && col <= c.Max {
|
|
|
|
style = c.Style
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return style
|
|
|
|
}
|
2018-03-12 20:14:39 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// mergeCellsParser provides a function to check merged cells in worksheet by
|
|
|
|
// given axis.
|
2019-03-23 20:08:06 +08:00
|
|
|
func (f *File) mergeCellsParser(xlsx *xlsxWorksheet, axis string) (string, error) {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
axis = strings.ToUpper(axis)
|
|
|
|
if xlsx.MergeCells != nil {
|
|
|
|
for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
|
2019-12-14 19:57:37 +08:00
|
|
|
ok, err := f.checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref)
|
2019-03-23 20:08:06 +08:00
|
|
|
if err != nil {
|
|
|
|
return axis, err
|
|
|
|
}
|
|
|
|
if ok {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
|
|
|
|
}
|
|
|
|
}
|
2018-03-12 20:14:39 +08:00
|
|
|
}
|
2019-03-23 20:08:06 +08:00
|
|
|
return axis, nil
|
2018-03-12 20:14:39 +08:00
|
|
|
}
|
|
|
|
|
2018-08-06 10:21:24 +08:00
|
|
|
// checkCellInArea provides a function to determine if a given coordinate is
|
2017-01-25 15:44:18 +08:00
|
|
|
// within an area.
|
2019-12-14 19:57:37 +08:00
|
|
|
func (f *File) checkCellInArea(cell, area string) (bool, error) {
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
col, row, err := CellNameToCoordinates(cell)
|
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
return false, err
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2017-01-25 15:44:18 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
rng := strings.Split(area, ":")
|
|
|
|
if len(rng) != 2 {
|
2019-03-23 20:08:06 +08:00
|
|
|
return false, err
|
2018-04-08 10:31:11 +08:00
|
|
|
}
|
2019-12-14 19:57:37 +08:00
|
|
|
coordinates, err := f.areaRefToCoordinates(area)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
2018-04-08 10:31:11 +08:00
|
|
|
|
2019-12-14 19:57:37 +08:00
|
|
|
return cellInRef([]int{col, row}, coordinates), err
|
|
|
|
}
|
2018-04-08 10:31:11 +08:00
|
|
|
|
2019-12-14 19:57:37 +08:00
|
|
|
// cellInRef provides a function to determine if a given range is within an
|
|
|
|
// range.
|
|
|
|
func cellInRef(cell, ref []int) bool {
|
|
|
|
return cell[0] >= ref[0] && cell[0] <= ref[2] && cell[1] >= ref[1] && cell[1] <= ref[3]
|
|
|
|
}
|
2017-01-25 15:44:18 +08:00
|
|
|
|
2019-12-14 19:57:37 +08:00
|
|
|
// isOverlap find if the given two rectangles overlap or not.
|
|
|
|
func isOverlap(rect1, rect2 []int) bool {
|
|
|
|
return cellInRef([]int{rect1[0], rect1[1]}, rect2) ||
|
|
|
|
cellInRef([]int{rect1[2], rect1[1]}, rect2) ||
|
|
|
|
cellInRef([]int{rect1[0], rect1[3]}, rect2) ||
|
|
|
|
cellInRef([]int{rect1[2], rect1[3]}, rect2) ||
|
|
|
|
cellInRef([]int{rect2[0], rect2[1]}, rect1) ||
|
|
|
|
cellInRef([]int{rect2[2], rect2[1]}, rect1) ||
|
|
|
|
cellInRef([]int{rect2[0], rect2[3]}, rect1) ||
|
|
|
|
cellInRef([]int{rect2[2], rect2[3]}, rect1)
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2017-01-25 15:44:18 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
// getSharedForumula find a cell contains the same formula as another cell,
|
|
|
|
// the "shared" value can be used for the t attribute and the si attribute can
|
|
|
|
// be used to refer to the cell containing the formula. Two formulas are
|
|
|
|
// considered to be the same when their respective representations in
|
|
|
|
// R1C1-reference notation, are the same.
|
|
|
|
//
|
|
|
|
// Note that this function not validate ref tag to check the cell if or not in
|
|
|
|
// allow area, and always return origin shared formula.
|
|
|
|
func getSharedForumula(xlsx *xlsxWorksheet, si string) string {
|
|
|
|
for _, r := range xlsx.SheetData.Row {
|
|
|
|
for _, c := range r.C {
|
|
|
|
if c.F != nil && c.F.Ref != "" && c.F.T == STCellFormulaTypeShared && c.F.Si == si {
|
|
|
|
return c.F.Content
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
2017-01-25 15:44:18 +08:00
|
|
|
}
|