diff --git a/excelize.go b/excelize.go index cca6616..0c0f74a 100644 --- a/excelize.go +++ b/excelize.go @@ -36,6 +36,7 @@ type File struct { xmlAttr map[string][]xml.Attr checked map[string]bool sheetMap map[string]string + streams map[string]*StreamWriter CalcChain *xlsxCalcChain Comments map[string]*xlsxComments ContentTypes *xlsxTypes diff --git a/file.go b/file.go index 6a48c0c..4a2ab10 100644 --- a/file.go +++ b/file.go @@ -110,6 +110,26 @@ func (f *File) WriteToBuffer() (*bytes.Buffer, error) { f.sharedStringsWriter() f.styleSheetWriter() + for path, stream := range f.streams { + fi, err := zw.Create(path) + if err != nil { + zw.Close() + return buf, err + } + var from io.Reader + from, err = stream.rawData.Reader() + if err != nil { + stream.rawData.Close() + return buf, err + } + _, err = io.Copy(fi, from) + if err != nil { + zw.Close() + return buf, err + } + stream.rawData.Close() + } + for path, content := range f.XLSX { fi, err := zw.Create(path) if err != nil { diff --git a/go.mod b/go.mod index fb2c1e8..4b6e778 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/360EntSecGroup-Skylar/excelize/v2 -go 1.15 +go 1.11 require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 diff --git a/stream.go b/stream.go index 83b25f7..bbb1ec1 100644 --- a/stream.go +++ b/stream.go @@ -85,6 +85,13 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) { if err != nil { return nil, err } + + sheetXML := fmt.Sprintf("xl/worksheets/sheet%d.xml", sw.SheetID) + if f.streams == nil { + f.streams = make(map[string]*StreamWriter) + } + f.streams[sheetXML] = sw + sw.rawData.WriteString(XMLHeader + ``) @@ -387,13 +394,8 @@ func (sw *StreamWriter) Flush() error { sheetXML := fmt.Sprintf("xl/worksheets/sheet%d.xml", sw.SheetID) delete(sw.File.Sheet, sheetXML) delete(sw.File.checked, sheetXML) + delete(sw.File.XLSX, sheetXML) - defer sw.rawData.Close() - b, err := sw.rawData.Bytes() - if err != nil { - return err - } - sw.File.XLSX[sheetXML] = b return nil } @@ -444,36 +446,6 @@ func (bw *bufferedWriter) Reader() (io.Reader, error) { return io.NewSectionReader(bw.tmp, 0, fi.Size()), nil } -// Bytes returns the entire content of the bufferedWriter. If a temp file is -// used, Bytes will efficiently allocate a buffer to prevent re-allocations. -func (bw *bufferedWriter) Bytes() ([]byte, error) { - if bw.tmp == nil { - return bw.buf.Bytes(), nil - } - - if err := bw.Flush(); err != nil { - return nil, err - } - - var buf bytes.Buffer - if fi, err := bw.tmp.Stat(); err == nil { - if size := fi.Size() + bytes.MinRead; size > bytes.MinRead { - if int64(int(size)) == size { - buf.Grow(int(size)) - } else { - return nil, bytes.ErrTooLarge - } - } - } - - if _, err := bw.tmp.Seek(0, 0); err != nil { - return nil, err - } - - _, err := buf.ReadFrom(bw.tmp) - return buf.Bytes(), err -} - // Sync will write the in-memory buffer to a temp file, if the in-memory // buffer has grown large enough. Any error will be returned. func (bw *bufferedWriter) Sync() (err error) {