From 9ab6b220cddd01f593f8b5214f95b08a4aabe1e8 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Thu, 7 Nov 2024 09:26:18 -0500 Subject: [PATCH 1/3] Add PageOrder setting as part of PageLayoutOptions This controls whether page numbers are assigned in a zig-zag going across first, or down first. --- sheet.go | 7 +++++++ sheet_test.go | 1 + xmlWorksheet.go | 3 +++ 3 files changed, 11 insertions(+) diff --git a/sheet.go b/sheet.go index c52fb94c43..74a5f3574d 100644 --- a/sheet.go +++ b/sheet.go @@ -1652,6 +1652,10 @@ func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { ws.newPageSetUp() ws.PageSetUp.BlackAndWhite = *opts.BlackAndWhite } + if opts.PageOrder != nil && (*opts.PageOrder == "overThenDown" || *opts.PageOrder == "downThenOver") { + ws.newPageSetUp() + ws.PageSetUp.PageOrder = *opts.PageOrder + } } // GetPageLayout provides a function to gets worksheet page layout. @@ -1686,6 +1690,9 @@ func (f *File) GetPageLayout(sheet string) (PageLayoutOptions, error) { opts.FitToWidth = ws.PageSetUp.FitToWidth } opts.BlackAndWhite = boolPtr(ws.PageSetUp.BlackAndWhite) + if ws.PageSetUp.PageOrder != "" { + opts.PageOrder = stringPtr(ws.PageSetUp.PageOrder) + } } return opts, err } diff --git a/sheet_test.go b/sheet_test.go index 89aa507278..d897874ad1 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -210,6 +210,7 @@ func TestSetPageLayout(t *testing.T) { FitToHeight: intPtr(2), FitToWidth: intPtr(2), BlackAndWhite: boolPtr(true), + PageOrder: stringPtr("overThenDown"), } assert.NoError(t, f.SetPageLayout("Sheet1", &expected)) opts, err := f.GetPageLayout("Sheet1") diff --git a/xmlWorksheet.go b/xmlWorksheet.go index 43359d5d58..667bdf584c 100644 --- a/xmlWorksheet.go +++ b/xmlWorksheet.go @@ -1006,6 +1006,9 @@ type PageLayoutOptions struct { FitToWidth *int // BlackAndWhite specified print black and white. BlackAndWhite *bool + // PageOrder specifies the ordering of multiple pages. Values + // accepted: overThenDown, downThenOver + PageOrder *string } // ViewOptions directly maps the settings of sheet view. From f2e39c52d9490016117ac599934a8449b1e36346 Mon Sep 17 00:00:00 2001 From: xuri Date: Fri, 8 Nov 2024 14:24:48 +0800 Subject: [PATCH 2/3] Simplify code for the setPageSetUp function to reduce cyclomatic complexity --- sheet.go | 6 +++--- templates.go | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sheet.go b/sheet.go index 74a5f3574d..be4cd87651 100644 --- a/sheet.go +++ b/sheet.go @@ -1627,7 +1627,7 @@ func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { ws.newPageSetUp() ws.PageSetUp.PaperSize = opts.Size } - if opts.Orientation != nil && (*opts.Orientation == "portrait" || *opts.Orientation == "landscape") { + if opts.Orientation != nil && inStrSlice(supportedPageOrientation, *opts.Orientation, true) != -1 { ws.newPageSetUp() ws.PageSetUp.Orientation = *opts.Orientation } @@ -1652,7 +1652,7 @@ func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { ws.newPageSetUp() ws.PageSetUp.BlackAndWhite = *opts.BlackAndWhite } - if opts.PageOrder != nil && (*opts.PageOrder == "overThenDown" || *opts.PageOrder == "downThenOver") { + if opts.PageOrder != nil && inStrSlice(supportedPageOrder, *opts.PageOrder, true) != -1 { ws.newPageSetUp() ws.PageSetUp.PageOrder = *opts.PageOrder } @@ -1662,7 +1662,7 @@ func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { func (f *File) GetPageLayout(sheet string) (PageLayoutOptions, error) { opts := PageLayoutOptions{ Size: intPtr(0), - Orientation: stringPtr("portrait"), + Orientation: stringPtr(supportedPageOrientation[0]), FirstPageNumber: uintPtr(1), AdjustTo: uintPtr(100), } diff --git a/templates.go b/templates.go index 5aafc43e8a..68d8e1f69d 100644 --- a/templates.go +++ b/templates.go @@ -498,6 +498,12 @@ var supportedDrawingUnderlineTypes = []string{ // supportedPositioning defined supported positioning types. var supportedPositioning = []string{"absolute", "oneCell", "twoCell"} +// supportedPageOrientation defined supported page setup page orientation. +var supportedPageOrientation = []string{"portrait", "landscape"} + +// supportedPageOrder defined supported page setup page order. +var supportedPageOrder = []string{"overThenDown", "downThenOver"} + // builtInDefinedNames defined built-in defined names are built with a _xlnm prefix. var builtInDefinedNames = []string{"_xlnm.Print_Area", "_xlnm.Print_Titles", "_xlnm.Criteria", "_xlnm._FilterDatabase", "_xlnm.Extract", "_xlnm.Consolidate_Area", "_xlnm.Database", "_xlnm.Sheet_Title"} From 807b724edcbbe7270edd9987833a379545743846 Mon Sep 17 00:00:00 2001 From: xuri Date: Fri, 8 Nov 2024 15:46:36 +0800 Subject: [PATCH 3/3] An error will be return if the option value of the SetPageLayout function is invalid - Add a new exported error variable `ErrPageSetupAdjustTo` - Updated unit tests --- errors.go | 9 +++++++++ sheet.go | 21 +++++++++++++++------ sheet_test.go | 10 ++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/errors.go b/errors.go index 55a3c3c3e6..76708b41fa 100644 --- a/errors.go +++ b/errors.go @@ -88,6 +88,9 @@ var ( // ErrOutlineLevel defined the error message on receive an invalid outline // level number. ErrOutlineLevel = errors.New("invalid outline level") + // ErrPageSetupAdjustTo defined the error message for receiving a page setup + // adjust to value exceeds limit. + ErrPageSetupAdjustTo = errors.New("adjust to value must be between 10 and 400") // ErrParameterInvalid defined the error message on receive the invalid // parameter. ErrParameterInvalid = errors.New("parameter is invalid") @@ -249,6 +252,12 @@ func newInvalidNameError(name string) error { return fmt.Errorf("invalid name %q, the name should be starts with a letter or underscore, can not include a space or character, and can not conflict with an existing name in the workbook", name) } +// newInvalidPageLayoutValueError defined the error message on receiving the invalid +// page layout options value. +func newInvalidPageLayoutValueError(name, value, msg string) error { + return fmt.Errorf("invalid %s value %q, acceptable value should be one of %s", name, value, msg) +} + // newInvalidRowNumberError defined the error message on receiving the invalid // row number. func newInvalidRowNumberError(row int) error { diff --git a/sheet.go b/sheet.go index be4cd87651..5bff9b75d3 100644 --- a/sheet.go +++ b/sheet.go @@ -1609,8 +1609,7 @@ func (f *File) SetPageLayout(sheet string, opts *PageLayoutOptions) error { if opts == nil { return err } - ws.setPageSetUp(opts) - return err + return ws.setPageSetUp(opts) } // newPageSetUp initialize page setup settings for the worksheet if which not @@ -1622,12 +1621,15 @@ func (ws *xlsxWorksheet) newPageSetUp() { } // setPageSetUp set page setup settings for the worksheet by given options. -func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { +func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) error { if opts.Size != nil { ws.newPageSetUp() ws.PageSetUp.PaperSize = opts.Size } - if opts.Orientation != nil && inStrSlice(supportedPageOrientation, *opts.Orientation, true) != -1 { + if opts.Orientation != nil { + if inStrSlice(supportedPageOrientation, *opts.Orientation, true) == -1 { + return newInvalidPageLayoutValueError("Orientation", *opts.Orientation, strings.Join(supportedPageOrientation, ", ")) + } ws.newPageSetUp() ws.PageSetUp.Orientation = *opts.Orientation } @@ -1636,7 +1638,10 @@ func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { ws.PageSetUp.FirstPageNumber = strconv.Itoa(int(*opts.FirstPageNumber)) ws.PageSetUp.UseFirstPageNumber = true } - if opts.AdjustTo != nil && 10 <= *opts.AdjustTo && *opts.AdjustTo <= 400 { + if opts.AdjustTo != nil { + if *opts.AdjustTo < 10 || 400 < *opts.AdjustTo { + return ErrPageSetupAdjustTo + } ws.newPageSetUp() ws.PageSetUp.Scale = int(*opts.AdjustTo) } @@ -1652,10 +1657,14 @@ func (ws *xlsxWorksheet) setPageSetUp(opts *PageLayoutOptions) { ws.newPageSetUp() ws.PageSetUp.BlackAndWhite = *opts.BlackAndWhite } - if opts.PageOrder != nil && inStrSlice(supportedPageOrder, *opts.PageOrder, true) != -1 { + if opts.PageOrder != nil { + if inStrSlice(supportedPageOrder, *opts.PageOrder, true) == -1 { + return newInvalidPageLayoutValueError("PageOrder", *opts.PageOrder, strings.Join(supportedPageOrder, ", ")) + } ws.newPageSetUp() ws.PageSetUp.PageOrder = *opts.PageOrder } + return nil } // GetPageLayout provides a function to gets worksheet page layout. diff --git a/sheet_test.go b/sheet_test.go index d897874ad1..03f85eab85 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -220,6 +220,16 @@ func TestSetPageLayout(t *testing.T) { assert.EqualError(t, f.SetPageLayout("SheetN", nil), "sheet SheetN does not exist") // Test set page layout with invalid sheet name assert.EqualError(t, f.SetPageLayout("Sheet:1", nil), ErrSheetNameInvalid.Error()) + // Test set page layout with invalid parameters + assert.EqualError(t, f.SetPageLayout("Sheet1", &PageLayoutOptions{ + AdjustTo: uintPtr(5), + }), "adjust to value must be between 10 and 400") + assert.EqualError(t, f.SetPageLayout("Sheet1", &PageLayoutOptions{ + Orientation: stringPtr("x"), + }), "invalid Orientation value \"x\", acceptable value should be one of portrait, landscape") + assert.EqualError(t, f.SetPageLayout("Sheet1", &PageLayoutOptions{ + PageOrder: stringPtr("x"), + }), "invalid PageOrder value \"x\", acceptable value should be one of overThenDown, downThenOver") } func TestGetPageLayout(t *testing.T) {