Browse Source

Merge pull request #218 from xStrom/groups

Add basic grouping support
Geoffrey J. Teale 9 years ago
parent
commit
46e6e472d6
6 changed files with 101 additions and 29 deletions
  1. 8 7
      col.go
  2. 10 4
      lib.go
  3. 6 5
      row.go
  4. 25 6
      sheet.go
  5. 41 0
      sheet_test.go
  6. 11 7
      xmlWorksheet.go

+ 8 - 7
col.go

@@ -4,13 +4,14 @@ package xlsx
 const ColWidth = 9.5
 
 type Col struct {
-	Min       int
-	Max       int
-	Hidden    bool
-	Width     float64
-	Collapsed bool
-	numFmt    string
-	style     *Style
+	Min          int
+	Max          int
+	Hidden       bool
+	Width        float64
+	Collapsed    bool
+	OutlineLevel uint8
+	numFmt       string
+	style        *Style
 }
 
 func (c *Col) SetType(cellType CellType) {

+ 10 - 4
lib.go

@@ -298,6 +298,8 @@ func makeRowFromRaw(rawrow xlsxRow, sheet *Sheet) *Row {
 	}
 	upper++
 
+	row.OutlineLevel = rawrow.OutlineLevel
+
 	row.Cells = make([]*Cell, upper)
 	for i := 0; i < upper; i++ {
 		cell = new(Cell)
@@ -521,10 +523,11 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File, sheet *Sheet) ([]*R
 			// columns.
 			for i := rawcol.Min; i <= rawcol.Max && i <= colCount; i++ {
 				col := &Col{
-					Min:    rawcol.Min,
-					Max:    rawcol.Max,
-					Hidden: rawcol.Hidden,
-					Width:  rawcol.Width}
+					Min:          rawcol.Min,
+					Max:          rawcol.Max,
+					Hidden:       rawcol.Hidden,
+					Width:        rawcol.Width,
+					OutlineLevel: rawcol.OutlineLevel}
 				cols[i-1] = col
 				if file.styles != nil {
 					col.style = file.styles.getStyle(rawcol.Style)
@@ -559,6 +562,7 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File, sheet *Sheet) ([]*R
 		}
 
 		row.Hidden = rawrow.Hidden
+		row.OutlineLevel = rawrow.OutlineLevel
 
 		insertColIndex = minCol
 		for _, rawcell := range rawrow.C {
@@ -658,6 +662,8 @@ func readSheetFromFile(sc chan *indexedSheet, index int, rsheet xlsxSheet, fi *F
 
 	sheet.SheetFormat.DefaultColWidth = worksheet.SheetFormatPr.DefaultColWidth
 	sheet.SheetFormat.DefaultRowHeight = worksheet.SheetFormatPr.DefaultRowHeight
+	sheet.SheetFormat.OutlineLevelCol = worksheet.SheetFormatPr.OutlineLevelCol
+	sheet.SheetFormat.OutlineLevelRow = worksheet.SheetFormatPr.OutlineLevelRow
 
 	result.Sheet = sheet
 	sc <- result

+ 6 - 5
row.go

@@ -1,11 +1,12 @@
 package xlsx
 
 type Row struct {
-	Cells    []*Cell
-	Hidden   bool
-	Sheet    *Sheet
-	Height   float64
-	isCustom bool
+	Cells        []*Cell
+	Hidden       bool
+	Sheet        *Sheet
+	Height       float64
+	OutlineLevel uint8
+	isCustom     bool
 }
 
 func (r *Row) SetHeightCM(ht float64) {

+ 25 - 6
sheet.go

@@ -35,6 +35,8 @@ type Pane struct {
 type SheetFormat struct {
 	DefaultColWidth  float64
 	DefaultRowHeight float64
+	OutlineLevelCol  uint8
+	OutlineLevelRow  uint8
 }
 
 // Add a new Row to a Sheet
@@ -178,6 +180,7 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 	xSheet := xlsxSheetData{}
 	maxRow := 0
 	maxCell := 0
+	var maxLevelCol, maxLevelRow uint8
 
 	// Scan through the sheet and see if there are any merged cells. If there
 	// are, we may need to extend the size of the sheet. There needs to be
@@ -219,13 +222,18 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 		}
 		worksheet.Cols.Col = append(worksheet.Cols.Col,
 			xlsxCol{Min: col.Min,
-				Max:         col.Max,
-				Hidden:      col.Hidden,
-				Width:       col.Width,
-				CustomWidth: customWidth,
-				Collapsed:   col.Collapsed,
-				Style:       XfId,
+				Max:          col.Max,
+				Hidden:       col.Hidden,
+				Width:        col.Width,
+				CustomWidth:  customWidth,
+				Collapsed:    col.Collapsed,
+				OutlineLevel: col.OutlineLevel,
+				Style:        XfId,
 			})
+
+		if col.OutlineLevel > maxLevelCol {
+			maxLevelCol = col.OutlineLevel
+		}
 	}
 
 	for r, row := range s.Rows {
@@ -238,6 +246,10 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 			xRow.CustomHeight = true
 			xRow.Ht = fmt.Sprintf("%g", row.Height)
 		}
+		xRow.OutlineLevel = row.OutlineLevel
+		if row.OutlineLevel > maxLevelRow {
+			maxLevelRow = row.OutlineLevel
+		}
 		for c, cell := range row.Cells {
 			XfId := colsXfIdList[c]
 
@@ -306,6 +318,13 @@ func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxW
 		xSheet.Row = append(xSheet.Row, xRow)
 	}
 
+	// Update sheet format with the freshly determined max levels
+	s.SheetFormat.OutlineLevelCol = maxLevelCol
+	s.SheetFormat.OutlineLevelRow = maxLevelRow
+	// .. and then also apply this to the xml worksheet
+	worksheet.SheetFormatPr.OutlineLevelCol = s.SheetFormat.OutlineLevelCol
+	worksheet.SheetFormatPr.OutlineLevelRow = s.SheetFormat.OutlineLevelRow
+
 	if worksheet.MergeCells != nil {
 		worksheet.MergeCells.Count = len(worksheet.MergeCells.Cells)
 	}

+ 41 - 0
sheet_test.go

@@ -351,3 +351,44 @@ func (s *SheetSuite) TestBorder(c *C) {
 
 	c.Assert(worksheet.SheetData.Row[0].C[0].S, Equals, 1)
 }
+
+func (s *SheetSuite) TestOutlineLevels(c *C) {
+	file := NewFile()
+	sheet, _ := file.AddSheet("Sheet1")
+
+	r1 := sheet.AddRow()
+	c11 := r1.AddCell()
+	c11.Value = "A1"
+	c12 := r1.AddCell()
+	c12.Value = "B1"
+
+	r2 := sheet.AddRow()
+	c21 := r2.AddCell()
+	c21.Value = "A2"
+	c22 := r2.AddCell()
+	c22.Value = "B2"
+
+	r3 := sheet.AddRow()
+	c31 := r3.AddCell()
+	c31.Value = "A3"
+	c32 := r3.AddCell()
+	c32.Value = "B3"
+
+	// Add some groups
+	r1.OutlineLevel = 1
+	r2.OutlineLevel = 2
+	sheet.Col(0).OutlineLevel = 1
+
+	refTable := NewSharedStringRefTable()
+	styles := newXlsxStyleSheet(nil)
+	worksheet := sheet.makeXLSXSheet(refTable, styles)
+
+	c.Assert(worksheet.SheetFormatPr.OutlineLevelCol, Equals, uint8(1))
+	c.Assert(worksheet.SheetFormatPr.OutlineLevelRow, Equals, uint8(2))
+
+	c.Assert(worksheet.Cols.Col[0].OutlineLevel, Equals, uint8(1))
+	c.Assert(worksheet.Cols.Col[1].OutlineLevel, Equals, uint8(0))
+	c.Assert(worksheet.SheetData.Row[0].OutlineLevel, Equals, uint8(1))
+	c.Assert(worksheet.SheetData.Row[1].OutlineLevel, Equals, uint8(2))
+	c.Assert(worksheet.SheetData.Row[2].OutlineLevel, Equals, uint8(0))
+}

+ 11 - 7
xmlWorksheet.go

@@ -105,6 +105,8 @@ type xlsxPageMargins struct {
 type xlsxSheetFormatPr struct {
 	DefaultColWidth  float64 `xml:"defaultColWidth,attr,omitempty"`
 	DefaultRowHeight float64 `xml:"defaultRowHeight,attr"`
+	OutlineLevelCol  uint8   `xml:"outlineLevelCol,attr,omitempty"`
+	OutlineLevelRow  uint8   `xml:"outlineLevelRow,attr,omitempty"`
 }
 
 // xlsxSheetViews directly maps the sheetViews element in the namespace
@@ -193,13 +195,14 @@ type xlsxCols struct {
 // currently I have not checked it for completeness - it does as much
 // as I need.
 type xlsxCol struct {
-	Collapsed   bool    `xml:"collapsed,attr"`
-	Hidden      bool    `xml:"hidden,attr"`
-	Max         int     `xml:"max,attr"`
-	Min         int     `xml:"min,attr"`
-	Style       int     `xml:"style,attr"`
-	Width       float64 `xml:"width,attr"`
-	CustomWidth int     `xml:"customWidth,attr,omitempty"`
+	Collapsed    bool    `xml:"collapsed,attr"`
+	Hidden       bool    `xml:"hidden,attr"`
+	Max          int     `xml:"max,attr"`
+	Min          int     `xml:"min,attr"`
+	Style        int     `xml:"style,attr"`
+	Width        float64 `xml:"width,attr"`
+	CustomWidth  int     `xml:"customWidth,attr,omitempty"`
+	OutlineLevel uint8   `xml:"outlineLevel,attr,omitempty"`
 }
 
 // xlsxDimension directly maps the dimension element in the namespace
@@ -230,6 +233,7 @@ type xlsxRow struct {
 	C            []xlsxC `xml:"c"`
 	Ht           string  `xml:"ht,attr,omitempty"`
 	CustomHeight bool    `xml:"customHeight,attr,omitempty"`
+	OutlineLevel uint8   `xml:"outlineLevel,attr,omitempty"`
 }
 
 type xlsxMergeCell struct {