summaryrefslogtreecommitdiff
path: root/cellmerged.go
diff options
context:
space:
mode:
Diffstat (limited to 'cellmerged.go')
-rw-r--r--cellmerged.go153
1 files changed, 152 insertions, 1 deletions
diff --git a/cellmerged.go b/cellmerged.go
index c1df9b3..968a28a 100644
--- a/cellmerged.go
+++ b/cellmerged.go
@@ -9,7 +9,158 @@
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
// currently.