Fix #576, serialize by fields order on stream flush

formula
xuri 5 years ago
parent e51aff2d95
commit 023dba7265
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7

@ -40,7 +40,7 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct][version]
[homepage]: http://contributor-covenant.org [homepage]: https://www.contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/ [version]: https://www.contributor-covenant.org/version/2/0/code_of_conduct

@ -27,6 +27,7 @@ type StreamWriter struct {
File *File File *File
Sheet string Sheet string
SheetID int SheetID int
worksheet *xlsxWorksheet
rawData bufferedWriter rawData bufferedWriter
tableParts string tableParts string
} }
@ -77,15 +78,15 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
Sheet: sheet, Sheet: sheet,
SheetID: sheetID, SheetID: sheetID,
} }
var err error
ws, err := f.workSheetReader(sheet) sw.worksheet, err = f.workSheetReader(sheet)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sw.rawData.WriteString(XMLHeader + `<worksheet` + templateNamespaceIDMap) sw.rawData.WriteString(XMLHeader + `<worksheet` + templateNamespaceIDMap)
bulkAppendOtherFields(&sw.rawData, ws, "XMLName", "SheetData", "TableParts") bulkAppendFields(&sw.rawData, sw.worksheet, 1, 5)
sw.rawData.WriteString(`<sheetData>`) sw.rawData.WriteString(`<sheetData>`)
return sw, nil return sw, err
} }
// AddTable creates an Excel table for the StreamWriter using the given // AddTable creates an Excel table for the StreamWriter using the given
@ -373,7 +374,9 @@ func writeCell(buf *bufferedWriter, c xlsxC) {
// Flush ending the streaming writing process. // Flush ending the streaming writing process.
func (sw *StreamWriter) Flush() error { func (sw *StreamWriter) Flush() error {
sw.rawData.WriteString(`</sheetData>`) sw.rawData.WriteString(`</sheetData>`)
bulkAppendFields(&sw.rawData, sw.worksheet, 7, 37)
sw.rawData.WriteString(sw.tableParts) sw.rawData.WriteString(sw.tableParts)
bulkAppendFields(&sw.rawData, sw.worksheet, 39, 39)
sw.rawData.WriteString(`</worksheet>`) sw.rawData.WriteString(`</worksheet>`)
if err := sw.rawData.Flush(); err != nil { if err := sw.rawData.Flush(); err != nil {
return err return err
@ -392,23 +395,15 @@ func (sw *StreamWriter) Flush() error {
return nil return nil
} }
// bulkAppendOtherFields bulk-appends fields in a worksheet, skipping the // bulkAppendFields bulk-appends fields in a worksheet by specified field
// specified field names. // names order range.
func bulkAppendOtherFields(w io.Writer, ws *xlsxWorksheet, skip ...string) { func bulkAppendFields(w io.Writer, ws *xlsxWorksheet, from, to int) {
skipMap := make(map[string]struct{})
for _, name := range skip {
skipMap[name] = struct{}{}
}
s := reflect.ValueOf(ws).Elem() s := reflect.ValueOf(ws).Elem()
typeOfT := s.Type()
enc := xml.NewEncoder(w) enc := xml.NewEncoder(w)
for i := 0; i < s.NumField(); i++ { for i := 0; i < s.NumField(); i++ {
f := s.Field(i) if from <= i && i <= to {
if _, ok := skipMap[typeOfT.Field(i).Name]; ok { enc.Encode(s.Field(i).Interface())
continue
} }
enc.Encode(f.Interface())
} }
} }

@ -92,6 +92,13 @@ func TestStreamWriter(t *testing.T) {
_, err = streamWriter.rawData.Reader() _, err = streamWriter.rawData.Reader()
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, os.Remove(streamWriter.rawData.tmp.Name())) assert.NoError(t, os.Remove(streamWriter.rawData.tmp.Name()))
// Test unsupport charset
file = NewFile()
delete(file.Sheet, "xl/worksheets/sheet1.xml")
file.XLSX["xl/worksheets/sheet1.xml"] = MacintoshCyrillicCharset
streamWriter, err = file.NewStreamWriter("Sheet1")
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
} }
func TestStreamTable(t *testing.T) { func TestStreamTable(t *testing.T) {

Loading…
Cancel
Save