Resolve #492, init support for insert and remove page break

This commit is contained in:
xuri 2020-03-01 00:34:41 +08:00
parent 0ac7e18389
commit 1d87da57ec
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
4 changed files with 150 additions and 3 deletions

View File

@ -8,6 +8,7 @@ go:
- 1.11.x
- 1.12.x
- 1.13.x
- 1.14.x
os:
- linux

109
sheet.go
View File

@ -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 {

View File

@ -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))

View File

@ -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.