diff options
| author | xuri <xuri.me@gmail.com> | 2021-09-18 23:20:24 +0800 | 
|---|---|---|
| committer | xuri <xuri.me@gmail.com> | 2021-09-19 11:06:54 +0800 | 
| commit | 790c363cceaaa09e91ad579e2d25cb13c1582bba (patch) | |
| tree | b5747f30edeac96a7fdadec574f1a5b1d332ca18 /rows.go | |
| parent | 2add938798cdd1456616869298319528b0c76913 (diff) | |
This closes #833, closes #845, and closes #1022, breaking changes
- Close spreadsheet and row's iterator required
- New options `WorksheetUnzipMemLimit` have been added
- Improve streaming reading performance, memory usage decrease about 93.7%
Diffstat (limited to 'rows.go')
| -rw-r--r-- | rows.go | 43 | 
1 files changed, 38 insertions, 5 deletions
| @@ -18,6 +18,7 @@ import (  	"io"  	"log"  	"math" +	"os"  	"strconv"  	"github.com/mohae/deepcopy" @@ -60,7 +61,7 @@ func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error) {  			max = cur  		}  	} -	return results[:max], nil +	return results[:max], rows.Close()  }  // Rows defines an iterator to a sheet. @@ -70,6 +71,7 @@ type Rows struct {  	rawCellValue               bool  	sheet                      string  	f                          *File +	tempFile                   *os.File  	decoder                    *xml.Decoder  } @@ -84,6 +86,15 @@ func (rows *Rows) Error() error {  	return rows.err  } +// Close closes the open worksheet XML file in the system temporary +// directory. +func (rows *Rows) Close() error { +	if rows.tempFile != nil { +		return rows.tempFile.Close() +	} +	return nil +} +  // Columns return the current row's column values.  func (rows *Rows) Columns(opts ...Options) ([]string, error) {  	var rowIterator rowXMLIterator @@ -196,6 +207,9 @@ func rowXMLHandler(rowIterator *rowXMLIterator, xmlElement *xml.StartElement, ra  //        }  //        fmt.Println()  //    } +//    if err = rows.Close(); err != nil { +//        fmt.Println(err) +//    }  //  func (f *File) Rows(sheet string) (*Rows, error) {  	name, ok := f.sheetMap[trimSheetName(sheet)] @@ -215,8 +229,13 @@ func (f *File) Rows(sheet string) (*Rows, error) {  		inElement string  		row       int  		rows      Rows +		needClose bool +		decoder   *xml.Decoder +		tempFile  *os.File  	) -	decoder := f.xmlNewDecoder(bytes.NewReader(f.readXML(name))) +	if needClose, decoder, tempFile, err = f.sheetDecoder(name); needClose && err == nil { +		defer tempFile.Close() +	}  	for {  		token, _ := decoder.Token()  		if token == nil { @@ -241,15 +260,29 @@ func (f *File) Rows(sheet string) (*Rows, error) {  			if xmlElement.Name.Local == "sheetData" {  				rows.f = f  				rows.sheet = name -				rows.decoder = f.xmlNewDecoder(bytes.NewReader(f.readXML(name))) -				return &rows, nil +				_, rows.decoder, rows.tempFile, err = f.sheetDecoder(name) +				return &rows, err  			} -		default:  		}  	}  	return &rows, nil  } +// sheetDecoder creates XML decoder by given path in the zip from memory data +// or system temporary file. +func (f *File) sheetDecoder(name string) (bool, *xml.Decoder, *os.File, error) { +	var ( +		content  []byte +		err      error +		tempFile *os.File +	) +	if content = f.readXML(name); len(content) > 0 { +		return false, f.xmlNewDecoder(bytes.NewReader(content)), tempFile, err +	} +	tempFile, err = f.readTemp(name) +	return true, f.xmlNewDecoder(tempFile), tempFile, err +} +  // SetRowHeight provides a function to set the height of a single row. For  // example, set the height of the first row in Sheet1:  // | 
