Browse Source

Merge pull request #110 from greenenergy/master

Thanks, @greenenergy.
Shawn Milochik 10 years ago
parent
commit
761bdfa2de
6 changed files with 49 additions and 5 deletions
  1. 8 0
      cell.go
  2. 1 1
      file_test.go
  3. 26 2
      sheet.go
  4. 1 1
      sheet_test.go
  5. 1 1
      write.go
  6. 12 0
      xmlWorksheet.go

+ 8 - 0
cell.go

@@ -29,6 +29,8 @@ type Cell struct {
 	numFmt   string
 	numFmt   string
 	date1904 bool
 	date1904 bool
 	Hidden   bool
 	Hidden   bool
+	HMerge   int
+	VMerge   int
 	cellType CellType
 	cellType CellType
 }
 }
 
 
@@ -43,6 +45,12 @@ func NewCell(r *Row) *Cell {
 	return &Cell{style: NewStyle(), Row: r}
 	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
+}
+
 // Type returns the CellType of a cell. See CellType constants for more details.
 // Type returns the CellType of a cell. See CellType constants for more details.
 func (c *Cell) Type() CellType {
 func (c *Cell) Type() CellType {
 	return c.cellType
 	return c.cellType

+ 1 - 1
file_test.go

@@ -653,7 +653,7 @@ func (l *FileSuite) TestMarshalFile(c *C) {
 	// For now we only allow simple string data in the
 	// For now we only allow simple string data in the
 	// spreadsheet.  Style support will follow.
 	// spreadsheet.  Style support will follow.
 	expectedStyles := `<?xml version="1.0" encoding="UTF-8"?>
 	expectedStyles := `<?xml version="1.0" encoding="UTF-8"?>
-<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="1"><font><sz val="12"/><name val="Verdana"/><family val="0"/><charset val="0"/></font></fonts><fills count="1"><fill><patternFill patternType="none"><fgColor rgb="FFFFFFFF"/><bgColor rgb="00000000"/></patternFill></fill></fills><borders count="1"><border><left style="none"/><right style="none"/><top style="none"/><bottom style="none"/></border></borders><cellStyleXfs count="1"><xf applyAlignment="0" applyBorder="0" applyFont="0" applyFill="0" applyProtection="0" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="0" textRotation="0" vertical="" wrapText="0"/></xf></cellStyleXfs><cellXfs count="1"><xf applyAlignment="0" applyBorder="0" applyFont="0" applyFill="0" applyProtection="0" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="0" textRotation="0" vertical="" wrapText="0"/></xf></cellXfs></styleSheet>`
+<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="1"><font><sz val="12"/><name val="Verdana"/><family val="0"/><charset val="0"/></font></fonts><fills count="2"><fill><patternFill patternType="none"><fgColor rgb="FFFFFFFF"/><bgColor rgb="00000000"/></patternFill></fill><fill><patternFill patternType="lightGrey"/></fill></fills><borders count="1"><border><left style="none"/><right style="none"/><top style="none"/><bottom style="none"/></border></borders><cellStyleXfs count="1"><xf applyAlignment="0" applyBorder="0" applyFont="0" applyFill="0" applyProtection="0" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="0" textRotation="0" vertical="" wrapText="0"/></xf></cellStyleXfs><cellXfs count="1"><xf applyAlignment="0" applyBorder="0" applyFont="0" applyFill="0" applyProtection="0" borderId="0" fillId="0" fontId="0" numFmtId="0"><alignment horizontal="" indent="0" shrinkToFit="0" textRotation="0" vertical="" wrapText="0"/></xf></cellXfs></styleSheet>`
 	c.Assert(parts["xl/styles.xml"], Equals, expectedStyles)
 	c.Assert(parts["xl/styles.xml"], Equals, expectedStyles)
 }
 }
 
 

+ 26 - 2
sheet.go

@@ -72,7 +72,7 @@ func (sh *Sheet) Cell(row, col int) *Cell {
 	return new(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 {
 func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
 	if startcol > endcol {
 	if startcol > endcol {
 		return fmt.Errorf("Could not set width for range %d-%d: startcol must be less than endcol.", startcol, endcol)
 		return fmt.Errorf("Could not set width for range %d-%d: startcol must be less than endcol.", startcol, endcol)
@@ -91,7 +91,7 @@ func (s *Sheet) SetColWidth(startcol, endcol int, width float64) error {
 	return nil
 	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 {
 func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxWorksheet {
 	worksheet := newXlsxWorksheet()
 	worksheet := newXlsxWorksheet()
 	xSheet := xlsxSheetData{}
 	xSheet := xlsxSheetData{}
@@ -110,6 +110,12 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 				xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
 				xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
 				fontId := styles.addFont(xFont)
 				fontId := styles.addFont(xFont)
 				fillId := styles.addFill(xFill)
 				fillId := styles.addFill(xFill)
+
+				// HACK - adding light grey fill, as in OO and Google
+				greyfill := xlsxFill{}
+				greyfill.PatternFill.PatternType = "lightGrey"
+				styles.addFill(greyfill)
+
 				borderId := styles.addBorder(xBorder)
 				borderId := styles.addBorder(xBorder)
 				xCellStyleXf.FontId = fontId
 				xCellStyleXf.FontId = fontId
 				xCellStyleXf.FillId = fillId
 				xCellStyleXf.FillId = fillId
@@ -150,10 +156,28 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 				xC.S = XfId
 				xC.S = XfId
 			}
 			}
 			xRow.C = append(xRow.C, xC)
 			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
+				if worksheet.MergeCells == nil {
+					worksheet.MergeCells = &xlsxMergeCells{}
+				}
+				worksheet.MergeCells.Cells = append(worksheet.MergeCells.Cells, mc)
+			}
 		}
 		}
 		xSheet.Row = append(xSheet.Row, xRow)
 		xSheet.Row = append(xSheet.Row, xRow)
 	}
 	}
 
 
+	if worksheet.MergeCells != nil {
+		worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
+	}
+
 	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
 	worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
 	for _, col := range s.Cols {
 	for _, col := range s.Cols {
 		if col.Width == 0 {
 		if col.Width == 0 {

+ 1 - 1
sheet_test.go

@@ -81,7 +81,7 @@ func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
 	c.Assert(styles.Fonts.Font[0].Sz.Val, Equals, "10")
 	c.Assert(styles.Fonts.Font[0].Sz.Val, Equals, "10")
 	c.Assert(styles.Fonts.Font[0].Name.Val, Equals, "Verdana")
 	c.Assert(styles.Fonts.Font[0].Name.Val, Equals, "Verdana")
 
 
-	c.Assert(styles.Fills.Count, Equals, 1)
+	c.Assert(styles.Fills.Count, Equals, 2)
 	c.Assert(styles.Fills.Fill[0].PatternFill.PatternType, Equals, "solid")
 	c.Assert(styles.Fills.Fill[0].PatternFill.PatternType, Equals, "solid")
 	c.Assert(styles.Fills.Fill[0].PatternFill.FgColor.RGB, Equals, "FFFFFFFF")
 	c.Assert(styles.Fills.Fill[0].PatternFill.FgColor.RGB, Equals, "FFFFFFFF")
 	c.Assert(styles.Fills.Fill[0].PatternFill.BgColor.RGB, Equals, "00000000")
 	c.Assert(styles.Fills.Fill[0].PatternFill.BgColor.RGB, Equals, "00000000")

+ 1 - 1
write.go

@@ -4,7 +4,7 @@ import "reflect"
 
 
 // Writes an array to row r. Accepts a pointer to array type 'e',
 // 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,
 // 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.
 // doesn't point to an array, otherwise the number of columns written.
 func (r *Row) WriteSlice(e interface{}, cols int) int {
 func (r *Row) WriteSlice(e interface{}, cols int) int {
 	if cols == 0 {
 	if cols == 0 {

+ 12 - 0
xmlWorksheet.go

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