summaryrefslogtreecommitdiff
path: root/cell.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-12-27 23:34:14 +0800
committerxuri <xuri.me@gmail.com>2021-12-27 23:49:28 +0800
commit89b85934f60ba0012f3de6da03eb12959e4b4b72 (patch)
tree3d913c2bdabf06b79b7c2f223cfe26b64aacd8cc /cell.go
parent6b1e592cbc7b1412da5f6d0badeaf1083117c762 (diff)
This closes #1096, memory usage optimization and another 4 changes
- Unzip shared string table to system temporary file when large inner XML, reduce memory usage about 70% - Remove unnecessary exported variable `XMLHeader`, we can using `encoding/xml` package's `xml.Header` instead of it - Using constant instead of inline text for default XML path - Rename exported option field `WorksheetUnzipMemLimit` to `UnzipXMLSizeLimit` - Unit test and documentation updated
Diffstat (limited to 'cell.go')
-rw-r--r--cell.go90
1 files changed, 60 insertions, 30 deletions
diff --git a/cell.go b/cell.go
index 5c34bb9..daff3d9 100644
--- a/cell.go
+++ b/cell.go
@@ -14,6 +14,7 @@ package excelize
import (
"encoding/xml"
"fmt"
+ "os"
"reflect"
"strconv"
"strings"
@@ -348,28 +349,49 @@ func (f *File) SetCellStr(sheet, axis, value string) error {
ws.Lock()
defer ws.Unlock()
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
- cellData.T, cellData.V = f.setCellString(value)
+ cellData.T, cellData.V, err = f.setCellString(value)
return err
}
// setCellString provides a function to set string type to shared string
// table.
-func (f *File) setCellString(value string) (t string, v string) {
+func (f *File) setCellString(value string) (t, v string, err error) {
if len(value) > TotalCellChars {
value = value[:TotalCellChars]
}
t = "s"
- v = strconv.Itoa(f.setSharedString(value))
+ var si int
+ if si, err = f.setSharedString(value); err != nil {
+ return
+ }
+ v = strconv.Itoa(si)
+ return
+}
+
+// sharedStringsLoader load shared string table from system temporary file to
+// memory, and reset shared string table for reader.
+func (f *File) sharedStringsLoader() (err error) {
+ f.Lock()
+ defer f.Unlock()
+ if path, ok := f.tempFiles.Load(dafaultXMLPathSharedStrings); ok {
+ f.Pkg.Store(dafaultXMLPathSharedStrings, f.readBytes(dafaultXMLPathSharedStrings))
+ f.tempFiles.Delete(dafaultXMLPathSharedStrings)
+ err = os.Remove(path.(string))
+ f.SharedStrings, f.sharedStringItemMap = nil, nil
+ }
return
}
// setSharedString provides a function to add string to the share string table.
-func (f *File) setSharedString(val string) int {
+func (f *File) setSharedString(val string) (int, error) {
+ if err := f.sharedStringsLoader(); err != nil {
+ return 0, err
+ }
sst := f.sharedStringsReader()
f.Lock()
defer f.Unlock()
if i, ok := f.sharedStringsMap[val]; ok {
- return i
+ return i, nil
}
sst.Count++
sst.UniqueCount++
@@ -377,7 +399,7 @@ func (f *File) setSharedString(val string) int {
_, val, t.Space = setCellStr(val)
sst.SI = append(sst.SI, xlsxSI{T: &t})
f.sharedStringsMap[val] = sst.UniqueCount - 1
- return sst.UniqueCount - 1
+ return sst.UniqueCount - 1, nil
}
// setCellStr provides a function to set string type to cell.
@@ -762,6 +784,34 @@ func (f *File) GetCellRichText(sheet, cell string) (runs []RichTextRun, err erro
return
}
+// newRpr create run properties for the rich text by given font format.
+func newRpr(fnt *Font) *xlsxRPr {
+ rpr := xlsxRPr{}
+ trueVal := ""
+ if fnt.Bold {
+ rpr.B = &trueVal
+ }
+ if fnt.Italic {
+ rpr.I = &trueVal
+ }
+ if fnt.Strike {
+ rpr.Strike = &trueVal
+ }
+ if fnt.Underline != "" {
+ rpr.U = &attrValString{Val: &fnt.Underline}
+ }
+ if fnt.Family != "" {
+ rpr.RFont = &attrValString{Val: &fnt.Family}
+ }
+ if fnt.Size > 0.0 {
+ rpr.Sz = &attrValFloat{Val: &fnt.Size}
+ }
+ if fnt.Color != "" {
+ rpr.Color = &xlsxColor{RGB: getPaletteColor(fnt.Color)}
+ }
+ return &rpr
+}
+
// SetCellRichText provides a function to set cell with rich text by given
// worksheet. For example, set rich text on the A1 cell of the worksheet named
// Sheet1:
@@ -875,6 +925,9 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
if err != nil {
return err
}
+ if err := f.sharedStringsLoader(); err != nil {
+ return err
+ }
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
si := xlsxSI{}
sst := f.sharedStringsReader()
@@ -889,30 +942,7 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
_, run.T.Val, run.T.Space = setCellStr(textRun.Text)
fnt := textRun.Font
if fnt != nil {
- rpr := xlsxRPr{}
- trueVal := ""
- if fnt.Bold {
- rpr.B = &trueVal
- }
- if fnt.Italic {
- rpr.I = &trueVal
- }
- if fnt.Strike {
- rpr.Strike = &trueVal
- }
- if fnt.Underline != "" {
- rpr.U = &attrValString{Val: &fnt.Underline}
- }
- if fnt.Family != "" {
- rpr.RFont = &attrValString{Val: &fnt.Family}
- }
- if fnt.Size > 0.0 {
- rpr.Sz = &attrValFloat{Val: &fnt.Size}
- }
- if fnt.Color != "" {
- rpr.Color = &xlsxColor{RGB: getPaletteColor(fnt.Color)}
- }
- run.RPr = &rpr
+ run.RPr = newRpr(fnt)
}
textRuns = append(textRuns, run)
}