Browse Source

Added cell merging

Colin Fox 10 years ago
parent
commit
6a8352524a
4 changed files with 43 additions and 10 deletions
  1. 8 0
      cell.go
  2. 21 9
      sheet.go
  3. 1 1
      write.go
  4. 13 0
      xmlWorksheet.go

+ 8 - 0
cell.go

@@ -27,6 +27,8 @@ type Cell struct {
 	numFmt   string
 	date1904 bool
 	Hidden   bool
+	HMerge   int
+	VMerge   int
 	cellType CellType
 }
 
@@ -40,6 +42,12 @@ func NewCell(r *Row) *Cell {
 	return &Cell{style: NewStyle(), Row: r}
 }
 
+// Merge with other cells, horizontally and/or vertically.
+func (c *Cell) Merge(hcells, vcells int) {
+	c.HMerge = hcells
+	c.VMerge = vcells
+}
+
 func (c *Cell) Type() CellType {
 	return c.cellType
 }

+ 21 - 9
sheet.go

@@ -8,13 +8,13 @@ import (
 // Sheet is a high level structure intended to provide user access to
 // the contents of a particular sheet within an XLSX file.
 type Sheet struct {
-	Name   string
-	File   *File
-	Rows   []*Row
-	Cols   []*Col
-	MaxRow int
-	MaxCol int
-	Hidden bool
+	Name       string
+	File       *File
+	Rows       []*Row
+	Cols       []*Col
+	MaxRow     int
+	MaxCol     int
+	Hidden     bool
 	SheetViews []SheetView
 }
 
@@ -72,7 +72,7 @@ func (sh *Sheet) Cell(row, col int) *Cell {
 	return new(Cell)
 }
 
-//Set the width of a single column or multipel columns.
+//Set the width of a single column or multiple columns.
 func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
 	if startcol > endcol {
 		return fmt.Errorf("Could not set width for range %g-%g: startcol must be less than endcol.", startcol, endcol)
@@ -91,7 +91,7 @@ func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
 	return nil
 }
 
-// Dump sheet to it's XML representation, intended for internal use only
+// Dump sheet to its XML representation, intended for internal use only
 func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxWorksheet {
 	worksheet := newXlsxWorksheet()
 	xSheet := xlsxSheetData{}
@@ -150,9 +150,21 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 				xC.S = XfId
 			}
 			xRow.C = append(xRow.C, xC)
+
+			if cell.HMerge > 0 || cell.VMerge > 0 {
+				// r == rownum, c == colnum
+				mc := xlsxMergeCell{}
+				start := fmt.Sprintf("%s%d", numericToLetters(c), r+1)
+				endcol := c + cell.HMerge
+				endrow := r + cell.VMerge + 1
+				end := fmt.Sprintf("%s%d", numericToLetters(endcol), endrow)
+				mc.Ref = start + ":" + end
+				worksheet.MergeCells.Cells = append(worksheet.MergeCells.Cells, mc)
+			}
 		}
 		xSheet.Row = append(xSheet.Row, xRow)
 	}
+	worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
 
 	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
 	for _, col := range s.Cols {

+ 1 - 1
write.go

@@ -4,7 +4,7 @@ import "reflect"
 
 // Writes an array to row r. Accepts a pointer to array type 'e',
 // and writes the number of columns to write, 'cols'. If 'cols' is < 0,
-// the entire array will be written if possible. Retuens -1 if the 'e'
+// the entire array will be written if possible. Returns -1 if the 'e'
 // doesn't point to an array, otherwise the number of columns written.
 func (r *Row) WriteSlice(e interface{}, cols int) int {
 	if cols == 0 {

+ 13 - 0
xmlWorksheet.go

@@ -16,6 +16,7 @@ type xlsxWorksheet struct {
 	SheetFormatPr xlsxSheetFormatPr `xml:"sheetFormatPr"`
 	Cols          xlsxCols          `xml:"cols"`
 	SheetData     xlsxSheetData     `xml:"sheetData"`
+	MergeCells    xlsxMergeCells    `xml:"mergeCells"`
 	PrintOptions  xlsxPrintOptions  `xml:"printOptions"`
 	PageMargins   xlsxPageMargins   `xml:"pageMargins"`
 	PageSetUp     xlsxPageSetUp     `xml:"pageSetup"`
@@ -226,6 +227,16 @@ type xlsxRow struct {
 	C      []xlsxC `xml:"c"`
 }
 
+type xlsxMergeCell struct {
+	Ref string `xml:"ref,attr"` // ref: horiz "A1:C1", vert "B3:B6", both  "D3:G4"
+}
+
+type xlsxMergeCells struct {
+	XMLName xml.Name        `xml:"mergeCells"`
+	Count   int             `xml:"count,attr"`
+	Cells   []xlsxMergeCell `xml:"mergeCell"`
+}
+
 // xlsxC directly maps the c element in the namespace
 // http://schemas.openxmlformats.org/sprceadsheetml/2006/main -
 // currently I have not checked it for completeness - it does as much
@@ -300,5 +311,7 @@ func newXlsxWorksheet() (worksheet *xlsxWorksheet) {
 	worksheet.HeaderFooter.OddHeader[0] = xlsxOddHeader{Content: `&C&"Times New Roman,Regular"&12&A`}
 	worksheet.HeaderFooter.OddFooter = make([]xlsxOddFooter, 1)
 	worksheet.HeaderFooter.OddFooter[0] = xlsxOddFooter{Content: `&C&"Times New Roman,Regular"&12Page &P`}
+
+	worksheet.MergeCells.Count = 0
 	return
 }