Browse Source

Add SetSheetViewOptions and GetSheetViewOptions (#145)

Two new methods:
- SetSheetViewOptions(sheetName string, viewIndex int, opts ...SheetViewOption) error
- GetSheetViewOptions(sheetName string, viewIndex int, opts ...SheetViewOptionPtr) error

The option values are given by the user through types that have privates methods
that implement the private SheetViewOption and SheetViewOptionPtr interfaces:
- DefaultGridColor(bool)
- RightToLeft(bool)
- ShowFormulas(bool)
- ShowGridLines(bool)
- ShowRowColHeaders(bool)

Examples:
    err := xl.SetSheetViewOptions("Sheet1", -1, excelize.ShowGridLines(true))

    var showGridLines excelize.ShowGridLines
    err := xl.GetSheetViewOptions("Sheet1", -1, &showGridLines)

Fixes #145.
Olivier Mengué 8 years ago
parent
commit
88e48e079a
4 changed files with 275 additions and 3 deletions
  1. 11 0
      lib.go
  2. 138 0
      sheetview.go
  3. 122 0
      sheetview_test.go
  4. 4 3
      xmlWorksheet.go

+ 11 - 0
lib.go

@@ -121,3 +121,14 @@ func deepCopy(dst, src interface{}) error {
 	}
 	}
 	return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
 	return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
 }
 }
+
+// boolPtr returns a pointer to a bool with the given value.
+func boolPtr(b bool) *bool { return &b }
+
+// defaultTrue returns true if b is nil, or the pointed value.
+func defaultTrue(b *bool) bool {
+	if b == nil {
+		return true
+	}
+	return *b
+}

+ 138 - 0
sheetview.go

@@ -0,0 +1,138 @@
+package excelize
+
+import "fmt"
+
+// SheetViewOption is an option of a view of a worksheet. See SetSheetViewOptions().
+type SheetViewOption interface {
+	setSheetViewOption(view *xlsxSheetView)
+}
+
+// SheetViewOptionPtr is a writable SheetViewOption. See GetSheetViewOptions().
+type SheetViewOptionPtr interface {
+	getSheetViewOption(view *xlsxSheetView)
+}
+
+type (
+	// DefaultGridColor is a SheetViewOption.
+	DefaultGridColor bool
+	// RightToLeft is a SheetViewOption.
+	RightToLeft bool
+	// ShowFormulas is a SheetViewOption.
+	ShowFormulas bool
+	// ShowGridLines is a SheetViewOption.
+	ShowGridLines bool
+	// ShowRowColHeaders is a SheetViewOption.
+	ShowRowColHeaders bool
+	/* TODO
+	// ShowWhiteSpace is a SheetViewOption.
+	ShowWhiteSpace bool
+	// ShowZeros is a SheetViewOption.
+	ShowZeros bool
+	// WindowProtection is a SheetViewOption.
+	WindowProtection bool
+	*/
+)
+
+// Defaults for each option are described in XML schema for CT_SheetView
+
+func (o DefaultGridColor) setSheetViewOption(view *xlsxSheetView) {
+	view.DefaultGridColor = boolPtr(bool(o))
+}
+
+func (o *DefaultGridColor) getSheetViewOption(view *xlsxSheetView) {
+	*o = DefaultGridColor(defaultTrue(view.DefaultGridColor)) // Excel default: true
+}
+
+func (o RightToLeft) setSheetViewOption(view *xlsxSheetView) {
+	view.RightToLeft = bool(o) // Excel default: false
+}
+
+func (o *RightToLeft) getSheetViewOption(view *xlsxSheetView) {
+	*o = RightToLeft(view.RightToLeft)
+}
+
+func (o ShowFormulas) setSheetViewOption(view *xlsxSheetView) {
+	view.ShowFormulas = bool(o) // Excel default: false
+}
+
+func (o *ShowFormulas) getSheetViewOption(view *xlsxSheetView) {
+	*o = ShowFormulas(view.ShowFormulas) // Excel default: false
+}
+
+func (o ShowGridLines) setSheetViewOption(view *xlsxSheetView) {
+	view.ShowGridLines = boolPtr(bool(o))
+}
+
+func (o *ShowGridLines) getSheetViewOption(view *xlsxSheetView) {
+	*o = ShowGridLines(defaultTrue(view.ShowGridLines)) // Excel default: true
+}
+
+func (o ShowRowColHeaders) setSheetViewOption(view *xlsxSheetView) {
+	view.ShowRowColHeaders = boolPtr(bool(o))
+}
+
+func (o *ShowRowColHeaders) getSheetViewOption(view *xlsxSheetView) {
+	*o = ShowRowColHeaders(defaultTrue(view.ShowRowColHeaders)) // Excel default: true
+}
+
+// getSheetView returns the SheetView object
+func (f *File) getSheetView(sheetName string, viewIndex int) (*xlsxSheetView, error) {
+	xlsx := f.workSheetReader(sheetName)
+	if viewIndex < 0 {
+		if viewIndex < -len(xlsx.SheetViews.SheetView) {
+			return nil, fmt.Errorf("view index %d out of range", viewIndex)
+		}
+		viewIndex = len(xlsx.SheetViews.SheetView) + viewIndex
+	} else if viewIndex >= len(xlsx.SheetViews.SheetView) {
+		return nil, fmt.Errorf("view index %d out of range", viewIndex)
+	}
+
+	return &(xlsx.SheetViews.SheetView[viewIndex]), nil
+}
+
+// SetSheetViewOptions sets sheet view options.
+// The viewIndex may be negative and if so is counted backward (-1 is the last view).
+//
+// Available options:
+//    DefaultGridColor(bool)
+//    RightToLeft(bool)
+//    ShowFormulas(bool)
+//    ShowGridLines(bool)
+//    ShowRowColHeaders(bool)
+// Example:
+//    err = f.SetSheetViewOptions("Sheet1", -1, ShowGridLines(false))
+func (f *File) SetSheetViewOptions(name string, viewIndex int, opts ...SheetViewOption) error {
+	view, err := f.getSheetView(name, viewIndex)
+	if err != nil {
+		return err
+	}
+
+	for _, opt := range opts {
+		opt.setSheetViewOption(view)
+	}
+	return nil
+}
+
+// GetSheetViewOptions gets the value of sheet view options.
+// The viewIndex may be negative and if so is counted backward (-1 is the last view).
+//
+// Available options:
+//    DefaultGridColor(bool)
+//    RightToLeft(bool)
+//    ShowFormulas(bool)
+//    ShowGridLines(bool)
+//    ShowRowColHeaders(bool)
+// Example:
+//    var showGridLines excelize.ShowGridLines
+//    err = f.GetSheetViewOptions("Sheet1", -1, &showGridLines)
+func (f *File) GetSheetViewOptions(name string, viewIndex int, opts ...SheetViewOptionPtr) error {
+	view, err := f.getSheetView(name, viewIndex)
+	if err != nil {
+		return err
+	}
+
+	for _, opt := range opts {
+		opt.getSheetViewOption(view)
+	}
+	return nil
+}

+ 122 - 0
sheetview_test.go

@@ -0,0 +1,122 @@
+package excelize_test
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/360EntSecGroup-Skylar/excelize"
+)
+
+var _ = []excelize.SheetViewOption{
+	excelize.DefaultGridColor(true),
+	excelize.RightToLeft(false),
+	excelize.ShowFormulas(false),
+	excelize.ShowGridLines(true),
+	excelize.ShowRowColHeaders(true),
+}
+
+var _ = []excelize.SheetViewOptionPtr{
+	(*excelize.DefaultGridColor)(nil),
+	(*excelize.RightToLeft)(nil),
+	(*excelize.ShowFormulas)(nil),
+	(*excelize.ShowGridLines)(nil),
+	(*excelize.ShowRowColHeaders)(nil),
+}
+
+func ExampleFile_SetSheetViewOptions() {
+	xl := excelize.NewFile()
+	const sheet = "Sheet1"
+
+	if err := xl.SetSheetViewOptions(sheet, 0,
+		excelize.DefaultGridColor(false),
+		excelize.RightToLeft(false),
+		excelize.ShowFormulas(true),
+		excelize.ShowGridLines(true),
+		excelize.ShowRowColHeaders(true),
+	); err != nil {
+		panic(err)
+	}
+	// Output:
+}
+
+func ExampleFile_GetSheetViewOptions() {
+	xl := excelize.NewFile()
+	const sheet = "Sheet1"
+
+	var (
+		defaultGridColor  excelize.DefaultGridColor
+		rightToLeft       excelize.RightToLeft
+		showFormulas      excelize.ShowFormulas
+		showGridLines     excelize.ShowGridLines
+		showRowColHeaders excelize.ShowRowColHeaders
+	)
+
+	if err := xl.GetSheetViewOptions(sheet, 0,
+		&defaultGridColor,
+		&rightToLeft,
+		&showFormulas,
+		&showGridLines,
+		&showRowColHeaders,
+	); err != nil {
+		panic(err)
+	}
+
+	fmt.Println("Default:")
+	fmt.Println("- defaultGridColor:", defaultGridColor)
+	fmt.Println("- rightToLeft:", rightToLeft)
+	fmt.Println("- showFormulas:", showFormulas)
+	fmt.Println("- showGridLines:", showGridLines)
+	fmt.Println("- showRowColHeaders:", showRowColHeaders)
+
+	if err := xl.SetSheetViewOptions(sheet, 0, excelize.ShowGridLines(false)); err != nil {
+		panic(err)
+	}
+
+	if err := xl.GetSheetViewOptions(sheet, 0, &showGridLines); err != nil {
+		panic(err)
+	}
+
+	fmt.Println("After change:")
+	fmt.Println("- showGridLines:", showGridLines)
+
+	// Output:
+	// Default:
+	// - defaultGridColor: true
+	// - rightToLeft: false
+	// - showFormulas: false
+	// - showGridLines: true
+	// - showRowColHeaders: true
+	// After change:
+	// - showGridLines: false
+}
+
+func TestSheetViewOptionsErrors(t *testing.T) {
+	xl := excelize.NewFile()
+	const sheet = "Sheet1"
+
+	if err := xl.GetSheetViewOptions(sheet, 0); err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	}
+	if err := xl.GetSheetViewOptions(sheet, -1); err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	}
+	if err := xl.GetSheetViewOptions(sheet, 1); err == nil {
+		t.Error("Error expected but got nil")
+	}
+	if err := xl.GetSheetViewOptions(sheet, -2); err == nil {
+		t.Error("Error expected but got nil")
+	}
+
+	if err := xl.SetSheetViewOptions(sheet, 0); err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	}
+	if err := xl.SetSheetViewOptions(sheet, -1); err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	}
+	if err := xl.SetSheetViewOptions(sheet, 1); err == nil {
+		t.Error("Error expected but got nil")
+	}
+	if err := xl.SetSheetViewOptions(sheet, -2); err == nil {
+		t.Error("Error expected but got nil")
+	}
+}

+ 4 - 3
xmlWorksheet.go

@@ -145,17 +145,18 @@ type xlsxSheetViews struct {
 // last sheetView definition is loaded, and the others are discarded. When
 // last sheetView definition is loaded, and the others are discarded. When
 // multiple windows are viewing the same sheet, multiple sheetView elements
 // multiple windows are viewing the same sheet, multiple sheetView elements
 // (with corresponding workbookView entries) are saved.
 // (with corresponding workbookView entries) are saved.
+// See https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.sheetview.aspx
 type xlsxSheetView struct {
 type xlsxSheetView struct {
 	WindowProtection         bool             `xml:"windowProtection,attr,omitempty"`
 	WindowProtection         bool             `xml:"windowProtection,attr,omitempty"`
 	ShowFormulas             bool             `xml:"showFormulas,attr,omitempty"`
 	ShowFormulas             bool             `xml:"showFormulas,attr,omitempty"`
-	ShowGridLines            string           `xml:"showGridLines,attr,omitempty"`
-	ShowRowColHeaders        bool             `xml:"showRowColHeaders,attr,omitempty"`
+	ShowGridLines            *bool            `xml:"showGridLines,attr"`
+	ShowRowColHeaders        *bool            `xml:"showRowColHeaders,attr"`
 	ShowZeros                bool             `xml:"showZeros,attr,omitempty"`
 	ShowZeros                bool             `xml:"showZeros,attr,omitempty"`
 	RightToLeft              bool             `xml:"rightToLeft,attr,omitempty"`
 	RightToLeft              bool             `xml:"rightToLeft,attr,omitempty"`
 	TabSelected              bool             `xml:"tabSelected,attr,omitempty"`
 	TabSelected              bool             `xml:"tabSelected,attr,omitempty"`
 	ShowWhiteSpace           *bool            `xml:"showWhiteSpace,attr"`
 	ShowWhiteSpace           *bool            `xml:"showWhiteSpace,attr"`
 	ShowOutlineSymbols       bool             `xml:"showOutlineSymbols,attr,omitempty"`
 	ShowOutlineSymbols       bool             `xml:"showOutlineSymbols,attr,omitempty"`
-	DefaultGridColor         bool             `xml:"defaultGridColor,attr"`
+	DefaultGridColor         *bool            `xml:"defaultGridColor,attr"`
 	View                     string           `xml:"view,attr,omitempty"`
 	View                     string           `xml:"view,attr,omitempty"`
 	TopLeftCell              string           `xml:"topLeftCell,attr,omitempty"`
 	TopLeftCell              string           `xml:"topLeftCell,attr,omitempty"`
 	ColorID                  int              `xml:"colorId,attr,omitempty"`
 	ColorID                  int              `xml:"colorId,attr,omitempty"`