From 4c433c57e65734094f959d25b50f138a6ca88020 Mon Sep 17 00:00:00 2001 From: Xudong Zhang Date: Fri, 13 Dec 2019 21:43:59 +0800 Subject: [PATCH] Resolve #527, unmerge an area (#528) --- cellmerged.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++ cellmerged_test.go | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/cellmerged.go b/cellmerged.go index c1df9b3db9..4a5d11f4d2 100644 --- a/cellmerged.go +++ b/cellmerged.go @@ -33,6 +33,56 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) { 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. // It consists of the following structure. // example: []string{"D4:E10", "cell value"} diff --git a/cellmerged_test.go b/cellmerged_test.go index d53acc2eb3..0c5ac76e44 100644 --- a/cellmerged_test.go +++ b/cellmerged_test.go @@ -52,3 +52,39 @@ func TestGetMergeCells(t *testing.T) { _, err = f.GetMergeCells("SheetN") assert.EqualError(t, err, "sheet SheetN is not exist") } + +func TestUnmergeCell(t *testing.T) { + f, err := OpenFile(filepath.Join("test", "MergeCell.xlsx")) + if !assert.NoError(t, err) { + t.FailNow() + } + sheet1 := f.GetSheetName(1) + + xlsx, err := f.workSheetReader(sheet1) + assert.NoError(t, err) + + mergeCellNum := len(xlsx.MergeCells.Cells) + + assert.EqualError(t, f.UnmergeCell("Sheet1", "A", "A"), `cannot convert cell "A" to coordinates: invalid cell name "A"`) + + // unmerge the mergecell that contains A1 + err = f.UnmergeCell(sheet1, "A1", "A1") + assert.NoError(t, err) + + if len(xlsx.MergeCells.Cells) != mergeCellNum-1 { + t.FailNow() + } + + // unmerge area A7:D3(A3:D7) + // 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() + } + + // Test unmerged area on not exists worksheet. + err = f.UnmergeCell("SheetN", "A1", "A1") + assert.EqualError(t, err, "sheet SheetN is not exist") +}