diff --git a/sheetpr.go b/sheetpr.go new file mode 100644 index 00000000..2a887176 --- /dev/null +++ b/sheetpr.go @@ -0,0 +1,139 @@ +package excelize + +// SheetPrOption is an option of a view of a worksheet. See SetSheetPrOptions(). +type SheetPrOption interface { + setSheetPrOption(view *xlsxSheetPr) +} + +// SheetPrOptionPtr is a writable SheetPrOption. See GetSheetPrOptions(). +type SheetPrOptionPtr interface { + SheetPrOption + getSheetPrOption(view *xlsxSheetPr) +} + +type ( + // CodeName is a SheetPrOption + CodeName string + // EnableFormatConditionsCalculation is a SheetPrOption + EnableFormatConditionsCalculation bool + // Published is a SheetPrOption + Published bool + // FitToPage is a SheetPrOption + FitToPage bool + // AutoPageBreaks is a SheetPrOption + AutoPageBreaks bool +) + +func (o CodeName) setSheetPrOption(pr *xlsxSheetPr) { + pr.CodeName = string(o) +} + +func (o *CodeName) getSheetPrOption(pr *xlsxSheetPr) { + if pr == nil { + *o = "" + return + } + *o = CodeName(pr.CodeName) +} + +func (o EnableFormatConditionsCalculation) setSheetPrOption(pr *xlsxSheetPr) { + pr.EnableFormatConditionsCalculation = boolPtr(bool(o)) +} + +func (o *EnableFormatConditionsCalculation) getSheetPrOption(pr *xlsxSheetPr) { + if pr == nil { + *o = true + return + } + *o = EnableFormatConditionsCalculation(defaultTrue(pr.EnableFormatConditionsCalculation)) +} + +func (o Published) setSheetPrOption(pr *xlsxSheetPr) { + pr.Published = boolPtr(bool(o)) +} + +func (o *Published) getSheetPrOption(pr *xlsxSheetPr) { + if pr == nil { + *o = true + return + } + *o = Published(defaultTrue(pr.Published)) +} + +func (o FitToPage) setSheetPrOption(pr *xlsxSheetPr) { + if pr.PageSetUpPr == nil { + if !o { + return + } + pr.PageSetUpPr = new(xlsxPageSetUpPr) + } + pr.PageSetUpPr.FitToPage = bool(o) +} + +func (o *FitToPage) getSheetPrOption(pr *xlsxSheetPr) { + // Excel default: false + if pr == nil || pr.PageSetUpPr == nil { + *o = false + return + } + *o = FitToPage(pr.PageSetUpPr.FitToPage) +} + +func (o AutoPageBreaks) setSheetPrOption(pr *xlsxSheetPr) { + if pr.PageSetUpPr == nil { + if !o { + return + } + pr.PageSetUpPr = new(xlsxPageSetUpPr) + } + pr.PageSetUpPr.AutoPageBreaks = bool(o) +} + +func (o *AutoPageBreaks) getSheetPrOption(pr *xlsxSheetPr) { + // Excel default: false + if pr == nil || pr.PageSetUpPr == nil { + *o = false + return + } + *o = AutoPageBreaks(pr.PageSetUpPr.AutoPageBreaks) +} + +// SetSheetPrOptions sets sheet properties. +// +// Available options: +// CodeName(string) +// EnableFormatConditionsCalculation(bool) +// Published(bool) +// FitToPage(bool) +// AutoPageBreaks(bool) +func (f *File) SetSheetPrOptions(name string, opts ...SheetPrOption) error { + sheet := f.workSheetReader(name) + pr := sheet.SheetPr + if pr == nil { + pr = new(xlsxSheetPr) + sheet.SheetPr = pr + } + + for _, opt := range opts { + opt.setSheetPrOption(pr) + } + return nil +} + +// SetSheetPrOptions sets sheet properties. +// +// Available options: +// CodeName(string) +// EnableFormatConditionsCalculation(bool) +// Published(bool) +// FitToPage(bool) +// AutoPageBreaks(bool) +func (f *File) GetSheetPrOptions(name string, opts ...SheetPrOptionPtr) error { + sheet := f.workSheetReader(name) + pr := sheet.SheetPr + + for _, opt := range opts { + opt.getSheetPrOption(pr) + } + return nil +} diff --git a/sheetpr_test.go b/sheetpr_test.go new file mode 100644 index 00000000..c28ee052 --- /dev/null +++ b/sheetpr_test.go @@ -0,0 +1,154 @@ +package excelize_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/mohae/deepcopy" + + "github.com/360EntSecGroup-Skylar/excelize" +) + +var _ = []excelize.SheetPrOption{ + excelize.CodeName("hello"), + excelize.EnableFormatConditionsCalculation(false), + excelize.Published(false), + excelize.FitToPage(true), + excelize.AutoPageBreaks(true), +} + +var _ = []excelize.SheetPrOptionPtr{ + (*excelize.CodeName)(nil), + (*excelize.EnableFormatConditionsCalculation)(nil), + (*excelize.Published)(nil), + (*excelize.FitToPage)(nil), + (*excelize.AutoPageBreaks)(nil), +} + +func ExampleFile_SetSheetPrOptions() { + xl := excelize.NewFile() + const sheet = "Sheet1" + + if err := xl.SetSheetPrOptions(sheet, + excelize.CodeName("code"), + excelize.EnableFormatConditionsCalculation(false), + excelize.Published(false), + excelize.FitToPage(true), + excelize.AutoPageBreaks(true), + ); err != nil { + panic(err) + } + // Output: +} + +func ExampleFile_GetSheetPrOptions() { + xl := excelize.NewFile() + const sheet = "Sheet1" + + var ( + codeName excelize.CodeName + enableFormatConditionsCalculation excelize.EnableFormatConditionsCalculation + published excelize.Published + fitToPage excelize.FitToPage + autoPageBreaks excelize.AutoPageBreaks + ) + + if err := xl.GetSheetPrOptions(sheet, + &codeName, + &enableFormatConditionsCalculation, + &published, + &fitToPage, + &autoPageBreaks, + ); err != nil { + panic(err) + } + fmt.Println("Defaults:") + fmt.Printf("- codeName: %q\n", codeName) + fmt.Println("- enableFormatConditionsCalculation:", enableFormatConditionsCalculation) + fmt.Println("- published:", published) + fmt.Println("- fitToPage:", fitToPage) + fmt.Println("- autoPageBreaks:", autoPageBreaks) + // Output: + // Defaults: + // - codeName: "" + // - enableFormatConditionsCalculation: true + // - published: true + // - fitToPage: false + // - autoPageBreaks: false +} + +func TestSheetPrOptions(t *testing.T) { + const sheet = "Sheet1" + for _, test := range []struct { + container excelize.SheetPrOptionPtr + nonDefault excelize.SheetPrOption + }{ + {new(excelize.CodeName), excelize.CodeName("xx")}, + {new(excelize.EnableFormatConditionsCalculation), excelize.EnableFormatConditionsCalculation(false)}, + {new(excelize.Published), excelize.Published(false)}, + {new(excelize.FitToPage), excelize.FitToPage(true)}, + {new(excelize.AutoPageBreaks), excelize.AutoPageBreaks(true)}, + } { + opt := test.nonDefault + t.Logf("option %T", opt) + + def := deepcopy.Copy(test.container).(excelize.SheetPrOptionPtr) + val1 := deepcopy.Copy(def).(excelize.SheetPrOptionPtr) + val2 := deepcopy.Copy(def).(excelize.SheetPrOptionPtr) + + xl := excelize.NewFile() + // Get the default value + if err := xl.GetSheetPrOptions(sheet, def); err != nil { + t.Fatalf("%T: %s", opt, err) + } + // Get again and check + if err := xl.GetSheetPrOptions(sheet, val1); err != nil { + t.Fatalf("%T: %s", opt, err) + } + if !reflect.DeepEqual(val1, def) { + t.Fatalf("%T: value should not have changed", opt) + } + // Set the same value + if err := xl.SetSheetPrOptions(sheet, val1); err != nil { + t.Fatalf("%T: %s", opt, err) + } + // Get again and check + if err := xl.GetSheetPrOptions(sheet, val1); err != nil { + t.Fatalf("%T: %s", opt, err) + } + if !reflect.DeepEqual(val1, def) { + t.Fatalf("%T: value should not have changed", opt) + } + + // Set a different value + if err := xl.SetSheetPrOptions(sheet, test.nonDefault); err != nil { + t.Fatalf("%T: %s", opt, err) + } + if err := xl.GetSheetPrOptions(sheet, val1); err != nil { + t.Fatalf("%T: %s", opt, err) + } + // Get again and compare + if err := xl.GetSheetPrOptions(sheet, val2); err != nil { + t.Fatalf("%T: %s", opt, err) + } + if !reflect.DeepEqual(val2, val1) { + t.Fatalf("%T: value should not have changed", opt) + } + // Value should not be the same as the default + if reflect.DeepEqual(val1, def) { + t.Fatalf("%T: value should have changed from default", opt) + } + + // Restore the default value + if err := xl.SetSheetPrOptions(sheet, def); err != nil { + t.Fatalf("%T: %s", opt, err) + } + if err := xl.GetSheetPrOptions(sheet, val1); err != nil { + t.Fatalf("%T: %s", opt, err) + } + if !reflect.DeepEqual(val1, def) { + t.Fatalf("%T: value should now be the same as default", opt) + } + } +} diff --git a/xmlWorksheet.go b/xmlWorksheet.go index 9b46a285..748ca1fb 100644 --- a/xmlWorksheet.go +++ b/xmlWorksheet.go @@ -196,7 +196,7 @@ type xlsxSheetPr struct { CodeName string `xml:"codeName,attr,omitempty"` EnableFormatConditionsCalculation *bool `xml:"enableFormatConditionsCalculation,attr"` FilterMode bool `xml:"filterMode,attr,omitempty"` - Published bool `xml:"published,attr,omitempty"` + Published *bool `xml:"published,attr"` SyncHorizontal bool `xml:"syncHorizontal,attr,omitempty"` SyncVertical bool `xml:"syncVertical,attr,omitempty"` TransitionEntry bool `xml:"transitionEntry,attr,omitempty"`