Skip to content

Commit

Permalink
This closes qax-os#1360, closes qax-os#1361
Browse files Browse the repository at this point in the history
- Fix default number format parse issue with a long string of digits
- Fix creating a sheet with an empty name cause a corrupted file
- The `GetCellStyle` function no longer return master cell style of the merge cell range
- Using the specialized name in variables and functions
  • Loading branch information
xuri committed Sep 27, 2022
1 parent addcc1a commit efcf599
Show file tree
Hide file tree
Showing 23 changed files with 126 additions and 145 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func main() {
fmt.Println(err)
}
}()
// Get value from cell by given worksheet name and axis.
// Get value from cell by given worksheet name and cell reference.
cell, err := f.GetCellValue("Sheet1", "B2")
if err != nil {
fmt.Println(err)
Expand Down
16 changes: 8 additions & 8 deletions adjust.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (f *File) adjustTable(ws *xlsxWorksheet, sheet string, dir adjustDirection,
Decode(&t); err != nil && err != io.EOF {
return
}
coordinates, err := areaRefToCoordinates(t.Ref)
coordinates, err := rangeRefToCoordinates(t.Ref)
if err != nil {
return
}
Expand All @@ -204,7 +204,7 @@ func (f *File) adjustTable(ws *xlsxWorksheet, sheet string, dir adjustDirection,
idx--
continue
}
t.Ref, _ = f.coordinatesToAreaRef([]int{x1, y1, x2, y2})
t.Ref, _ = f.coordinatesToRangeRef([]int{x1, y1, x2, y2})
if t.AutoFilter != nil {
t.AutoFilter.Ref = t.Ref
}
Expand All @@ -221,7 +221,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
return nil
}

coordinates, err := areaRefToCoordinates(ws.AutoFilter.Ref)
coordinates, err := rangeRefToCoordinates(ws.AutoFilter.Ref)
if err != nil {
return err
}
Expand All @@ -241,7 +241,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
coordinates = f.adjustAutoFilterHelper(dir, coordinates, num, offset)
x1, y1, x2, y2 = coordinates[0], coordinates[1], coordinates[2], coordinates[3]

if ws.AutoFilter.Ref, err = f.coordinatesToAreaRef([]int{x1, y1, x2, y2}); err != nil {
if ws.AutoFilter.Ref, err = f.coordinatesToRangeRef([]int{x1, y1, x2, y2}); err != nil {
return err
}
return nil
Expand Down Expand Up @@ -277,8 +277,8 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
}

for i := 0; i < len(ws.MergeCells.Cells); i++ {
areaData := ws.MergeCells.Cells[i]
coordinates, err := areaRefToCoordinates(areaData.Ref)
mergedCells := ws.MergeCells.Cells[i]
coordinates, err := rangeRefToCoordinates(mergedCells.Ref)
if err != nil {
return err
}
Expand All @@ -305,8 +305,8 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
i--
continue
}
areaData.rect = []int{x1, y1, x2, y2}
if areaData.Ref, err = f.coordinatesToAreaRef([]int{x1, y1, x2, y2}); err != nil {
mergedCells.rect = []int{x1, y1, x2, y2}
if mergedCells.Ref, err = f.coordinatesToRangeRef([]int{x1, y1, x2, y2}); err != nil {
return err
}
}
Expand Down
20 changes: 12 additions & 8 deletions calc.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,10 +789,14 @@ func (f *File) calcCellValue(ctx *calcContext, sheet, cell string) (result strin
return
}
result = token.Value()
isNum, precision := isNumeric(result)
if isNum && (precision > 15 || precision == 0) {
num := roundPrecision(result, -1)
result = strings.ToUpper(num)
if isNum, precision, decimal := isNumeric(result); isNum {
if precision > 15 {
result = strings.ToUpper(strconv.FormatFloat(decimal, 'G', 15, 64))
return
}
if !strings.HasPrefix(result, "0") {
result = strings.ToUpper(strconv.FormatFloat(decimal, 'f', -1, 64))
}
}
return
}
Expand Down Expand Up @@ -2089,13 +2093,13 @@ func (fn *formulaFuncs) COMPLEX(argsList *list.List) formulaArg {
// cmplx2str replace complex number string characters.
func cmplx2str(num complex128, suffix string) string {
realPart, imagPart := fmt.Sprint(real(num)), fmt.Sprint(imag(num))
isNum, i := isNumeric(realPart)
isNum, i, decimal := isNumeric(realPart)
if isNum && i > 15 {
realPart = roundPrecision(realPart, -1)
realPart = strconv.FormatFloat(decimal, 'G', 15, 64)
}
isNum, i = isNumeric(imagPart)
isNum, i, decimal = isNumeric(imagPart)
if isNum && i > 15 {
imagPart = roundPrecision(imagPart, -1)
imagPart = strconv.FormatFloat(decimal, 'G', 15, 64)
}
c := realPart
if imag(num) > 0 {
Expand Down
2 changes: 1 addition & 1 deletion calc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1736,7 +1736,7 @@ func TestCalcCellValue(t *testing.T) {
"=UPPER(\"TEST 123\")": "TEST 123",
// VALUE
"=VALUE(\"50\")": "50",
"=VALUE(\"1.0E-07\")": "1E-07",
"=VALUE(\"1.0E-07\")": "0.0000001",
"=VALUE(\"5,000\")": "5000",
"=VALUE(\"20%\")": "0.2",
"=VALUE(\"12:00:00\")": "0.5",
Expand Down
23 changes: 12 additions & 11 deletions cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ func (f *File) SetCellDefault(sheet, cell, value string) error {
// setCellDefault prepares cell type and string type cell value by a given
// string.
func setCellDefault(value string) (t string, v string) {
if ok, _ := isNumeric(value); !ok {
if ok, _, _ := isNumeric(value); !ok {
t = "str"
}
v = value
Expand Down Expand Up @@ -631,7 +631,7 @@ func (f *File) SetCellFormula(sheet, cell, formula string, opts ...FormulaOpts)

// setSharedFormula set shared formula for the cells.
func (ws *xlsxWorksheet) setSharedFormula(ref string) error {
coordinates, err := areaRefToCoordinates(ref)
coordinates, err := rangeRefToCoordinates(ref)
if err != nil {
return err
}
Expand Down Expand Up @@ -1098,7 +1098,7 @@ func (f *File) setSheetCells(sheet, cell string, slice interface{}, dir adjustDi
return err
}

// getCellInfo does common preparation for all SetCell* methods.
// getCellInfo does common preparation for all set cell value functions.
func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, error) {
var err error
cell, err = f.mergeCellsParser(ws, cell)
Expand All @@ -1116,8 +1116,9 @@ func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, er
return &ws.SheetData.Row[row-1].C[col-1], col, row, err
}

// getCellStringFunc does common value extraction workflow for all GetCell*
// methods. Passed function implements specific part of required logic.
// getCellStringFunc does common value extraction workflow for all get cell
// value function. Passed function implements specific part of required
// logic.
func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c *xlsxC) (string, bool, error)) (string, error) {
ws, err := f.workSheetReader(sheet)
if err != nil {
Expand Down Expand Up @@ -1235,7 +1236,7 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error)
i--
continue
}
ok, err := f.checkCellInArea(cell, ws.MergeCells.Cells[i].Ref)
ok, err := f.checkCellInRangeRef(cell, ws.MergeCells.Cells[i].Ref)
if err != nil {
return cell, err
}
Expand All @@ -1247,18 +1248,18 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error)
return cell, nil
}

// checkCellInArea provides a function to determine if a given cell reference
// checkCellInRangeRef provides a function to determine if a given cell reference
// in a range.
func (f *File) checkCellInArea(cell, area string) (bool, error) {
func (f *File) checkCellInRangeRef(cell, reference string) (bool, error) {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return false, err
}

if rng := strings.Split(area, ":"); len(rng) != 2 {
if rng := strings.Split(reference, ":"); len(rng) != 2 {
return false, err
}
coordinates, err := areaRefToCoordinates(area)
coordinates, err := rangeRefToCoordinates(reference)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -1333,7 +1334,7 @@ func parseSharedFormula(dCol, dRow int, orig []byte) (res string, start int) {
// R1C1-reference notation, are the same.
//
// Note that this function not validate ref tag to check the cell whether in
// allow area, and always return origin shared formula.
// allow range reference, and always return origin shared formula.
func getSharedFormula(ws *xlsxWorksheet, si int, cell string) string {
for _, r := range ws.SheetData.Row {
for _, c := range r.C {
Expand Down
38 changes: 21 additions & 17 deletions cell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,43 +95,43 @@ func TestConcurrency(t *testing.T) {
assert.NoError(t, f.Close())
}

func TestCheckCellInArea(t *testing.T) {
func TestCheckCellInRangeRef(t *testing.T) {
f := NewFile()
expectedTrueCellInAreaList := [][2]string{
expectedTrueCellInRangeRefList := [][2]string{
{"c2", "A1:AAZ32"},
{"B9", "A1:B9"},
{"C2", "C2:C2"},
}

for _, expectedTrueCellInArea := range expectedTrueCellInAreaList {
cell := expectedTrueCellInArea[0]
area := expectedTrueCellInArea[1]
ok, err := f.checkCellInArea(cell, area)
for _, expectedTrueCellInRangeRef := range expectedTrueCellInRangeRefList {
cell := expectedTrueCellInRangeRef[0]
reference := expectedTrueCellInRangeRef[1]
ok, err := f.checkCellInRangeRef(cell, reference)
assert.NoError(t, err)
assert.Truef(t, ok,
"Expected cell %v to be in area %v, got false\n", cell, area)
"Expected cell %v to be in range reference %v, got false\n", cell, reference)
}

expectedFalseCellInAreaList := [][2]string{
expectedFalseCellInRangeRefList := [][2]string{
{"c2", "A4:AAZ32"},
{"C4", "D6:A1"}, // weird case, but you never know
{"AEF42", "BZ40:AEF41"},
}

for _, expectedFalseCellInArea := range expectedFalseCellInAreaList {
cell := expectedFalseCellInArea[0]
area := expectedFalseCellInArea[1]
ok, err := f.checkCellInArea(cell, area)
for _, expectedFalseCellInRangeRef := range expectedFalseCellInRangeRefList {
cell := expectedFalseCellInRangeRef[0]
reference := expectedFalseCellInRangeRef[1]
ok, err := f.checkCellInRangeRef(cell, reference)
assert.NoError(t, err)
assert.Falsef(t, ok,
"Expected cell %v not to be inside of area %v, but got true\n", cell, area)
"Expected cell %v not to be inside of range reference %v, but got true\n", cell, reference)
}

ok, err := f.checkCellInArea("A1", "A:B")
ok, err := f.checkCellInRangeRef("A1", "A:B")
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.False(t, ok)

ok, err = f.checkCellInArea("AA0", "Z0:AB1")
ok, err = f.checkCellInRangeRef("AA0", "Z0:AB1")
assert.EqualError(t, err, newCellNameToCoordinatesError("AA0", newInvalidCellNameError("AA0")).Error())
assert.False(t, ok)
}
Expand Down Expand Up @@ -326,8 +326,10 @@ func TestGetCellValue(t *testing.T) {
<c r="Y1"><v>275.39999999999998</v></c>
<c r="Z1"><v>68.900000000000006</v></c>
<c r="AA1"><v>1.1000000000000001</v></c>
<c r="AA2"><v>1234567890123_4</v></c>
<c r="AA3"><v>123456789_0123_4</v></c>
<c r="AB1" t="str"><v>1234567890123_4</v></c>
<c r="AC1" t="str"><v>123456789_0123_4</v></c>
<c r="AD1"><v>+0.0000000000000000002399999999999992E-4</v></c>
<c r="AE1"><v>7.2399999999999992E-2</v></c>
</row>`)))
f.checked = nil
rows, err = f.GetRows("Sheet1")
Expand Down Expand Up @@ -361,6 +363,8 @@ func TestGetCellValue(t *testing.T) {
"1.1",
"1234567890123_4",
"123456789_0123_4",
"2.39999999999999E-23",
"0.0724",
}}, rows)
assert.NoError(t, err)
}
Expand Down
2 changes: 1 addition & 1 deletion col.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ func flatCols(col xlsxCol, cols []xlsxCol, replacer func(fc, c xlsxCol) xlsxCol)
// | | | (x2,y2)|
// +-----+------------+------------+
//
// Example of an object that covers some area from cell A1 to B2.
// Example of an object that covers some range reference from cell A1 to B2.
//
// Based on the width and height of the object we need to calculate 8 vars:
//
Expand Down
4 changes: 2 additions & 2 deletions datavalidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (f *File) squashSqref(cells [][]int) []string {
l, r := 0, 0
for i := 1; i < len(cells); i++ {
if cells[i][0] == cells[r][0] && cells[i][1]-cells[r][1] > 1 {
curr, _ := f.coordinatesToAreaRef(append(cells[l], cells[r]...))
curr, _ := f.coordinatesToRangeRef(append(cells[l], cells[r]...))
if l == r {
curr, _ = CoordinatesToCellName(cells[l][0], cells[l][1])
}
Expand All @@ -343,7 +343,7 @@ func (f *File) squashSqref(cells [][]int) []string {
r++
}
}
curr, _ := f.coordinatesToAreaRef(append(cells[l], cells[r]...))
curr, _ := f.coordinatesToRangeRef(append(cells[l], cells[r]...))
if l == r {
curr, _ = CoordinatesToCellName(cells[l][0], cells[l][1])
}
Expand Down
2 changes: 1 addition & 1 deletion excelize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ func TestSetCellStyleBorder(t *testing.T) {

var style int

// Test set border on overlapping area with vertical variants shading styles gradient fill.
// Test set border on overlapping range with vertical variants shading styles gradient fill.
style, err = f.NewStyle(&Style{
Border: []Border{
{Type: "left", Color: "0000FF", Style: 3},
Expand Down
Loading

0 comments on commit efcf599

Please sign in to comment.