Fix #576, serialize by fields order on stream flush
This commit is contained in:
parent
e51aff2d95
commit
023dba7265
|
@ -40,7 +40,7 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
|
|||
|
||||
## 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
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[version]: https://www.contributor-covenant.org/version/2/0/code_of_conduct
|
||||
|
|
29
stream.go
29
stream.go
|
@ -27,6 +27,7 @@ type StreamWriter struct {
|
|||
File *File
|
||||
Sheet string
|
||||
SheetID int
|
||||
worksheet *xlsxWorksheet
|
||||
rawData bufferedWriter
|
||||
tableParts string
|
||||
}
|
||||
|
@ -77,15 +78,15 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
|
|||
Sheet: sheet,
|
||||
SheetID: sheetID,
|
||||
}
|
||||
|
||||
ws, err := f.workSheetReader(sheet)
|
||||
var err error
|
||||
sw.worksheet, err = f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sw.rawData.WriteString(XMLHeader + `<worksheet` + templateNamespaceIDMap)
|
||||
bulkAppendOtherFields(&sw.rawData, ws, "XMLName", "SheetData", "TableParts")
|
||||
bulkAppendFields(&sw.rawData, sw.worksheet, 1, 5)
|
||||
sw.rawData.WriteString(`<sheetData>`)
|
||||
return sw, nil
|
||||
return sw, err
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (sw *StreamWriter) Flush() error {
|
||||
sw.rawData.WriteString(`</sheetData>`)
|
||||
bulkAppendFields(&sw.rawData, sw.worksheet, 7, 37)
|
||||
sw.rawData.WriteString(sw.tableParts)
|
||||
bulkAppendFields(&sw.rawData, sw.worksheet, 39, 39)
|
||||
sw.rawData.WriteString(`</worksheet>`)
|
||||
if err := sw.rawData.Flush(); err != nil {
|
||||
return err
|
||||
|
@ -392,23 +395,15 @@ func (sw *StreamWriter) Flush() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// bulkAppendOtherFields bulk-appends fields in a worksheet, skipping the
|
||||
// specified field names.
|
||||
func bulkAppendOtherFields(w io.Writer, ws *xlsxWorksheet, skip ...string) {
|
||||
skipMap := make(map[string]struct{})
|
||||
for _, name := range skip {
|
||||
skipMap[name] = struct{}{}
|
||||
}
|
||||
|
||||
// bulkAppendFields bulk-appends fields in a worksheet by specified field
|
||||
// names order range.
|
||||
func bulkAppendFields(w io.Writer, ws *xlsxWorksheet, from, to int) {
|
||||
s := reflect.ValueOf(ws).Elem()
|
||||
typeOfT := s.Type()
|
||||
enc := xml.NewEncoder(w)
|
||||
for i := 0; i < s.NumField(); i++ {
|
||||
f := s.Field(i)
|
||||
if _, ok := skipMap[typeOfT.Field(i).Name]; ok {
|
||||
continue
|
||||
if from <= i && i <= to {
|
||||
enc.Encode(s.Field(i).Interface())
|
||||
}
|
||||
enc.Encode(f.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,13 @@ func TestStreamWriter(t *testing.T) {
|
|||
_, err = streamWriter.rawData.Reader()
|
||||
assert.NoError(t, err)
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue