diff options
author | xuri <xuri.me@gmail.com> | 2021-04-28 02:04:36 +0000 |
---|---|---|
committer | xuri <xuri.me@gmail.com> | 2021-04-28 02:04:36 +0000 |
commit | af5e87dbcf5a89201072f5ca07d532258ece278f (patch) | |
tree | 51edb1a6082e4c291e467cc3fb35845f9f993763 | |
parent | a13ef5545ec79108477910346ae4cab82ab8bbda (diff) |
#826, support merge cell in streaming mode
-rw-r--r-- | stream.go | 34 | ||||
-rw-r--r-- | stream_test.go | 12 |
2 files changed, 39 insertions, 7 deletions
@@ -26,12 +26,14 @@ import ( // StreamWriter defined the type of stream writer. type StreamWriter struct { - File *File - Sheet string - SheetID int - worksheet *xlsxWorksheet - rawData bufferedWriter - tableParts string + File *File + Sheet string + SheetID int + worksheet *xlsxWorksheet + rawData bufferedWriter + mergeCellsCount int + mergeCells string + tableParts string } // NewStreamWriter return stream writer struct by given worksheet name for @@ -322,6 +324,19 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}) error { return sw.rawData.Sync() } +// MergeCell provides a function to merge cells by a given coordinate area for +// the StreamWriter. Don't create a merged cell that overlaps with another +// existing merged cell. +func (sw *StreamWriter) MergeCell(hcell, vcell string) error { + _, err := areaRangeToCoordinates(hcell, vcell) + if err != nil { + return err + } + sw.mergeCellsCount++ + sw.mergeCells += fmt.Sprintf(`<mergeCell ref="%s:%s"/>`, hcell, vcell) + return nil +} + // setCellFormula provides a function to set formula of a cell. func setCellFormula(c *xlsxC, formula string) { if formula != "" { @@ -413,7 +428,12 @@ func writeCell(buf *bufferedWriter, c xlsxC) { // Flush ending the streaming writing process. func (sw *StreamWriter) Flush() error { _, _ = sw.rawData.WriteString(`</sheetData>`) - bulkAppendFields(&sw.rawData, sw.worksheet, 8, 38) + bulkAppendFields(&sw.rawData, sw.worksheet, 8, 15) + if sw.mergeCellsCount > 0 { + sw.mergeCells = fmt.Sprintf(`<mergeCells count="%d">%s</mergeCells>`, sw.mergeCellsCount, sw.mergeCells) + } + _, _ = sw.rawData.WriteString(sw.mergeCells) + bulkAppendFields(&sw.rawData, sw.worksheet, 17, 38) _, _ = sw.rawData.WriteString(sw.tableParts) bulkAppendFields(&sw.rawData, sw.worksheet, 40, 40) _, _ = sw.rawData.WriteString(`</worksheet>`) diff --git a/stream_test.go b/stream_test.go index 322eea9..26732d8 100644 --- a/stream_test.go +++ b/stream_test.go @@ -134,6 +134,18 @@ func TestStreamTable(t *testing.T) { assert.EqualError(t, streamWriter.AddTable("A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`) } +func TestStreamMergeCells(t *testing.T) { + file := NewFile() + streamWriter, err := file.NewStreamWriter("Sheet1") + assert.NoError(t, err) + assert.NoError(t, streamWriter.MergeCell("A1", "D1")) + // Test merge cells with illegal cell coordinates. + assert.EqualError(t, streamWriter.MergeCell("A", "D1"), `cannot convert cell "A" to coordinates: invalid cell name "A"`) + assert.NoError(t, streamWriter.Flush()) + // Save spreadsheet by the given path. + assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamMergeCells.xlsx"))) +} + func TestNewStreamWriter(t *testing.T) { // Test error exceptions file := NewFile() |