diff --git a/cell.go b/cell.go index ab42b7237a..a25f2e4cf3 100644 --- a/cell.go +++ b/cell.go @@ -228,7 +228,7 @@ func (f *File) SetCellStr(sheet, axis, value string) error { if len(value) > 32767 { value = value[0:32767] } - // Leading space(s) character detection. + // Leading and ending space(s) character detection. if len(value) > 0 && (value[0] == 32 || value[len(value)-1] == 32) { cellData.XMLSpace = xml.Attr{ Name: xml.Name{Space: NameSpaceXML, Local: "space"}, diff --git a/rows_test.go b/rows_test.go index d52c635590..a99a594dd3 100644 --- a/rows_test.go +++ b/rows_test.go @@ -669,6 +669,11 @@ func TestDuplicateRowInvalidRownum(t *testing.T) { } } +func TestErrSheetNotExistError(t *testing.T) { + err := ErrSheetNotExist{SheetName: "Sheet1"} + assert.EqualValues(t, err.Error(), "Sheet Sheet1 is not exist") +} + func BenchmarkRows(b *testing.B) { for i := 0; i < b.N; i++ { f, _ := OpenFile(filepath.Join("test", "Book1.xlsx")) diff --git a/sheet.go b/sheet.go index ce3e6450fb..951baf9239 100644 --- a/sheet.go +++ b/sheet.go @@ -1401,162 +1401,3 @@ func makeContiguousColumns(xlsx *xlsxWorksheet, fromRow, toRow, colCount int) { fillColumns(rowData, colCount, fromRow) } } - -type ( - PageMarginBottom float64 - PageMarginFooter float64 - PageMarginHeader float64 - PageMarginLeft float64 - PageMarginRight float64 - PageMarginTop float64 -) - -// setPageMargins provides a method to set the bottom margin for the worksheet. -func (p PageMarginBottom) setPageMargins(ps *xlsxPageMargins) { - ps.Bottom = float64(p) -} - -// setPageMargins provides a method to get the bottom margin for the worksheet. -func (o *PageMarginBottom) getPageMargins(ps *xlsxPageMargins) { - // Excel default: portrait - if ps == nil || ps.Bottom == 0 { - *o = 0.75 - return - } - *o = PageMarginBottom(ps.Bottom) -} - -// setPageMargins provides a method to set the Footer margin for the worksheet. -func (p PageMarginFooter) setPageMargins(ps *xlsxPageMargins) { - ps.Footer = float64(p) -} - -// setPageMargins provides a method to get the Footer margin for the worksheet. -func (o *PageMarginFooter) getPageMargins(ps *xlsxPageMargins) { - // Excel default: portrait - if ps == nil || ps.Footer == 0 { - *o = 0.3 - return - } - *o = PageMarginFooter(ps.Footer) -} - -// setPageMargins provides a method to set the Header margin for the worksheet. -func (p PageMarginHeader) setPageMargins(ps *xlsxPageMargins) { - ps.Header = float64(p) -} - -// setPageMargins provides a method to get the Header margin for the worksheet. -func (o *PageMarginHeader) getPageMargins(ps *xlsxPageMargins) { - // Excel default: portrait - if ps == nil || ps.Header == 0 { - *o = 0.3 - return - } - *o = PageMarginHeader(ps.Header) -} - -// setPageMargins provides a method to set the left margin for the worksheet. -func (p PageMarginLeft) setPageMargins(ps *xlsxPageMargins) { - ps.Left = float64(p) -} - -// setPageMargins provides a method to get the left margin for the worksheet. -func (o *PageMarginLeft) getPageMargins(ps *xlsxPageMargins) { - // Excel default: portrait - if ps == nil || ps.Left == 0 { - *o = 0.7 - return - } - *o = PageMarginLeft(ps.Left) -} - -// setPageMargins provides a method to set the right margin for the worksheet. -func (p PageMarginRight) setPageMargins(ps *xlsxPageMargins) { - ps.Right = float64(p) -} - -// setPageMargins provides a method to get the right margin for the worksheet. -func (o *PageMarginRight) getPageMargins(ps *xlsxPageMargins) { - // Excel default: portrait - if ps == nil || ps.Right == 0 { - *o = 0.7 - return - } - *o = PageMarginRight(ps.Right) -} - -// setPageMargins provides a method to set the top margin for the worksheet. -func (p PageMarginTop) setPageMargins(ps *xlsxPageMargins) { - ps.Top = float64(p) -} - -// setPageMargins provides a method to get the top margin for the worksheet. -func (o *PageMarginTop) getPageMargins(ps *xlsxPageMargins) { - // Excel default: portrait - if ps == nil || ps.Top == 0 { - *o = 0.75 - return - } - *o = PageMarginTop(ps.Top) -} - -// PageMarginsOptions is an option of a page margin of a worksheet. See -// SetPageMargins(). -type PageMarginsOptions interface { - setPageMargins(layout *xlsxPageMargins) -} - -// PageMarginsOptionsPtr is a writable PageMarginsOptions. See GetPageMargins(). -type PageMarginsOptionsPtr interface { - PageMarginsOptions - getPageMargins(layout *xlsxPageMargins) -} - -// SetPageMargins provides a function to set worksheet page lmargins. -// -// Available options: -// PageMarginBotom(float64) -// PageMarginFooter(float64) -// PageMarginHeader(float64) -// PageMarginLeft(float64) -// PageMarginRightfloat64) -// PageMarginTop(float64) -func (f *File) SetPageMargins(sheet string, opts ...PageMarginsOptions) error { - s, err := f.workSheetReader(sheet) - if err != nil { - return err - } - ps := s.PageMargins - if ps == nil { - ps = new(xlsxPageMargins) - s.PageMargins = ps - } - - for _, opt := range opts { - opt.setPageMargins(ps) - } - return err -} - -// GetPageMargins provides a function to get worksheet page margins. -// -// Available options: -// PageMarginBotom(float64) -// PageMarginFooter(float64) -// PageMarginHeader(float64) -// PageMarginLeft(float64) -// PageMarginRightfloat64) -// PageMarginTop(float64) -func (f *File) GetPageMargins(sheet string, opts ...PageMarginsOptionsPtr) error { - s, err := f.workSheetReader(sheet) - if err != nil { - return err - } - ps := s.PageMargins - - for _, opt := range opts { - opt.getPageMargins(ps) - } - return err -} diff --git a/sheet_test.go b/sheet_test.go index 6bfa7dcaf6..51797935b0 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -247,65 +247,3 @@ func TestGetSheetMap(t *testing.T) { } assert.Equal(t, len(sheetMap), 2) } - -func TestPageMarginsOption(t *testing.T) { - const sheet = "Sheet1" - - testData := []struct { - container excelize.PageMarginsOptionsPtr - nonDefault excelize.PageMarginsOptions - }{ - {new(excelize.PageMarginTop), excelize.PageMarginTop(1.0)}, - {new(excelize.PageMarginBottom), excelize.PageMarginBottom(1.0)}, - {new(excelize.PageMarginLeft), excelize.PageMarginLeft(1.0)}, - {new(excelize.PageMarginRight), excelize.PageMarginRight(1.0)}, - {new(excelize.PageMarginHeader), excelize.PageMarginHeader(1.0)}, - {new(excelize.PageMarginFooter), excelize.PageMarginFooter(1.0)}, - } - - for i, test := range testData { - t.Run(fmt.Sprintf("TestData%d", i), func(t *testing.T) { - - opt := test.nonDefault - t.Logf("option %T", opt) - - def := deepcopy.Copy(test.container).(excelize.PageMarginsOptionsPtr) - val1 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr) - val2 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr) - - f := excelize.NewFile() - // Get the default value - assert.NoError(t, f.GetPageMargins(sheet, def), opt) - // Get again and check - assert.NoError(t, f.GetPageMargins(sheet, val1), opt) - if !assert.Equal(t, val1, def, opt) { - t.FailNow() - } - // Set the same value - assert.NoError(t, f.SetPageMargins(sheet, val1), opt) - // Get again and check - assert.NoError(t, f.GetPageMargins(sheet, val1), opt) - if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) { - t.FailNow() - } - // Set a different value - assert.NoError(t, f.SetPageMargins(sheet, test.nonDefault), opt) - assert.NoError(t, f.GetPageMargins(sheet, val1), opt) - // Get again and compare - assert.NoError(t, f.GetPageMargins(sheet, val2), opt) - if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) { - t.FailNow() - } - // Value should not be the same as the default - if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opt) { - t.FailNow() - } - // Restore the default value - assert.NoError(t, f.SetPageMargins(sheet, def), opt) - assert.NoError(t, f.GetPageMargins(sheet, val1), opt) - if !assert.Equal(t, def, val1) { - t.FailNow() - } - }) - } -} diff --git a/sheetpr.go b/sheetpr.go index a273ac1a5f..086bd3a15d 100644 --- a/sheetpr.go +++ b/sheetpr.go @@ -191,3 +191,169 @@ func (f *File) GetSheetPrOptions(name string, opts ...SheetPrOptionPtr) error { } return err } + +type ( + // PageMarginBottom specifies the bottom margin for the page. + PageMarginBottom float64 + // PageMarginFooter specifies the footer margin for the page. + PageMarginFooter float64 + // PageMarginHeader specifies the header margin for the page. + PageMarginHeader float64 + // PageMarginLeft specifies the left margin for the page. + PageMarginLeft float64 + // PageMarginRight specifies the right margin for the page. + PageMarginRight float64 + // PageMarginTop specifies the top margin for the page. + PageMarginTop float64 +) + +// setPageMargins provides a method to set the bottom margin for the worksheet. +func (p PageMarginBottom) setPageMargins(pm *xlsxPageMargins) { + pm.Bottom = float64(p) +} + +// setPageMargins provides a method to get the bottom margin for the worksheet. +func (p *PageMarginBottom) getPageMargins(pm *xlsxPageMargins) { + // Excel default: 0.75 + if pm == nil || pm.Bottom == 0 { + *p = 0.75 + return + } + *p = PageMarginBottom(pm.Bottom) +} + +// setPageMargins provides a method to set the footer margin for the worksheet. +func (p PageMarginFooter) setPageMargins(pm *xlsxPageMargins) { + pm.Footer = float64(p) +} + +// setPageMargins provides a method to get the footer margin for the worksheet. +func (p *PageMarginFooter) getPageMargins(pm *xlsxPageMargins) { + // Excel default: 0.3 + if pm == nil || pm.Footer == 0 { + *p = 0.3 + return + } + *p = PageMarginFooter(pm.Footer) +} + +// setPageMargins provides a method to set the header margin for the worksheet. +func (p PageMarginHeader) setPageMargins(pm *xlsxPageMargins) { + pm.Header = float64(p) +} + +// setPageMargins provides a method to get the header margin for the worksheet. +func (p *PageMarginHeader) getPageMargins(pm *xlsxPageMargins) { + // Excel default: 0.3 + if pm == nil || pm.Header == 0 { + *p = 0.3 + return + } + *p = PageMarginHeader(pm.Header) +} + +// setPageMargins provides a method to set the left margin for the worksheet. +func (p PageMarginLeft) setPageMargins(pm *xlsxPageMargins) { + pm.Left = float64(p) +} + +// setPageMargins provides a method to get the left margin for the worksheet. +func (p *PageMarginLeft) getPageMargins(pm *xlsxPageMargins) { + // Excel default: 0.7 + if pm == nil || pm.Left == 0 { + *p = 0.7 + return + } + *p = PageMarginLeft(pm.Left) +} + +// setPageMargins provides a method to set the right margin for the worksheet. +func (p PageMarginRight) setPageMargins(pm *xlsxPageMargins) { + pm.Right = float64(p) +} + +// setPageMargins provides a method to get the right margin for the worksheet. +func (p *PageMarginRight) getPageMargins(pm *xlsxPageMargins) { + // Excel default: 0.7 + if pm == nil || pm.Right == 0 { + *p = 0.7 + return + } + *p = PageMarginRight(pm.Right) +} + +// setPageMargins provides a method to set the top margin for the worksheet. +func (p PageMarginTop) setPageMargins(pm *xlsxPageMargins) { + pm.Top = float64(p) +} + +// setPageMargins provides a method to get the top margin for the worksheet. +func (p *PageMarginTop) getPageMargins(pm *xlsxPageMargins) { + // Excel default: 0.75 + if pm == nil || pm.Top == 0 { + *p = 0.75 + return + } + *p = PageMarginTop(pm.Top) +} + +// PageMarginsOptions is an option of a page margin of a worksheet. See +// SetPageMargins(). +type PageMarginsOptions interface { + setPageMargins(layout *xlsxPageMargins) +} + +// PageMarginsOptionsPtr is a writable PageMarginsOptions. See +// GetPageMargins(). +type PageMarginsOptionsPtr interface { + PageMarginsOptions + getPageMargins(layout *xlsxPageMargins) +} + +// SetPageMargins provides a function to set worksheet page margins. +// +// Available options: +// PageMarginBotom(float64) +// PageMarginFooter(float64) +// PageMarginHeader(float64) +// PageMarginLeft(float64) +// PageMarginRight(float64) +// PageMarginTop(float64) +func (f *File) SetPageMargins(sheet string, opts ...PageMarginsOptions) error { + s, err := f.workSheetReader(sheet) + if err != nil { + return err + } + pm := s.PageMargins + if pm == nil { + pm = new(xlsxPageMargins) + s.PageMargins = pm + } + + for _, opt := range opts { + opt.setPageMargins(pm) + } + return err +} + +// GetPageMargins provides a function to get worksheet page margins. +// +// Available options: +// PageMarginBotom(float64) +// PageMarginFooter(float64) +// PageMarginHeader(float64) +// PageMarginLeft(float64) +// PageMarginRight(float64) +// PageMarginTop(float64) +func (f *File) GetPageMargins(sheet string, opts ...PageMarginsOptionsPtr) error { + s, err := f.workSheetReader(sheet) + if err != nil { + return err + } + pm := s.PageMargins + + for _, opt := range opts { + opt.getPageMargins(pm) + } + return err +} diff --git a/sheetpr_test.go b/sheetpr_test.go index 97a314c918..d1ae2f1308 100644 --- a/sheetpr_test.go +++ b/sheetpr_test.go @@ -146,3 +146,164 @@ func TestSheetPrOptions(t *testing.T) { }) } } + +func TestSetSheetrOptions(t *testing.T) { + f := excelize.NewFile() + // Test SetSheetrOptions on not exists worksheet. + assert.EqualError(t, f.SetSheetPrOptions("SheetN"), "sheet SheetN is not exist") +} + +func TestGetSheetPrOptions(t *testing.T) { + f := excelize.NewFile() + // Test GetSheetPrOptions on not exists worksheet. + assert.EqualError(t, f.GetSheetPrOptions("SheetN"), "sheet SheetN is not exist") +} + +var _ = []excelize.PageMarginsOptions{ + excelize.PageMarginBottom(1.0), + excelize.PageMarginFooter(1.0), + excelize.PageMarginHeader(1.0), + excelize.PageMarginLeft(1.0), + excelize.PageMarginRight(1.0), + excelize.PageMarginTop(1.0), +} + +var _ = []excelize.PageMarginsOptionsPtr{ + (*excelize.PageMarginBottom)(nil), + (*excelize.PageMarginFooter)(nil), + (*excelize.PageMarginHeader)(nil), + (*excelize.PageMarginLeft)(nil), + (*excelize.PageMarginRight)(nil), + (*excelize.PageMarginTop)(nil), +} + +func ExampleFile_SetPageMargins() { + f := excelize.NewFile() + const sheet = "Sheet1" + + if err := f.SetPageMargins(sheet, + excelize.PageMarginBottom(1.0), + excelize.PageMarginFooter(1.0), + excelize.PageMarginHeader(1.0), + excelize.PageMarginLeft(1.0), + excelize.PageMarginRight(1.0), + excelize.PageMarginTop(1.0), + ); err != nil { + panic(err) + } + // Output: +} + +func ExampleFile_GetPageMargins() { + f := excelize.NewFile() + const sheet = "Sheet1" + + var ( + marginBottom excelize.PageMarginBottom + marginFooter excelize.PageMarginFooter + marginHeader excelize.PageMarginHeader + marginLeft excelize.PageMarginLeft + marginRight excelize.PageMarginRight + marginTop excelize.PageMarginTop + ) + + if err := f.GetPageMargins(sheet, + &marginBottom, + &marginFooter, + &marginHeader, + &marginLeft, + &marginRight, + &marginTop, + ); err != nil { + panic(err) + } + fmt.Println("Defaults:") + fmt.Println("- marginBottom:", marginBottom) + fmt.Println("- marginFooter:", marginFooter) + fmt.Println("- marginHeader:", marginHeader) + fmt.Println("- marginLeft:", marginLeft) + fmt.Println("- marginRight:", marginRight) + fmt.Println("- marginTop:", marginTop) + // Output: + // Defaults: + // - marginBottom: 0.75 + // - marginFooter: 0.3 + // - marginHeader: 0.3 + // - marginLeft: 0.7 + // - marginRight: 0.7 + // - marginTop: 0.75 +} + +func TestPageMarginsOption(t *testing.T) { + const sheet = "Sheet1" + + testData := []struct { + container excelize.PageMarginsOptionsPtr + nonDefault excelize.PageMarginsOptions + }{ + {new(excelize.PageMarginTop), excelize.PageMarginTop(1.0)}, + {new(excelize.PageMarginBottom), excelize.PageMarginBottom(1.0)}, + {new(excelize.PageMarginLeft), excelize.PageMarginLeft(1.0)}, + {new(excelize.PageMarginRight), excelize.PageMarginRight(1.0)}, + {new(excelize.PageMarginHeader), excelize.PageMarginHeader(1.0)}, + {new(excelize.PageMarginFooter), excelize.PageMarginFooter(1.0)}, + } + + for i, test := range testData { + t.Run(fmt.Sprintf("TestData%d", i), func(t *testing.T) { + + opt := test.nonDefault + t.Logf("option %T", opt) + + def := deepcopy.Copy(test.container).(excelize.PageMarginsOptionsPtr) + val1 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr) + val2 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr) + + f := excelize.NewFile() + // Get the default value + assert.NoError(t, f.GetPageMargins(sheet, def), opt) + // Get again and check + assert.NoError(t, f.GetPageMargins(sheet, val1), opt) + if !assert.Equal(t, val1, def, opt) { + t.FailNow() + } + // Set the same value + assert.NoError(t, f.SetPageMargins(sheet, val1), opt) + // Get again and check + assert.NoError(t, f.GetPageMargins(sheet, val1), opt) + if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) { + t.FailNow() + } + // Set a different value + assert.NoError(t, f.SetPageMargins(sheet, test.nonDefault), opt) + assert.NoError(t, f.GetPageMargins(sheet, val1), opt) + // Get again and compare + assert.NoError(t, f.GetPageMargins(sheet, val2), opt) + if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) { + t.FailNow() + } + // Value should not be the same as the default + if !assert.NotEqual(t, def, val1, "%T: value should have changed from default", opt) { + t.FailNow() + } + // Restore the default value + assert.NoError(t, f.SetPageMargins(sheet, def), opt) + assert.NoError(t, f.GetPageMargins(sheet, val1), opt) + if !assert.Equal(t, def, val1) { + t.FailNow() + } + }) + } +} + +func TestSetPageMargins(t *testing.T) { + f := excelize.NewFile() + // Test set page margins on not exists worksheet. + assert.EqualError(t, f.SetPageMargins("SheetN"), "sheet SheetN is not exist") +} + +func TestGetPageMargins(t *testing.T) { + f := excelize.NewFile() + // Test get page margins on not exists worksheet. + assert.EqualError(t, f.GetPageMargins("SheetN"), "sheet SheetN is not exist") +} diff --git a/templates.go b/templates.go index 0d3a0c58a4..b570910793 100644 --- a/templates.go +++ b/templates.go @@ -29,7 +29,7 @@ const templateWorkbook = `` -const templateSheet = `` +const templateSheet = `` const templateWorkbookRels = `` diff --git a/xmlPivotCache.go b/xmlPivotCache.go index a4b07118e8..45b48de99c 100644 --- a/xmlPivotCache.go +++ b/xmlPivotCache.go @@ -48,7 +48,7 @@ type xlsxPivotCacheDefinition struct { // PivotTable. type xlsxCacheSource struct { Type string `xml:"type,attr"` - ConnectionId int `xml:"connectionId,attr,omitempty"` + ConnectionID int `xml:"connectionId,attr,omitempty"` WorksheetSource *xlsxWorksheetSource `xml:"worksheetSource"` Consolidation *xlsxConsolidation `xml:"consolidation"` ExtLst *xlsxExtLst `xml:"extLst"` @@ -89,7 +89,7 @@ type xlsxCacheField struct { PropertyName string `xml:"propertyName,attr,omitempty"` ServerField bool `xml:"serverField,attr,omitempty"` UniqueList bool `xml:"uniqueList,attr,omitempty"` - NumFmtId int `xml:"numFmtId,attr"` + NumFmtID int `xml:"numFmtId,attr"` Formula string `xml:"formula,attr,omitempty"` SQLType int `xml:"sqlType,attr,omitempty"` Hierarchy int `xml:"hierarchy,attr,omitempty"` diff --git a/xmlPivotTable.go b/xmlPivotTable.go index 3738ed82b2..0549c5e39c 100644 --- a/xmlPivotTable.go +++ b/xmlPivotTable.go @@ -125,7 +125,7 @@ type xlsxPivotField struct { UniqueMemberProperty string `xml:"uniqueMemberProperty,attr,omitempty"` Compact bool `xml:"compact,attr"` AllDrilled bool `xml:"allDrilled,attr,omitempty"` - NumFmtId string `xml:"numFmtId,attr,omitempty"` + NumFmtID string `xml:"numFmtId,attr,omitempty"` Outline bool `xml:"outline,attr"` SubtotalTop bool `xml:"subtotalTop,attr,omitempty"` DragToRow bool `xml:"dragToRow,attr,omitempty"` @@ -273,7 +273,7 @@ type xlsxDataField struct { ShowDataAs string `xml:"showDataAs,attr,omitempty"` BaseField int `xml:"baseField,attr,omitempty"` BaseItem int64 `xml:"baseItem,attr,omitempty"` - NumFmtId string `xml:"numFmtId,attr,omitempty"` + NumFmtID string `xml:"numFmtId,attr,omitempty"` ExtLst *xlsxExtLst `xml:"extLst"` }