summaryrefslogtreecommitdiff
path: root/rows.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-09-18 23:20:24 +0800
committerxuri <xuri.me@gmail.com>2021-09-19 11:06:54 +0800
commit790c363cceaaa09e91ad579e2d25cb13c1582bba (patch)
treeb5747f30edeac96a7fdadec574f1a5b1d332ca18 /rows.go
parent2add938798cdd1456616869298319528b0c76913 (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.go43
1 files changed, 38 insertions, 5 deletions
diff --git a/rows.go b/rows.go
index 057cbc8..5c7b22d 100644
--- a/rows.go
+++ b/rows.go
@@ -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:
//