This made stream writer support set the insert page break (#1393)

This commit is contained in:
renxiaotu 2022-11-16 00:02:35 +08:00 committed by GitHub
parent 45d168c79d
commit aa80fa4179
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 30 deletions

View File

@ -1616,19 +1616,25 @@ func (f *File) UngroupSheets() error {
}
// InsertPageBreak create a page break to determine where the printed page
// ends and where begins the next one by given worksheet name and cell reference, so the
// content before the page break will be printed on one page and after the
// page break on another.
// ends and where begins the next one by given worksheet name and cell
// reference, 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) error {
var (
ws *xlsxWorksheet
row, col int
err error
)
rowBrk, colBrk := -1, -1
if ws, err = f.workSheetReader(sheet); err != nil {
ws, err := f.workSheetReader(sheet)
if err != nil {
return err
}
return ws.insertPageBreak(cell)
}
// insertPageBreak create a page break in the worksheet by specific cell
// reference.
func (ws *xlsxWorksheet) insertPageBreak(cell string) error {
var (
row, col int
err error
rowBrk, colBrk = -1, -1
)
if col, row, err = CellNameToCoordinates(cell); err != nil {
return err
}
@ -1638,10 +1644,10 @@ func (f *File) InsertPageBreak(sheet, cell string) error {
return err
}
if ws.RowBreaks == nil {
ws.RowBreaks = &xlsxBreaks{}
ws.RowBreaks = &xlsxRowBreaks{}
}
if ws.ColBreaks == nil {
ws.ColBreaks = &xlsxBreaks{}
ws.ColBreaks = &xlsxColBreaks{}
}
for idx, brk := range ws.RowBreaks.Brk {

View File

@ -25,7 +25,7 @@ import (
// StreamWriter defined the type of stream writer.
type StreamWriter struct {
File *File
file *File
Sheet string
SheetID int
sheetWritten bool
@ -107,7 +107,7 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
return nil, newNoExistSheetError(sheet)
}
sw := &StreamWriter{
File: f,
file: f,
Sheet: sheet,
SheetID: sheetID,
}
@ -169,7 +169,7 @@ func (sw *StreamWriter) AddTable(hCell, vCell, opts string) error {
}
// Correct table reference range, such correct C1:B3 to B1:C3.
ref, err := sw.File.coordinatesToRangeRef(coordinates)
ref, err := sw.file.coordinatesToRangeRef(coordinates)
if err != nil {
return err
}
@ -187,7 +187,7 @@ func (sw *StreamWriter) AddTable(hCell, vCell, opts string) error {
}
}
tableID := sw.File.countTables() + 1
tableID := sw.file.countTables() + 1
name := options.TableName
if name == "" {
@ -220,17 +220,17 @@ func (sw *StreamWriter) AddTable(hCell, vCell, opts string) error {
tableXML := strings.ReplaceAll(sheetRelationshipsTableXML, "..", "xl")
// Add first table for given sheet.
sheetPath := sw.File.sheetMap[trimSheetName(sw.Sheet)]
sheetPath := sw.file.sheetMap[trimSheetName(sw.Sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := sw.File.addRels(sheetRels, SourceRelationshipTable, sheetRelationshipsTableXML, "")
rID := sw.file.addRels(sheetRels, SourceRelationshipTable, sheetRelationshipsTableXML, "")
sw.tableParts = fmt.Sprintf(`<tableParts count="1"><tablePart r:id="rId%d"></tablePart></tableParts>`, rID)
if err = sw.File.addContentTypePart(tableID, "table"); err != nil {
if err = sw.file.addContentTypePart(tableID, "table"); err != nil {
return err
}
b, _ := xml.Marshal(table)
sw.File.saveFileList(tableXML, b)
sw.file.saveFileList(tableXML, b)
return err
}
@ -243,7 +243,7 @@ func (sw *StreamWriter) getRowValues(hRow, hCol, vCol int) (res []string, err er
return nil, err
}
dec := sw.File.xmlNewDecoder(r)
dec := sw.file.xmlNewDecoder(r)
for {
token, err := dec.Token()
if err == io.EOF {
@ -269,7 +269,7 @@ func (sw *StreamWriter) getRowValues(hRow, hCol, vCol int) (res []string, err er
if col < hCol || col > vCol {
continue
}
res[col-hCol], _ = c.getValueFrom(sw.File, nil, false)
res[col-hCol], _ = c.getValueFrom(sw.file, nil, false)
}
return res, nil
}
@ -438,6 +438,14 @@ func (sw *StreamWriter) SetColWidth(min, max int, width float64) 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 cell
// reference, so the content before the page break will be printed on one page
// and after the page break on another.
func (sw *StreamWriter) InsertPageBreak(cell string) error {
return sw.worksheet.insertPageBreak(cell)
}
// SetPanes provides a function to create and remove freeze panes and split
// panes by given worksheet name and panes options for the StreamWriter. Note
// that you must call the 'SetPanes' function before the 'SetRow' function.
@ -475,7 +483,7 @@ func setCellFormula(c *xlsxC, formula string) {
// setCellTime provides a function to set number of a cell with a time.
func (sw *StreamWriter) setCellTime(c *xlsxC, val time.Time) error {
var date1904, isNum bool
wb, err := sw.File.workbookReader()
wb, err := sw.file.workbookReader()
if err != nil {
return err
}
@ -483,7 +491,7 @@ func (sw *StreamWriter) setCellTime(c *xlsxC, val time.Time) error {
date1904 = wb.WorkbookPr.Date1904
}
if isNum, err = c.setCellTime(val, date1904); err == nil && isNum && c.S == 0 {
style, _ := sw.File.NewStyle(&Style{NumFmt: 22})
style, _ := sw.file.NewStyle(&Style{NumFmt: 22})
c.S = style
}
return nil
@ -643,10 +651,10 @@ func (sw *StreamWriter) Flush() error {
return err
}
sheetPath := sw.File.sheetMap[trimSheetName(sw.Sheet)]
sw.File.Sheet.Delete(sheetPath)
delete(sw.File.checked, sheetPath)
sw.File.Pkg.Delete(sheetPath)
sheetPath := sw.file.sheetMap[trimSheetName(sw.Sheet)]
sw.file.Sheet.Delete(sheetPath)
delete(sw.file.checked, sheetPath)
sw.file.Pkg.Delete(sheetPath)
return nil
}

View File

@ -234,6 +234,19 @@ func TestStreamMergeCells(t *testing.T) {
assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamMergeCells.xlsx")))
}
func TestStreamInsertPageBreak(t *testing.T) {
file := NewFile()
defer func() {
assert.NoError(t, file.Close())
}()
streamWriter, err := file.NewStreamWriter("Sheet1")
assert.NoError(t, err)
assert.NoError(t, streamWriter.InsertPageBreak("A1"))
assert.NoError(t, streamWriter.Flush())
// Save spreadsheet by the given path.
assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamInsertPageBreak.xlsx")))
}
func TestNewStreamWriter(t *testing.T) {
// Test error exceptions
file := NewFile()

View File

@ -44,8 +44,8 @@ type xlsxWorksheet struct {
PageMargins *xlsxPageMargins `xml:"pageMargins"`
PageSetUp *xlsxPageSetUp `xml:"pageSetup"`
HeaderFooter *xlsxHeaderFooter `xml:"headerFooter"`
RowBreaks *xlsxBreaks `xml:"rowBreaks"`
ColBreaks *xlsxBreaks `xml:"colBreaks"`
RowBreaks *xlsxRowBreaks `xml:"rowBreaks"`
ColBreaks *xlsxColBreaks `xml:"colBreaks"`
CustomProperties *xlsxInnerXML `xml:"customProperties"`
CellWatches *xlsxInnerXML `xml:"cellWatches"`
IgnoredErrors *xlsxInnerXML `xml:"ignoredErrors"`
@ -358,6 +358,18 @@ type xlsxBrk struct {
Pt bool `xml:"pt,attr,omitempty"`
}
// xlsxRowBreaks directly maps a collection of the row breaks.
type xlsxRowBreaks struct {
XMLName xml.Name `xml:"rowBreaks"`
xlsxBreaks
}
// xlsxRowBreaks directly maps a collection of the column breaks.
type xlsxColBreaks struct {
XMLName xml.Name `xml:"colBreaks"`
xlsxBreaks
}
// xlsxBreaks directly maps a collection of the row or column breaks.
type xlsxBreaks struct {
Brk []*xlsxBrk `xml:"brk"`