forked from p30928647/excelize
Fix #533, add support overlapped mergecells
This commit is contained in:
commit
3763228ea7
|
@ -206,9 +206,6 @@ func (f *File) areaRefToCoordinates(ref string) ([]int, error) {
|
||||||
return coordinates, err
|
return coordinates, err
|
||||||
}
|
}
|
||||||
coordinates[2], coordinates[3], err = CellNameToCoordinates(lastCell)
|
coordinates[2], coordinates[3], err = CellNameToCoordinates(lastCell)
|
||||||
if err != nil {
|
|
||||||
return coordinates, err
|
|
||||||
}
|
|
||||||
return coordinates, err
|
return coordinates, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
86
cell.go
86
cell.go
|
@ -412,63 +412,6 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MergeCell provides a function to merge cells by given coordinate area and
|
|
||||||
// sheet name. For example create a merged cell of D3:E9 on Sheet1:
|
|
||||||
//
|
|
||||||
// err := f.MergeCell("Sheet1", "D3", "E9")
|
|
||||||
//
|
|
||||||
// If you create a merged cell that overlaps with another existing merged cell,
|
|
||||||
// those merged cells that already exist will be removed.
|
|
||||||
func (f *File) MergeCell(sheet, hcell, vcell string) error {
|
|
||||||
coordinates, err := f.areaRefToCoordinates(hcell + ":" + vcell)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
x1, y1, x2, y2 := coordinates[0], coordinates[1], coordinates[2], coordinates[3]
|
|
||||||
|
|
||||||
if x1 == x2 && y1 == y2 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Correct the coordinate area, such correct C1:B3 to B1:C3.
|
|
||||||
if x2 < x1 {
|
|
||||||
x1, x2 = x2, x1
|
|
||||||
}
|
|
||||||
|
|
||||||
if y2 < y1 {
|
|
||||||
y1, y2 = y2, y1
|
|
||||||
}
|
|
||||||
|
|
||||||
hcell, _ = CoordinatesToCellName(x1, y1)
|
|
||||||
vcell, _ = CoordinatesToCellName(x2, y2)
|
|
||||||
|
|
||||||
xlsx, err := f.workSheetReader(sheet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if xlsx.MergeCells != nil {
|
|
||||||
ref := hcell + ":" + vcell
|
|
||||||
// Delete the merged cells of the overlapping area.
|
|
||||||
for _, cellData := range xlsx.MergeCells.Cells {
|
|
||||||
cc := strings.Split(cellData.Ref, ":")
|
|
||||||
if len(cc) != 2 {
|
|
||||||
return fmt.Errorf("invalid area %q", cellData.Ref)
|
|
||||||
}
|
|
||||||
c1, _ := checkCellInArea(hcell, cellData.Ref)
|
|
||||||
c2, _ := checkCellInArea(vcell, cellData.Ref)
|
|
||||||
c3, _ := checkCellInArea(cc[0], ref)
|
|
||||||
c4, _ := checkCellInArea(cc[1], ref)
|
|
||||||
if !(!c1 && !c2 && !c3 && !c4) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xlsx.MergeCells.Cells = append(xlsx.MergeCells.Cells, &xlsxMergeCell{Ref: ref})
|
|
||||||
} else {
|
|
||||||
xlsx.MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: hcell + ":" + vcell}}}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSheetRow writes an array to row by given worksheet name, starting
|
// SetSheetRow writes an array to row by given worksheet name, starting
|
||||||
// coordinate and a pointer to array type 'slice'. For example, writes an
|
// coordinate and a pointer to array type 'slice'. For example, writes an
|
||||||
// array to row 6 start with the cell B6 on Sheet1:
|
// array to row 6 start with the cell B6 on Sheet1:
|
||||||
|
@ -601,7 +544,7 @@ func (f *File) mergeCellsParser(xlsx *xlsxWorksheet, axis string) (string, error
|
||||||
axis = strings.ToUpper(axis)
|
axis = strings.ToUpper(axis)
|
||||||
if xlsx.MergeCells != nil {
|
if xlsx.MergeCells != nil {
|
||||||
for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
|
for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
|
||||||
ok, err := checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref)
|
ok, err := f.checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return axis, err
|
return axis, err
|
||||||
}
|
}
|
||||||
|
@ -615,7 +558,7 @@ func (f *File) mergeCellsParser(xlsx *xlsxWorksheet, axis string) (string, error
|
||||||
|
|
||||||
// checkCellInArea provides a function to determine if a given coordinate is
|
// checkCellInArea provides a function to determine if a given coordinate is
|
||||||
// within an area.
|
// within an area.
|
||||||
func checkCellInArea(cell, area string) (bool, error) {
|
func (f *File) checkCellInArea(cell, area string) (bool, error) {
|
||||||
col, row, err := CellNameToCoordinates(cell)
|
col, row, err := CellNameToCoordinates(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -625,11 +568,30 @@ func checkCellInArea(cell, area string) (bool, error) {
|
||||||
if len(rng) != 2 {
|
if len(rng) != 2 {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
coordinates, err := f.areaRefToCoordinates(area)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
firstCol, firstRow, _ := CellNameToCoordinates(rng[0])
|
return cellInRef([]int{col, row}, coordinates), err
|
||||||
lastCol, lastRow, _ := CellNameToCoordinates(rng[1])
|
}
|
||||||
|
|
||||||
return col >= firstCol && col <= lastCol && row >= firstRow && row <= lastRow, err
|
// 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]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSharedForumula find a cell contains the same formula as another cell,
|
// getSharedForumula find a cell contains the same formula as another cell,
|
||||||
|
|
37
cell_test.go
37
cell_test.go
|
@ -10,6 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCheckCellInArea(t *testing.T) {
|
func TestCheckCellInArea(t *testing.T) {
|
||||||
|
f := NewFile()
|
||||||
expectedTrueCellInAreaList := [][2]string{
|
expectedTrueCellInAreaList := [][2]string{
|
||||||
{"c2", "A1:AAZ32"},
|
{"c2", "A1:AAZ32"},
|
||||||
{"B9", "A1:B9"},
|
{"B9", "A1:B9"},
|
||||||
|
@ -19,7 +20,7 @@ func TestCheckCellInArea(t *testing.T) {
|
||||||
for _, expectedTrueCellInArea := range expectedTrueCellInAreaList {
|
for _, expectedTrueCellInArea := range expectedTrueCellInAreaList {
|
||||||
cell := expectedTrueCellInArea[0]
|
cell := expectedTrueCellInArea[0]
|
||||||
area := expectedTrueCellInArea[1]
|
area := expectedTrueCellInArea[1]
|
||||||
ok, err := checkCellInArea(cell, area)
|
ok, err := f.checkCellInArea(cell, area)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Truef(t, ok,
|
assert.Truef(t, ok,
|
||||||
"Expected cell %v to be in area %v, got false\n", cell, area)
|
"Expected cell %v to be in area %v, got false\n", cell, area)
|
||||||
|
@ -34,13 +35,17 @@ func TestCheckCellInArea(t *testing.T) {
|
||||||
for _, expectedFalseCellInArea := range expectedFalseCellInAreaList {
|
for _, expectedFalseCellInArea := range expectedFalseCellInAreaList {
|
||||||
cell := expectedFalseCellInArea[0]
|
cell := expectedFalseCellInArea[0]
|
||||||
area := expectedFalseCellInArea[1]
|
area := expectedFalseCellInArea[1]
|
||||||
ok, err := checkCellInArea(cell, area)
|
ok, err := f.checkCellInArea(cell, area)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Falsef(t, ok,
|
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 area %v, but got true\n", cell, area)
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := checkCellInArea("AA0", "Z0:AB1")
|
ok, err := f.checkCellInArea("A1", "A:B")
|
||||||
|
assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
|
assert.False(t, ok)
|
||||||
|
|
||||||
|
ok, err = f.checkCellInArea("AA0", "Z0:AB1")
|
||||||
assert.EqualError(t, err, `cannot convert cell "AA0" to coordinates: invalid cell name "AA0"`)
|
assert.EqualError(t, err, `cannot convert cell "AA0" to coordinates: invalid cell name "AA0"`)
|
||||||
assert.False(t, ok)
|
assert.False(t, ok)
|
||||||
}
|
}
|
||||||
|
@ -94,32 +99,6 @@ func TestGetCellFormula(t *testing.T) {
|
||||||
f.GetCellFormula("Sheet", "A1")
|
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")))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleFile_SetCellFloat() {
|
func ExampleFile_SetCellFloat() {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
var x = 3.14159265
|
var x = 3.14159265
|
||||||
|
|
203
cellmerged.go
203
cellmerged.go
|
@ -9,7 +9,158 @@
|
||||||
|
|
||||||
package excelize
|
package excelize
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MergeCell provides a function to merge cells by given coordinate area and
|
||||||
|
// sheet name. For example create a merged cell of D3:E9 on Sheet1:
|
||||||
|
//
|
||||||
|
// err := f.MergeCell("Sheet1", "D3", "E9")
|
||||||
|
//
|
||||||
|
// If you create a merged cell that overlaps with another existing merged cell,
|
||||||
|
// those merged cells that already exist will be removed.
|
||||||
|
//
|
||||||
|
// B1(x1,y1) D1(x2,y1)
|
||||||
|
// +--------------------------------+
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// A4(x3,y3) | C4(x4,y3) |
|
||||||
|
// +-----------------------------+ |
|
||||||
|
// | | | |
|
||||||
|
// | | | |
|
||||||
|
// | |B5(x1,y2) | D5(x2,y2)|
|
||||||
|
// | +--------------------------------+
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// |A8(x3,y4) C8(x4,y4)|
|
||||||
|
// +-----------------------------+
|
||||||
|
//
|
||||||
|
func (f *File) MergeCell(sheet, hcell, vcell string) error {
|
||||||
|
rect1, err := f.areaRefToCoordinates(hcell + ":" + vcell)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Correct the coordinate area, such correct C1:B3 to B1:C3.
|
||||||
|
if rect1[2] < rect1[0] {
|
||||||
|
rect1[0], rect1[2] = rect1[2], rect1[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if rect1[3] < rect1[1] {
|
||||||
|
rect1[1], rect1[3] = rect1[3], rect1[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
hcell, _ = CoordinatesToCellName(rect1[0], rect1[1])
|
||||||
|
vcell, _ = CoordinatesToCellName(rect1[2], rect1[3])
|
||||||
|
|
||||||
|
xlsx, err := f.workSheetReader(sheet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ref := hcell + ":" + vcell
|
||||||
|
if xlsx.MergeCells != nil {
|
||||||
|
for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
|
||||||
|
cellData := xlsx.MergeCells.Cells[i]
|
||||||
|
if cellData == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cc := strings.Split(cellData.Ref, ":")
|
||||||
|
if len(cc) != 2 {
|
||||||
|
return fmt.Errorf("invalid area %q", cellData.Ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
rect2, err := f.areaRefToCoordinates(cellData.Ref)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the merged cells of the overlapping area.
|
||||||
|
if isOverlap(rect1, rect2) {
|
||||||
|
xlsx.MergeCells.Cells = append(xlsx.MergeCells.Cells[:i], xlsx.MergeCells.Cells[i+1:]...)
|
||||||
|
i--
|
||||||
|
|
||||||
|
if rect1[0] > rect2[0] {
|
||||||
|
rect1[0], rect2[0] = rect2[0], rect1[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if rect1[2] < rect2[2] {
|
||||||
|
rect1[2], rect2[2] = rect2[2], rect1[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
if rect1[1] > rect2[1] {
|
||||||
|
rect1[1], rect2[1] = rect2[1], rect1[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if rect1[3] < rect2[3] {
|
||||||
|
rect1[3], rect2[3] = rect2[3], rect1[3]
|
||||||
|
}
|
||||||
|
hcell, _ = CoordinatesToCellName(rect1[0], rect1[1])
|
||||||
|
vcell, _ = CoordinatesToCellName(rect1[2], rect1[3])
|
||||||
|
ref = hcell + ":" + vcell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xlsx.MergeCells.Cells = append(xlsx.MergeCells.Cells, &xlsxMergeCell{Ref: ref})
|
||||||
|
} else {
|
||||||
|
xlsx.MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: ref}}}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmergeCell provides a function to unmerge a given coordinate area.
|
||||||
|
// For example unmerge area D3:E9 on Sheet1:
|
||||||
|
//
|
||||||
|
// err := f.UnmergeCell("Sheet1", "D3", "E9")
|
||||||
|
//
|
||||||
|
// Attention: overlapped areas will also be unmerged.
|
||||||
|
func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
|
||||||
|
xlsx, err := f.workSheetReader(sheet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rect1, err := f.areaRefToCoordinates(hcell + ":" + vcell)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if rect1[2] < rect1[0] {
|
||||||
|
rect1[0], rect1[2] = rect1[2], rect1[0]
|
||||||
|
}
|
||||||
|
if rect1[3] < rect1[1] {
|
||||||
|
rect1[1], rect1[3] = rect1[3], rect1[1]
|
||||||
|
}
|
||||||
|
hcell, _ = CoordinatesToCellName(rect1[0], rect1[1])
|
||||||
|
vcell, _ = CoordinatesToCellName(rect1[2], rect1[3])
|
||||||
|
|
||||||
|
// return nil since no MergeCells in the sheet
|
||||||
|
if xlsx.MergeCells == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for _, cellData := range xlsx.MergeCells.Cells {
|
||||||
|
if cellData == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cc := strings.Split(cellData.Ref, ":")
|
||||||
|
if len(cc) != 2 {
|
||||||
|
return fmt.Errorf("invalid area %q", cellData.Ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
rect2, err := f.areaRefToCoordinates(cellData.Ref)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if isOverlap(rect1, rect2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
xlsx.MergeCells.Cells[i] = cellData
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
xlsx.MergeCells.Cells = xlsx.MergeCells.Cells[:i]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetMergeCells provides a function to get all merged cells from a worksheet
|
// GetMergeCells provides a function to get all merged cells from a worksheet
|
||||||
// currently.
|
// currently.
|
||||||
|
@ -33,56 +184,6 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
|
||||||
return mergeCells, err
|
return mergeCells, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmergeCell provides a function to unmerge a given coordinate area.
|
|
||||||
// For example unmerge area D3:E9 on Sheet1:
|
|
||||||
//
|
|
||||||
// err := f.UnmergeCell("Sheet1", "D3", "E9")
|
|
||||||
//
|
|
||||||
// Attention: overlapped areas will also be unmerged.
|
|
||||||
func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
|
|
||||||
xlsx, err := f.workSheetReader(sheet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
coordinates, err := f.areaRefToCoordinates(hcell + ":" + vcell)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
x1, y1, x2, y2 := coordinates[0], coordinates[1], coordinates[2], coordinates[3]
|
|
||||||
|
|
||||||
if x2 < x1 {
|
|
||||||
x1, x2 = x2, x1
|
|
||||||
}
|
|
||||||
if y2 < y1 {
|
|
||||||
y1, y2 = y2, y1
|
|
||||||
}
|
|
||||||
hcell, _ = CoordinatesToCellName(x1, y1)
|
|
||||||
vcell, _ = CoordinatesToCellName(x2, y2)
|
|
||||||
|
|
||||||
// return nil since no MergeCells in the sheet
|
|
||||||
if xlsx.MergeCells == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ref := hcell + ":" + vcell
|
|
||||||
i := 0
|
|
||||||
for _, cellData := range xlsx.MergeCells.Cells {
|
|
||||||
cc := strings.Split(cellData.Ref, ":")
|
|
||||||
c1, _ := checkCellInArea(hcell, cellData.Ref)
|
|
||||||
c2, _ := checkCellInArea(vcell, cellData.Ref)
|
|
||||||
c3, _ := checkCellInArea(cc[0], ref)
|
|
||||||
c4, _ := checkCellInArea(cc[1], ref)
|
|
||||||
// skip the overlapped mergecell
|
|
||||||
if c1 || c2 || c3 || c4 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
xlsx.MergeCells.Cells[i] = cellData
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
xlsx.MergeCells.Cells = xlsx.MergeCells.Cells[:i]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeCell define a merged cell data.
|
// MergeCell define a merged cell data.
|
||||||
// It consists of the following structure.
|
// It consists of the following structure.
|
||||||
// example: []string{"D4:E10", "cell value"}
|
// example: []string{"D4:E10", "cell value"}
|
||||||
|
|
|
@ -7,6 +7,74 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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"`)
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "D9", "D9"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "D9", "E9"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "H14", "G13"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "C9", "D8"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "F11", "G13"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "H7", "B15"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "D11", "F13"))
|
||||||
|
assert.NoError(t, 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")
|
||||||
|
|
||||||
|
f.NewSheet("Sheet3")
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "D11", "F13"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "G10", "K12"))
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "B1", "D5")) // B1:D5
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "E1", "F5")) // E1:F5
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "H2", "I5"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "I4", "J6")) // H2:J6
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "M2", "N5"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "L4", "M6")) // L2:N6
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "P4", "Q7"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "O2", "P5")) // O2:Q7
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "A9", "B12"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "B7", "C9")) // A7:C12
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "E9", "F10"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "D8", "G12"))
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "I8", "I12"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "I10", "K10"))
|
||||||
|
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "M8", "Q13"))
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet3", "N10", "O11"))
|
||||||
|
|
||||||
|
// Test get merged cells on not exists worksheet.
|
||||||
|
assert.EqualError(t, f.MergeCell("SheetN", "N10", "O11"), "sheet SheetN is not exist")
|
||||||
|
|
||||||
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestMergeCell.xlsx")))
|
||||||
|
|
||||||
|
f = NewFile()
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "A2", "B3"))
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{nil, nil}}
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "A2", "B3"))
|
||||||
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A1"}}}
|
||||||
|
assert.EqualError(t, f.MergeCell("Sheet1", "A2", "B3"), `invalid area "A1"`)
|
||||||
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
|
||||||
|
assert.EqualError(t, f.MergeCell("Sheet1", "A2", "B3"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetMergeCells(t *testing.T) {
|
func TestGetMergeCells(t *testing.T) {
|
||||||
wants := []struct {
|
wants := []struct {
|
||||||
value string
|
value string
|
||||||
|
@ -68,23 +136,28 @@ func TestUnmergeCell(t *testing.T) {
|
||||||
assert.EqualError(t, f.UnmergeCell("Sheet1", "A", "A"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
assert.EqualError(t, f.UnmergeCell("Sheet1", "A", "A"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
|
|
||||||
// unmerge the mergecell that contains A1
|
// unmerge the mergecell that contains A1
|
||||||
err = f.UnmergeCell(sheet1, "A1", "A1")
|
assert.NoError(t, f.UnmergeCell(sheet1, "A1", "A1"))
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
if len(xlsx.MergeCells.Cells) != mergeCellNum-1 {
|
if len(xlsx.MergeCells.Cells) != mergeCellNum-1 {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmerge area A7:D3(A3:D7)
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestUnmergeCell.xlsx")))
|
||||||
// this will unmerge all since this area overlaps with all others
|
|
||||||
err = f.UnmergeCell(sheet1, "D7", "A3")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
if len(xlsx.MergeCells.Cells) != 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
f = NewFile()
|
||||||
|
assert.NoError(t, f.MergeCell("Sheet1", "A2", "B3"))
|
||||||
// Test unmerged area on not exists worksheet.
|
// Test unmerged area on not exists worksheet.
|
||||||
err = f.UnmergeCell("SheetN", "A1", "A1")
|
assert.EqualError(t, f.UnmergeCell("SheetN", "A1", "A1"), "sheet SheetN is not exist")
|
||||||
assert.EqualError(t, err, "sheet SheetN is not exist")
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = nil
|
||||||
|
assert.NoError(t, f.UnmergeCell("Sheet1", "H7", "B15"))
|
||||||
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{nil, nil}}
|
||||||
|
assert.NoError(t, f.UnmergeCell("Sheet1", "H15", "B7"))
|
||||||
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A1"}}}
|
||||||
|
assert.EqualError(t, f.UnmergeCell("Sheet1", "A2", "B3"), `invalid area "A1"`)
|
||||||
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
|
||||||
|
assert.EqualError(t, f.UnmergeCell("Sheet1", "A2", "B3"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,6 +290,12 @@ func TestSetCellHyperLink(t *testing.T) {
|
||||||
assert.NoError(t, file.SetCellHyperLink("Sheet1", cell, "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
|
assert.NoError(t, file.SetCellHyperLink("Sheet1", cell, "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
|
||||||
}
|
}
|
||||||
assert.EqualError(t, file.SetCellHyperLink("Sheet1", "A65531", "https://github.com/360EntSecGroup-Skylar/excelize", "External"), "over maximum limit hyperlinks in a worksheet")
|
assert.EqualError(t, file.SetCellHyperLink("Sheet1", "A65531", "https://github.com/360EntSecGroup-Skylar/excelize", "External"), "over maximum limit hyperlinks in a worksheet")
|
||||||
|
|
||||||
|
f = NewFile()
|
||||||
|
f.workSheetReader("Sheet1")
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
|
||||||
|
err = f.SetCellHyperLink("Sheet1", "A1", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
|
||||||
|
assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetCellHyperLink(t *testing.T) {
|
func TestGetCellHyperLink(t *testing.T) {
|
||||||
|
@ -310,6 +316,23 @@ func TestGetCellHyperLink(t *testing.T) {
|
||||||
link, target, err = f.GetCellHyperLink("Sheet3", "H3")
|
link, target, err = f.GetCellHyperLink("Sheet3", "H3")
|
||||||
assert.EqualError(t, err, "sheet Sheet3 is not exist")
|
assert.EqualError(t, err, "sheet Sheet3 is not exist")
|
||||||
t.Log(link, target)
|
t.Log(link, target)
|
||||||
|
|
||||||
|
f = NewFile()
|
||||||
|
f.workSheetReader("Sheet1")
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].Hyperlinks = &xlsxHyperlinks{
|
||||||
|
Hyperlink: []xlsxHyperlink{{Ref: "A1"}},
|
||||||
|
}
|
||||||
|
link, target, err = f.GetCellHyperLink("Sheet1", "A1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, link, true)
|
||||||
|
assert.Equal(t, target, "")
|
||||||
|
|
||||||
|
f.Sheet["xl/worksheets/sheet1.xml"].MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
|
||||||
|
link, target, err = f.GetCellHyperLink("Sheet1", "A1")
|
||||||
|
assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
|
assert.Equal(t, link, false)
|
||||||
|
assert.Equal(t, target, "")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetCellFormula(t *testing.T) {
|
func TestSetCellFormula(t *testing.T) {
|
||||||
|
|
|
@ -109,7 +109,7 @@ type xlsxPageSetUp struct {
|
||||||
FirstPageNumber int `xml:"firstPageNumber,attr,omitempty"`
|
FirstPageNumber int `xml:"firstPageNumber,attr,omitempty"`
|
||||||
FitToHeight int `xml:"fitToHeight,attr,omitempty"`
|
FitToHeight int `xml:"fitToHeight,attr,omitempty"`
|
||||||
FitToWidth int `xml:"fitToWidth,attr,omitempty"`
|
FitToWidth int `xml:"fitToWidth,attr,omitempty"`
|
||||||
HorizontalDPI float32 `xml:"horizontalDpi,attr,omitempty"`
|
HorizontalDPI int `xml:"horizontalDpi,attr,omitempty"`
|
||||||
RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
|
RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
|
||||||
Orientation string `xml:"orientation,attr,omitempty"`
|
Orientation string `xml:"orientation,attr,omitempty"`
|
||||||
PageOrder string `xml:"pageOrder,attr,omitempty"`
|
PageOrder string `xml:"pageOrder,attr,omitempty"`
|
||||||
|
@ -119,7 +119,7 @@ type xlsxPageSetUp struct {
|
||||||
Scale int `xml:"scale,attr,omitempty"`
|
Scale int `xml:"scale,attr,omitempty"`
|
||||||
UseFirstPageNumber bool `xml:"useFirstPageNumber,attr,omitempty"`
|
UseFirstPageNumber bool `xml:"useFirstPageNumber,attr,omitempty"`
|
||||||
UsePrinterDefaults bool `xml:"usePrinterDefaults,attr,omitempty"`
|
UsePrinterDefaults bool `xml:"usePrinterDefaults,attr,omitempty"`
|
||||||
VerticalDPI float32 `xml:"verticalDpi,attr,omitempty"`
|
VerticalDPI int `xml:"verticalDpi,attr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// xlsxPrintOptions directly maps the printOptions element in the namespace
|
// xlsxPrintOptions directly maps the printOptions element in the namespace
|
||||||
|
|
Loading…
Reference in New Issue