Browse Source

Fix #576, serialize by fields order on stream flush

xuri 5 years ago
parent
commit
023dba7265
3 changed files with 22 additions and 20 deletions
  1. 3 3
      CODE_OF_CONDUCT.md
  2. 12 17
      stream.go
  3. 7 0
      stream_test.go

+ 3 - 3
CODE_OF_CONDUCT.md

@@ -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

+ 12 - 17
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())
 	}
 }
 

+ 7 - 0
stream_test.go

@@ -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) {