2018-01-19 17:32:54 +08:00
|
|
|
package excelize
|
|
|
|
|
2018-12-27 18:51:44 +08:00
|
|
|
import (
|
2019-03-21 11:41:46 +08:00
|
|
|
"fmt"
|
2019-09-01 12:30:14 +08:00
|
|
|
"path/filepath"
|
2018-12-27 18:51:44 +08:00
|
|
|
"testing"
|
2019-10-26 20:55:24 +08:00
|
|
|
"time"
|
2018-12-27 18:51:44 +08:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
2018-01-19 17:32:54 +08:00
|
|
|
|
|
|
|
func TestCheckCellInArea(t *testing.T) {
|
|
|
|
expectedTrueCellInAreaList := [][2]string{
|
2018-01-31 11:12:43 +08:00
|
|
|
{"c2", "A1:AAZ32"},
|
|
|
|
{"B9", "A1:B9"},
|
|
|
|
{"C2", "C2:C2"},
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, expectedTrueCellInArea := range expectedTrueCellInAreaList {
|
|
|
|
cell := expectedTrueCellInArea[0]
|
|
|
|
area := expectedTrueCellInArea[1]
|
2019-03-23 20:08:06 +08:00
|
|
|
ok, err := checkCellInArea(cell, area)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Truef(t, ok,
|
2018-12-27 18:51:44 +08:00
|
|
|
"Expected cell %v to be in area %v, got false\n", cell, area)
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
expectedFalseCellInAreaList := [][2]string{
|
2018-01-31 11:12:43 +08:00
|
|
|
{"c2", "A4:AAZ32"},
|
|
|
|
{"C4", "D6:A1"}, // weird case, but you never know
|
|
|
|
{"AEF42", "BZ40:AEF41"},
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, expectedFalseCellInArea := range expectedFalseCellInAreaList {
|
|
|
|
cell := expectedFalseCellInArea[0]
|
|
|
|
area := expectedFalseCellInArea[1]
|
2019-03-23 20:08:06 +08:00
|
|
|
ok, err := checkCellInArea(cell, area)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Falsef(t, ok,
|
2018-12-27 18:51:44 +08:00
|
|
|
"Expected cell %v not to be inside of area %v, but got true\n", cell, area)
|
2018-01-19 17:32:54 +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
|
|
|
|
2019-03-23 20:08:06 +08:00
|
|
|
ok, err := checkCellInArea("AA0", "Z0:AB1")
|
|
|
|
assert.EqualError(t, err, `cannot convert cell "AA0" to coordinates: invalid cell name "AA0"`)
|
|
|
|
assert.False(t, ok)
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
2019-03-21 11:41:46 +08:00
|
|
|
|
|
|
|
func TestSetCellFloat(t *testing.T) {
|
|
|
|
sheet := "Sheet1"
|
|
|
|
t.Run("with no decimal", func(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
f.SetCellFloat(sheet, "A1", 123.0, -1, 64)
|
|
|
|
f.SetCellFloat(sheet, "A2", 123.0, 1, 64)
|
2019-03-23 20:08:06 +08:00
|
|
|
val, err := f.GetCellValue(sheet, "A1")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "123", val, "A1 should be 123")
|
|
|
|
val, err = f.GetCellValue(sheet, "A2")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "123.0", val, "A2 should be 123.0")
|
2019-03-21 11:41:46 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("with a decimal and precision limit", func(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
f.SetCellFloat(sheet, "A1", 123.42, 1, 64)
|
2019-03-23 20:08:06 +08:00
|
|
|
val, err := f.GetCellValue(sheet, "A1")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "123.4", val, "A1 should be 123.4")
|
2019-03-21 11:41:46 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("with a decimal and no limit", func(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
f.SetCellFloat(sheet, "A1", 123.42, -1, 64)
|
2019-03-23 20:08:06 +08:00
|
|
|
val, err := f.GetCellValue(sheet, "A1")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "123.42", val, "A1 should be 123.42")
|
2019-03-21 11:41:46 +08:00
|
|
|
})
|
2019-10-26 20:55:24 +08:00
|
|
|
f := NewFile()
|
|
|
|
assert.EqualError(t, f.SetCellFloat(sheet, "A", 123.42, -1, 64), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetCellValue(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
assert.EqualError(t, f.SetCellValue("Sheet1", "A", time.Now().UTC()), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
|
|
|
assert.EqualError(t, f.SetCellValue("Sheet1", "A", time.Duration(1e13)), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetCellBool(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
assert.EqualError(t, f.SetCellBool("Sheet1", "A", true), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetCellFormula(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
f.GetCellFormula("Sheet", "A1")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMergeCell(t *testing.T) {
|
|
|
|
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
|
|
|
if !assert.NoError(t, err) {
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
assert.EqualError(t, f.MergeCell("Sheet1", "A", "B"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
|
|
|
f.MergeCell("Sheet1", "D9", "D9")
|
|
|
|
f.MergeCell("Sheet1", "D9", "E9")
|
|
|
|
f.MergeCell("Sheet1", "H14", "G13")
|
|
|
|
f.MergeCell("Sheet1", "C9", "D8")
|
|
|
|
f.MergeCell("Sheet1", "F11", "G13")
|
|
|
|
f.MergeCell("Sheet1", "H7", "B15")
|
|
|
|
f.MergeCell("Sheet1", "D11", "F13")
|
|
|
|
f.MergeCell("Sheet1", "G10", "K12")
|
|
|
|
f.SetCellValue("Sheet1", "G11", "set value in merged cell")
|
|
|
|
f.SetCellInt("Sheet1", "H11", 100)
|
|
|
|
f.SetCellValue("Sheet1", "I11", float64(0.5))
|
|
|
|
f.SetCellHyperLink("Sheet1", "J11", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
|
|
|
|
f.SetCellFormula("Sheet1", "G12", "SUM(Sheet1!B19,Sheet1!C19)")
|
|
|
|
f.GetCellValue("Sheet1", "H11")
|
|
|
|
f.GetCellValue("Sheet2", "A6") // Merged cell ref is single coordinate.
|
|
|
|
f.GetCellFormula("Sheet1", "G12")
|
|
|
|
|
|
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestMergeCell.xlsx")))
|
2019-03-21 11:41:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func ExampleFile_SetCellFloat() {
|
|
|
|
f := NewFile()
|
2019-03-21 14:09:25 +08:00
|
|
|
var x = 3.14159265
|
2019-03-21 11:41:46 +08:00
|
|
|
f.SetCellFloat("Sheet1", "A1", x, 2, 64)
|
2019-03-23 20:08:06 +08:00
|
|
|
val, _ := f.GetCellValue("Sheet1", "A1")
|
|
|
|
fmt.Println(val)
|
2019-03-21 11:41:46 +08:00
|
|
|
// Output: 3.14
|
|
|
|
}
|
2019-04-16 14:50:16 +08:00
|
|
|
|
|
|
|
func BenchmarkSetCellValue(b *testing.B) {
|
|
|
|
values := []string{"First", "Second", "Third", "Fourth", "Fifth", "Sixth"}
|
|
|
|
cols := []string{"A", "B", "C", "D", "E", "F"}
|
|
|
|
f := NewFile()
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
for j := 0; j < len(values); j++ {
|
|
|
|
f.SetCellValue("Sheet1", fmt.Sprint(cols[j], i), values[j])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-01 12:30:14 +08:00
|
|
|
|
|
|
|
func TestOverflowNumericCell(t *testing.T) {
|
|
|
|
f, err := OpenFile(filepath.Join("test", "OverflowNumericCell.xlsx"))
|
|
|
|
if !assert.NoError(t, err) {
|
|
|
|
t.FailNow()
|
|
|
|
}
|
2019-09-02 21:52:55 +08:00
|
|
|
val, err := f.GetCellValue("Sheet1", "A1")
|
2019-09-01 12:30:14 +08:00
|
|
|
assert.NoError(t, err)
|
2019-09-02 21:52:55 +08:00
|
|
|
// GOARCH=amd64 - all ok; GOARCH=386 - actual: "-2147483648"
|
2019-09-01 12:30:14 +08:00
|
|
|
assert.Equal(t, "8595602512225", val, "A1 should be 8595602512225")
|
|
|
|
}
|