forked from p30928647/excelize
- New exported error `ErrStreamSetPanes` has been added
This commit is contained in:
parent
2f5704b114
commit
c02346bafc
|
@ -91,6 +91,9 @@ var (
|
||||||
// ErrStreamSetColWidth defined the error message on set column width in
|
// ErrStreamSetColWidth defined the error message on set column width in
|
||||||
// stream writing mode.
|
// stream writing mode.
|
||||||
ErrStreamSetColWidth = errors.New("must call the SetColWidth function before the SetRow function")
|
ErrStreamSetColWidth = errors.New("must call the SetColWidth function before the SetRow function")
|
||||||
|
// ErrStreamSetPanes defined the error message on set panes in stream
|
||||||
|
// writing mode.
|
||||||
|
ErrStreamSetPanes = errors.New("must call the SetPanes function before the SetRow function")
|
||||||
// ErrColumnNumber defined the error message on receive an invalid column
|
// ErrColumnNumber defined the error message on receive an invalid column
|
||||||
// number.
|
// number.
|
||||||
ErrColumnNumber = fmt.Errorf(`the column number must be greater than or equal to %d and less than or equal to %d`, MinColumns, MaxColumns)
|
ErrColumnNumber = fmt.Errorf(`the column number must be greater than or equal to %d and less than or equal to %d`, MinColumns, MaxColumns)
|
||||||
|
|
68
sheet.go
68
sheet.go
|
@ -683,8 +683,44 @@ func parsePanesOptions(opts string) (*panesOptions, error) {
|
||||||
return &format, err
|
return &format, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setPanes set create freeze panes and split panes by given options.
|
||||||
|
func (ws *xlsxWorksheet) setPanes(panes string) error {
|
||||||
|
opts, err := parsePanesOptions(panes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p := &xlsxPane{
|
||||||
|
ActivePane: opts.ActivePane,
|
||||||
|
TopLeftCell: opts.TopLeftCell,
|
||||||
|
XSplit: float64(opts.XSplit),
|
||||||
|
YSplit: float64(opts.YSplit),
|
||||||
|
}
|
||||||
|
if opts.Freeze {
|
||||||
|
p.State = "frozen"
|
||||||
|
}
|
||||||
|
if ws.SheetViews == nil {
|
||||||
|
ws.SheetViews = &xlsxSheetViews{SheetView: []xlsxSheetView{{}}}
|
||||||
|
}
|
||||||
|
ws.SheetViews.SheetView[len(ws.SheetViews.SheetView)-1].Pane = p
|
||||||
|
if !(opts.Freeze) && !(opts.Split) {
|
||||||
|
if len(ws.SheetViews.SheetView) > 0 {
|
||||||
|
ws.SheetViews.SheetView[len(ws.SheetViews.SheetView)-1].Pane = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var s []*xlsxSelection
|
||||||
|
for _, p := range opts.Panes {
|
||||||
|
s = append(s, &xlsxSelection{
|
||||||
|
ActiveCell: p.ActiveCell,
|
||||||
|
Pane: p.Pane,
|
||||||
|
SQRef: p.SQRef,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ws.SheetViews.SheetView[len(ws.SheetViews.SheetView)-1].Selection = s
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// SetPanes provides a function to create and remove freeze panes and split panes
|
// SetPanes provides a function to create and remove freeze panes and split panes
|
||||||
// by given worksheet name and panes format set.
|
// by given worksheet name and panes options.
|
||||||
//
|
//
|
||||||
// activePane defines the pane that is active. The possible values for this
|
// activePane defines the pane that is active. The possible values for this
|
||||||
// attribute are defined in the following table:
|
// attribute are defined in the following table:
|
||||||
|
@ -768,39 +804,11 @@ func parsePanesOptions(opts string) (*panesOptions, error) {
|
||||||
//
|
//
|
||||||
// f.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
|
// f.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
|
||||||
func (f *File) SetPanes(sheet, panes string) error {
|
func (f *File) SetPanes(sheet, panes string) error {
|
||||||
fs, _ := parsePanesOptions(panes)
|
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p := &xlsxPane{
|
return ws.setPanes(panes)
|
||||||
ActivePane: fs.ActivePane,
|
|
||||||
TopLeftCell: fs.TopLeftCell,
|
|
||||||
XSplit: float64(fs.XSplit),
|
|
||||||
YSplit: float64(fs.YSplit),
|
|
||||||
}
|
|
||||||
if fs.Freeze {
|
|
||||||
p.State = "frozen"
|
|
||||||
}
|
|
||||||
if ws.SheetViews == nil {
|
|
||||||
ws.SheetViews = &xlsxSheetViews{SheetView: []xlsxSheetView{{}}}
|
|
||||||
}
|
|
||||||
ws.SheetViews.SheetView[len(ws.SheetViews.SheetView)-1].Pane = p
|
|
||||||
if !(fs.Freeze) && !(fs.Split) {
|
|
||||||
if len(ws.SheetViews.SheetView) > 0 {
|
|
||||||
ws.SheetViews.SheetView[len(ws.SheetViews.SheetView)-1].Pane = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var s []*xlsxSelection
|
|
||||||
for _, p := range fs.Panes {
|
|
||||||
s = append(s, &xlsxSelection{
|
|
||||||
ActiveCell: p.ActiveCell,
|
|
||||||
Pane: p.Pane,
|
|
||||||
SQRef: p.SQRef,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ws.SheetViews.SheetView[len(ws.SheetViews.SheetView)-1].Selection = s
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSheetVisible provides a function to get worksheet visible by given worksheet
|
// GetSheetVisible provides a function to get worksheet visible by given worksheet
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestSetPane(t *testing.T) {
|
||||||
assert.NoError(t, f.SetPanes("Panes 3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`))
|
assert.NoError(t, f.SetPanes("Panes 3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`))
|
||||||
f.NewSheet("Panes 4")
|
f.NewSheet("Panes 4")
|
||||||
assert.NoError(t, f.SetPanes("Panes 4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`))
|
assert.NoError(t, f.SetPanes("Panes 4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`))
|
||||||
assert.NoError(t, f.SetPanes("Panes 4", ""))
|
assert.EqualError(t, f.SetPanes("Panes 4", ""), "unexpected end of JSON input")
|
||||||
assert.EqualError(t, f.SetPanes("SheetN", ""), "sheet SheetN does not exist")
|
assert.EqualError(t, f.SetPanes("SheetN", ""), "sheet SheetN does not exist")
|
||||||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
|
||||||
// Test add pane on empty sheet views worksheet
|
// Test add pane on empty sheet views worksheet
|
||||||
|
|
35
stream.go
35
stream.go
|
@ -119,7 +119,7 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
|
||||||
f.streams[sheetXMLPath] = sw
|
f.streams[sheetXMLPath] = sw
|
||||||
|
|
||||||
_, _ = sw.rawData.WriteString(xml.Header + `<worksheet` + templateNamespaceIDMap)
|
_, _ = sw.rawData.WriteString(xml.Header + `<worksheet` + templateNamespaceIDMap)
|
||||||
bulkAppendFields(&sw.rawData, sw.worksheet, 2, 5)
|
bulkAppendFields(&sw.rawData, sw.worksheet, 2, 3)
|
||||||
return sw, err
|
return sw, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,13 +351,7 @@ func (sw *StreamWriter) SetRow(cell string, values []interface{}, opts ...RowOpt
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !sw.sheetWritten {
|
sw.writeSheetData()
|
||||||
if len(sw.cols) > 0 {
|
|
||||||
_, _ = sw.rawData.WriteString("<cols>" + sw.cols + "</cols>")
|
|
||||||
}
|
|
||||||
_, _ = sw.rawData.WriteString(`<sheetData>`)
|
|
||||||
sw.sheetWritten = true
|
|
||||||
}
|
|
||||||
options := parseRowOpts(opts...)
|
options := parseRowOpts(opts...)
|
||||||
attrs, err := options.marshalAttrs()
|
attrs, err := options.marshalAttrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -415,6 +409,16 @@ func (sw *StreamWriter) SetColWidth(min, max int, width float64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func (sw *StreamWriter) SetPanes(panes string) error {
|
||||||
|
if sw.sheetWritten {
|
||||||
|
return ErrStreamSetPanes
|
||||||
|
}
|
||||||
|
return sw.worksheet.setPanes(panes)
|
||||||
|
}
|
||||||
|
|
||||||
// MergeCell provides a function to merge cells by a given range reference for
|
// MergeCell provides a function to merge cells by a given range reference for
|
||||||
// the StreamWriter. Don't create a merged cell that overlaps with another
|
// the StreamWriter. Don't create a merged cell that overlaps with another
|
||||||
// existing merged cell.
|
// existing merged cell.
|
||||||
|
@ -507,6 +511,7 @@ func setCellIntFunc(c *xlsxC, val interface{}) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeCell constructs a cell XML and writes it to the buffer.
|
||||||
func writeCell(buf *bufferedWriter, c xlsxC) {
|
func writeCell(buf *bufferedWriter, c xlsxC) {
|
||||||
_, _ = buf.WriteString(`<c`)
|
_, _ = buf.WriteString(`<c`)
|
||||||
if c.XMLSpace.Value != "" {
|
if c.XMLSpace.Value != "" {
|
||||||
|
@ -539,12 +544,22 @@ func writeCell(buf *bufferedWriter, c xlsxC) {
|
||||||
_, _ = buf.WriteString(`</c>`)
|
_, _ = buf.WriteString(`</c>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush ending the streaming writing process.
|
// writeSheetData prepares the element preceding sheetData and writes the
|
||||||
func (sw *StreamWriter) Flush() error {
|
// sheetData XML start element to the buffer.
|
||||||
|
func (sw *StreamWriter) writeSheetData() {
|
||||||
if !sw.sheetWritten {
|
if !sw.sheetWritten {
|
||||||
|
bulkAppendFields(&sw.rawData, sw.worksheet, 4, 5)
|
||||||
|
if len(sw.cols) > 0 {
|
||||||
|
_, _ = sw.rawData.WriteString("<cols>" + sw.cols + "</cols>")
|
||||||
|
}
|
||||||
_, _ = sw.rawData.WriteString(`<sheetData>`)
|
_, _ = sw.rawData.WriteString(`<sheetData>`)
|
||||||
sw.sheetWritten = true
|
sw.sheetWritten = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush ending the streaming writing process.
|
||||||
|
func (sw *StreamWriter) Flush() error {
|
||||||
|
sw.writeSheetData()
|
||||||
_, _ = sw.rawData.WriteString(`</sheetData>`)
|
_, _ = sw.rawData.WriteString(`</sheetData>`)
|
||||||
bulkAppendFields(&sw.rawData, sw.worksheet, 8, 15)
|
bulkAppendFields(&sw.rawData, sw.worksheet, 8, 15)
|
||||||
mergeCells := strings.Builder{}
|
mergeCells := strings.Builder{}
|
||||||
|
|
|
@ -146,7 +146,17 @@ func TestStreamSetColWidth(t *testing.T) {
|
||||||
assert.ErrorIs(t, streamWriter.SetColWidth(MaxColumns+1, 3, 20), ErrColumnNumber)
|
assert.ErrorIs(t, streamWriter.SetColWidth(MaxColumns+1, 3, 20), ErrColumnNumber)
|
||||||
assert.EqualError(t, streamWriter.SetColWidth(1, 3, MaxColumnWidth+1), ErrColumnWidth.Error())
|
assert.EqualError(t, streamWriter.SetColWidth(1, 3, MaxColumnWidth+1), ErrColumnWidth.Error())
|
||||||
assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
|
assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
|
||||||
assert.EqualError(t, streamWriter.SetColWidth(2, 3, 20), ErrStreamSetColWidth.Error())
|
assert.ErrorIs(t, streamWriter.SetColWidth(2, 3, 20), ErrStreamSetColWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStreamSetPanes(t *testing.T) {
|
||||||
|
file, paneOpts := NewFile(), `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`
|
||||||
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, streamWriter.SetPanes(paneOpts))
|
||||||
|
assert.EqualError(t, streamWriter.SetPanes(""), "unexpected end of JSON input")
|
||||||
|
assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
|
||||||
|
assert.ErrorIs(t, streamWriter.SetPanes(paneOpts), ErrStreamSetPanes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamTable(t *testing.T) {
|
func TestStreamTable(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue