summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2020-03-01 00:34:41 +0800
committerxuri <xuri.me@gmail.com>2020-03-01 00:34:41 +0800
commit1d87da57ecf5e13203b6441dd97160885981545e (patch)
tree63531d09078b0b88621b46667a4cd5f38c726adc
parent0ac7e18389b65a50424db923954fadccecc9cde1 (diff)
Resolve #492, init support for insert and remove page break
-rw-r--r--.travis.yml1
-rw-r--r--sheet.go109
-rw-r--r--sheet_test.go37
-rw-r--r--xmlWorksheet.go6
4 files changed, 150 insertions, 3 deletions
diff --git a/.travis.yml b/.travis.yml
index 1cb1d49..d94d5d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,7 @@ go:
- 1.11.x
- 1.12.x
- 1.13.x
+ - 1.14.x
os:
- linux
diff --git a/sheet.go b/sheet.go
index 48671c0..08b0e96 100644
--- a/sheet.go
+++ b/sheet.go
@@ -1437,6 +1437,115 @@ func (f *File) UngroupSheets() error {
return nil
}
+// InsertPageBreak create a page break to determine where the printed page
+// ends and where begins the next one by given worksheet name and axis, so the
+// content before the page break will be printed on one page and after the
+// page break on another.
+func (f *File) InsertPageBreak(sheet, cell string) (err error) {
+ var ws *xlsxWorksheet
+ var row, col int
+ var rowBrk, colBrk = -1, -1
+ if ws, err = f.workSheetReader(sheet); err != nil {
+ return
+ }
+ if col, row, err = CellNameToCoordinates(cell); err != nil {
+ return
+ }
+ col--
+ row--
+ if col == row && col == 0 {
+ return
+ }
+ if ws.RowBreaks == nil {
+ ws.RowBreaks = &xlsxBreaks{}
+ }
+ if ws.ColBreaks == nil {
+ ws.ColBreaks = &xlsxBreaks{}
+ }
+
+ for idx, brk := range ws.RowBreaks.Brk {
+ if brk.ID == row {
+ rowBrk = idx
+ }
+ }
+ for idx, brk := range ws.ColBreaks.Brk {
+ if brk.ID == col {
+ colBrk = idx
+ }
+ }
+
+ if row != 0 && rowBrk == -1 {
+ ws.RowBreaks.Brk = append(ws.RowBreaks.Brk, &xlsxBrk{
+ ID: row,
+ Max: 16383,
+ Man: true,
+ })
+ ws.RowBreaks.ManualBreakCount++
+ }
+ if col != 0 && colBrk == -1 {
+ ws.ColBreaks.Brk = append(ws.ColBreaks.Brk, &xlsxBrk{
+ ID: col,
+ Max: 1048575,
+ Man: true,
+ })
+ ws.ColBreaks.ManualBreakCount++
+ }
+ ws.RowBreaks.Count = len(ws.RowBreaks.Brk)
+ ws.ColBreaks.Count = len(ws.ColBreaks.Brk)
+ return
+}
+
+// RemovePageBreak remove a page break by given worksheet name and axis.
+func (f *File) RemovePageBreak(sheet, cell string) (err error) {
+ var ws *xlsxWorksheet
+ var row, col int
+ if ws, err = f.workSheetReader(sheet); err != nil {
+ return
+ }
+ if col, row, err = CellNameToCoordinates(cell); err != nil {
+ return
+ }
+ col--
+ row--
+ if col == row && col == 0 {
+ return
+ }
+ removeBrk := func(ID int, brks []*xlsxBrk) []*xlsxBrk {
+ for i, brk := range brks {
+ if brk.ID == ID {
+ brks = append(brks[:i], brks[i+1:]...)
+ }
+ }
+ return brks
+ }
+ if ws.RowBreaks == nil || ws.ColBreaks == nil {
+ return
+ }
+ rowBrks := len(ws.RowBreaks.Brk)
+ colBrks := len(ws.ColBreaks.Brk)
+ if rowBrks > 0 && rowBrks == colBrks {
+ ws.RowBreaks.Brk = removeBrk(row, ws.RowBreaks.Brk)
+ ws.ColBreaks.Brk = removeBrk(col, ws.ColBreaks.Brk)
+ ws.RowBreaks.Count = len(ws.RowBreaks.Brk)
+ ws.ColBreaks.Count = len(ws.ColBreaks.Brk)
+ ws.RowBreaks.ManualBreakCount--
+ ws.ColBreaks.ManualBreakCount--
+ return
+ }
+ if rowBrks > 0 && rowBrks > colBrks {
+ ws.RowBreaks.Brk = removeBrk(row, ws.RowBreaks.Brk)
+ ws.RowBreaks.Count = len(ws.RowBreaks.Brk)
+ ws.RowBreaks.ManualBreakCount--
+ return
+ }
+ if colBrks > 0 && colBrks > rowBrks {
+ ws.ColBreaks.Brk = removeBrk(col, ws.ColBreaks.Brk)
+ ws.ColBreaks.Count = len(ws.ColBreaks.Brk)
+ ws.ColBreaks.ManualBreakCount--
+ }
+ return
+}
+
// relsReader provides a function to get the pointer to the structure
// after deserialization of xl/worksheets/_rels/sheet%d.xml.rels.
func (f *File) relsReader(path string) *xlsxRelationships {
diff --git a/sheet_test.go b/sheet_test.go
index 69c8f22..38d86e6 100644
--- a/sheet_test.go
+++ b/sheet_test.go
@@ -264,6 +264,43 @@ func TestUngroupSheets(t *testing.T) {
assert.NoError(t, f.UngroupSheets())
}
+func TestInsertPageBreak(t *testing.T) {
+ f := excelize.NewFile()
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "A1"))
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "B2"))
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "C3"))
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "C3"))
+ assert.EqualError(t, f.InsertPageBreak("Sheet1", "A"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
+ assert.EqualError(t, f.InsertPageBreak("SheetN", "C3"), "sheet SheetN is not exist")
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertPageBreak.xlsx")))
+}
+
+func TestRemovePageBreak(t *testing.T) {
+ f := excelize.NewFile()
+ assert.NoError(t, f.RemovePageBreak("Sheet1", "A2"))
+
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "A2"))
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "B2"))
+ assert.NoError(t, f.RemovePageBreak("Sheet1", "A1"))
+ assert.NoError(t, f.RemovePageBreak("Sheet1", "B2"))
+
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "C3"))
+ assert.NoError(t, f.RemovePageBreak("Sheet1", "C3"))
+
+ assert.NoError(t, f.InsertPageBreak("Sheet1", "A3"))
+ assert.NoError(t, f.RemovePageBreak("Sheet1", "B3"))
+ assert.NoError(t, f.RemovePageBreak("Sheet1", "A3"))
+
+ f.NewSheet("Sheet2")
+ assert.NoError(t, f.InsertPageBreak("Sheet2", "B2"))
+ assert.NoError(t, f.InsertPageBreak("Sheet2", "C2"))
+ assert.NoError(t, f.RemovePageBreak("Sheet2", "B2"))
+
+ assert.EqualError(t, f.RemovePageBreak("Sheet1", "A"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
+ assert.EqualError(t, f.RemovePageBreak("SheetN", "C3"), "sheet SheetN is not exist")
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestRemovePageBreak.xlsx")))
+}
+
func TestGetSheetName(t *testing.T) {
f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx"))
assert.Equal(t, "Sheet1", f.GetSheetName(1))
diff --git a/xmlWorksheet.go b/xmlWorksheet.go
index dda1b78..aa33819 100644
--- a/xmlWorksheet.go
+++ b/xmlWorksheet.go
@@ -357,9 +357,9 @@ type xlsxBrk struct {
// xlsxBreaks directly maps a collection of the row or column breaks.
type xlsxBreaks struct {
- Brk *xlsxBrk `xml:"brk"`
- Count int `xml:"count,attr,omitempty"`
- ManualBreakCount int `xml:"manualBreakCount,attr,omitempty"`
+ Brk []*xlsxBrk `xml:"brk"`
+ Count int `xml:"count,attr,omitempty"`
+ ManualBreakCount int `xml:"manualBreakCount,attr,omitempty"`
}
// xlsxCustomSheetView directly maps the customSheetView element.