summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cell.go25
-rw-r--r--cell_test.go40
-rw-r--r--lib.go41
-rw-r--r--lib_test.go59
-rw-r--r--styles.go12
5 files changed, 159 insertions, 18 deletions
diff --git a/cell.go b/cell.go
index 5d26338..bb363aa 100644
--- a/cell.go
+++ b/cell.go
@@ -455,27 +455,16 @@ func (f *File) SetCellDefault(sheet, axis, value string) {
// checkCellInArea provides function to determine if a given coordinate is
// within an area.
func checkCellInArea(cell, area string) bool {
- result := false
cell = strings.ToUpper(cell)
- col := string(strings.Map(letterOnlyMapF, cell))
- row, _ := strconv.Atoi(strings.Map(intOnlyMapF, cell))
- xAxis := row - 1
- yAxis := TitleToNumber(col)
+ area = strings.ToUpper(area)
ref := strings.Split(area, ":")
- hCol := string(strings.Map(letterOnlyMapF, ref[0]))
- hRow, _ := strconv.Atoi(strings.Map(intOnlyMapF, ref[0]))
- hyAxis := hRow - 1
- hxAxis := TitleToNumber(hCol)
+ from := ref[0]
+ to := ref[1]
- vCol := string(strings.Map(letterOnlyMapF, ref[1]))
- vRow, _ := strconv.Atoi(strings.Map(intOnlyMapF, ref[1]))
- vyAxis := vRow - 1
- vxAxis := TitleToNumber(vCol)
-
- if hxAxis <= yAxis && yAxis <= vxAxis && hyAxis <= xAxis && xAxis <= vyAxis {
- result = true
- }
+ col, row := getCellColRow(cell)
+ fromCol, fromRow := getCellColRow(from)
+ toCol, toRow := getCellColRow(to)
- return result
+ return axisLowerOrEqualThan(fromCol, col) && axisLowerOrEqualThan(col, toCol) && axisLowerOrEqualThan(fromRow, row) && axisLowerOrEqualThan(row, toRow)
}
diff --git a/cell_test.go b/cell_test.go
new file mode 100644
index 0000000..2ab5413
--- /dev/null
+++ b/cell_test.go
@@ -0,0 +1,40 @@
+package excelize
+
+import "testing"
+
+func TestCheckCellInArea(t *testing.T) {
+ expectedTrueCellInAreaList := [][2]string{
+ [2]string{"c2", "A1:AAZ32"},
+ [2]string{"AA0", "Z0:AB1"},
+ [2]string{"B9", "A1:B9"},
+ [2]string{"C2", "C2:C2"},
+ }
+
+ for _, expectedTrueCellInArea := range expectedTrueCellInAreaList {
+ cell := expectedTrueCellInArea[0]
+ area := expectedTrueCellInArea[1]
+
+ cellInArea := checkCellInArea(cell, area)
+
+ if !cellInArea {
+ t.Fatalf("Expected cell %v to be in area %v, got false\n", cell, area)
+ }
+ }
+
+ expectedFalseCellInAreaList := [][2]string{
+ [2]string{"c2", "A4:AAZ32"},
+ [2]string{"C4", "D6:A1"}, // weird case, but you never know
+ [2]string{"AEF42", "BZ40:AEF41"},
+ }
+
+ for _, expectedFalseCellInArea := range expectedFalseCellInAreaList {
+ cell := expectedFalseCellInArea[0]
+ area := expectedFalseCellInArea[1]
+
+ cellInArea := checkCellInArea(cell, area)
+
+ if cellInArea {
+ t.Fatalf("Expected cell %v not to be inside of area %v, but got true\n", cell, area)
+ }
+ }
+}
diff --git a/lib.go b/lib.go
index 2f3df35..c0426d6 100644
--- a/lib.go
+++ b/lib.go
@@ -7,6 +7,7 @@ import (
"io"
"log"
"math"
+ "unicode"
)
// ReadZipReader can be used to read an XLSX in memory without touching the
@@ -132,3 +133,43 @@ func defaultTrue(b *bool) bool {
}
return *b
}
+
+// axisLowerOrEqualThan returns true if axis1 <= axis2
+// axis1/axis2 can be either a column or a row axis, e.g. "A", "AAE", "42", "1", etc.
+//
+// For instance, the following comparisons are all true:
+//
+// "A" <= "B"
+// "A" <= "AA"
+// "B" <= "AA"
+// "BC" <= "ABCD" (in a XLSX sheet, the BC col comes before the ABCD col)
+// "1" <= "2"
+// "2" <= "11" (in a XLSX sheet, the row 2 comes before the row 11)
+// and so on
+func axisLowerOrEqualThan(axis1, axis2 string) bool {
+ if len(axis1) < len(axis2) {
+ return true
+ } else if len(axis1) > len(axis2) {
+ return false
+ } else {
+ return axis1 <= axis2
+ }
+}
+
+// getCellColRow returns the two parts of a cell identifier (its col and row) as strings
+//
+// For instance:
+//
+// "C220" => "C", "220"
+// "aaef42" => "aaef", "42"
+// "" => "", ""
+func getCellColRow(cell string) (col, row string) {
+ for index, rune := range cell {
+ if unicode.IsDigit(rune) {
+ return cell[:index], cell[index:]
+ }
+
+ }
+
+ return cell, ""
+}
diff --git a/lib_test.go b/lib_test.go
new file mode 100644
index 0000000..3a4dc2c
--- /dev/null
+++ b/lib_test.go
@@ -0,0 +1,59 @@
+package excelize
+
+import "testing"
+
+func TestAxisLowerOrEqualThan(t *testing.T) {
+ trueExpectedInputList := [][2]string{
+ [2]string{"A", "B"},
+ [2]string{"A", "AA"},
+ [2]string{"B", "AA"},
+ [2]string{"BC", "ABCD"},
+ [2]string{"1", "2"},
+ [2]string{"2", "11"},
+ }
+
+ for _, trueExpectedInput := range trueExpectedInputList {
+ isLowerOrEqual := axisLowerOrEqualThan(trueExpectedInput[0], trueExpectedInput[1])
+ if !isLowerOrEqual {
+ t.Fatalf("Expected %v <= %v = true, got false\n", trueExpectedInput[0], trueExpectedInput[1])
+ }
+ }
+
+ falseExpectedInputList := [][2]string{
+ [2]string{"B", "A"},
+ [2]string{"AA", "A"},
+ [2]string{"AA", "B"},
+ [2]string{"ABCD", "AB"},
+ [2]string{"2", "1"},
+ [2]string{"11", "2"},
+ }
+
+ for _, falseExpectedInput := range falseExpectedInputList {
+ isLowerOrEqual := axisLowerOrEqualThan(falseExpectedInput[0], falseExpectedInput[1])
+ if isLowerOrEqual {
+ t.Fatalf("Expected %v <= %v = false, got true\n", falseExpectedInput[0], falseExpectedInput[1])
+ }
+ }
+}
+
+func TestGetCellColRow(t *testing.T) {
+ cellExpectedColRowList := map[string][2]string{
+ "C220": [2]string{"C", "220"},
+ "aaef42": [2]string{"aaef", "42"},
+ "bonjour": [2]string{"bonjour", ""},
+ "59": [2]string{"", "59"},
+ "": [2]string{"", ""},
+ }
+
+ for cell, expectedColRow := range cellExpectedColRowList {
+ col, row := getCellColRow(cell)
+
+ if col != expectedColRow[0] {
+ t.Fatalf("Expected cell %v to return col %v, got col %v\n", cell, expectedColRow[0], col)
+ }
+
+ if row != expectedColRow[1] {
+ t.Fatalf("Expected cell %v to return row %v, got row %v\n", cell, expectedColRow[1], row)
+ }
+ }
+}
diff --git a/styles.go b/styles.go
index 87bca13..8cee5ff 100644
--- a/styles.go
+++ b/styles.go
@@ -2327,7 +2327,19 @@ func (f *File) SetCellStyle(sheet, hcell, vcell string, styleID int) {
completeCol(xlsx, vyAxis+1, vxAxis+1)
for r, row := range xlsx.SheetData.Row {
+ if r < hyAxis {
+ continue
+ } else if r > vyAxis {
+ break
+ }
+
for k, c := range row.C {
+ if k < hxAxis {
+ continue
+ } else if k > vxAxis {
+ break
+ }
+
if checkCellInArea(c.R, hcell+":"+vcell) {
xlsx.SheetData.Row[r].C[k].S = styleID
}