forked from p30928647/excelize
This closes #1379, cleanup stream writer temporary files by the `Close` function
- Fix error on inserting columns or rows on the worksheet which contains one cell merged cell range - Fix getting incomplete rich text cell value in some cases - Unit tests updated
This commit is contained in:
parent
f44153ea46
commit
adf9d37d82
|
@ -278,7 +278,11 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
|
||||||
|
|
||||||
for i := 0; i < len(ws.MergeCells.Cells); i++ {
|
for i := 0; i < len(ws.MergeCells.Cells); i++ {
|
||||||
mergedCells := ws.MergeCells.Cells[i]
|
mergedCells := ws.MergeCells.Cells[i]
|
||||||
coordinates, err := rangeRefToCoordinates(mergedCells.Ref)
|
mergedCellsRef := mergedCells.Ref
|
||||||
|
if !strings.Contains(mergedCellsRef, ":") {
|
||||||
|
mergedCellsRef += ":" + mergedCellsRef
|
||||||
|
}
|
||||||
|
coordinates, err := rangeRefToCoordinates(mergedCellsRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,15 @@ func TestAdjustMergeCells(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, columns, 1, -1))
|
}, columns, 1, -1))
|
||||||
|
assert.NoError(t, f.adjustMergeCells(&xlsxWorksheet{
|
||||||
|
MergeCells: &xlsxMergeCells{
|
||||||
|
Cells: []*xlsxMergeCell{
|
||||||
|
{
|
||||||
|
Ref: "A2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, columns, 1, -1))
|
||||||
|
|
||||||
// testing adjustMergeCells
|
// testing adjustMergeCells
|
||||||
var cases []struct {
|
var cases []struct {
|
||||||
|
|
16
cell.go
16
cell.go
|
@ -152,20 +152,20 @@ func (f *File) SetCellValue(sheet, cell string, value interface{}) error {
|
||||||
|
|
||||||
// String extracts characters from a string item.
|
// String extracts characters from a string item.
|
||||||
func (x xlsxSI) String() string {
|
func (x xlsxSI) String() string {
|
||||||
if len(x.R) > 0 {
|
var value strings.Builder
|
||||||
var rows strings.Builder
|
if x.T != nil {
|
||||||
|
value.WriteString(x.T.Val)
|
||||||
|
}
|
||||||
for _, s := range x.R {
|
for _, s := range x.R {
|
||||||
if s.T != nil {
|
if s.T != nil {
|
||||||
rows.WriteString(s.T.Val)
|
value.WriteString(s.T.Val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bstrUnmarshal(rows.String())
|
if value.Len() == 0 {
|
||||||
}
|
|
||||||
if x.T != nil {
|
|
||||||
return bstrUnmarshal(x.T.Val)
|
|
||||||
}
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
return bstrUnmarshal(value.String())
|
||||||
|
}
|
||||||
|
|
||||||
// hasValue determine if cell non-blank value.
|
// hasValue determine if cell non-blank value.
|
||||||
func (c *xlsxC) hasValue() bool {
|
func (c *xlsxC) hasValue() bool {
|
||||||
|
|
4
file.go
4
file.go
|
@ -97,6 +97,9 @@ func (f *File) Close() error {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
for _, stream := range f.streams {
|
||||||
|
_ = stream.rawData.Close()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +198,6 @@ func (f *File) writeToZip(zw *zip.Writer) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_ = stream.rawData.Close()
|
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
f.Pkg.Range(func(path, content interface{}) bool {
|
f.Pkg.Range(func(path, content interface{}) bool {
|
||||||
|
|
|
@ -48,6 +48,11 @@ type StreamWriter struct {
|
||||||
// with numbers and style:
|
// with numbers and style:
|
||||||
//
|
//
|
||||||
// file := excelize.NewFile()
|
// file := excelize.NewFile()
|
||||||
|
// defer func() {
|
||||||
|
// if err := file.Close(); err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
|
// }
|
||||||
|
// }()
|
||||||
// streamWriter, err := file.NewStreamWriter("Sheet1")
|
// streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
|
|
|
@ -15,7 +15,11 @@ import (
|
||||||
|
|
||||||
func BenchmarkStreamWriter(b *testing.B) {
|
func BenchmarkStreamWriter(b *testing.B) {
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
row := make([]interface{}, 10)
|
row := make([]interface{}, 10)
|
||||||
for colID := 0; colID < 10; colID++ {
|
for colID := 0; colID < 10; colID++ {
|
||||||
row[colID] = colID
|
row[colID] = colID
|
||||||
|
@ -78,6 +82,7 @@ func TestStreamWriter(t *testing.T) {
|
||||||
|
|
||||||
// Test set cell column overflow.
|
// Test set cell column overflow.
|
||||||
assert.ErrorIs(t, streamWriter.SetRow("XFD51201", []interface{}{"A", "B", "C"}), ErrColumnNumber)
|
assert.ErrorIs(t, streamWriter.SetRow("XFD51201", []interface{}{"A", "B", "C"}), ErrColumnNumber)
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
|
||||||
// Test close temporary file error.
|
// Test close temporary file error.
|
||||||
file = NewFile()
|
file = NewFile()
|
||||||
|
@ -107,6 +112,7 @@ func TestStreamWriter(t *testing.T) {
|
||||||
file.Pkg.Store("xl/worksheets/sheet1.xml", MacintoshCyrillicCharset)
|
file.Pkg.Store("xl/worksheets/sheet1.xml", MacintoshCyrillicCharset)
|
||||||
_, err = file.NewStreamWriter("Sheet1")
|
_, err = file.NewStreamWriter("Sheet1")
|
||||||
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
|
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
|
||||||
// Test read cell.
|
// Test read cell.
|
||||||
file = NewFile()
|
file = NewFile()
|
||||||
|
@ -138,6 +144,9 @@ func TestStreamWriter(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamSetColWidth(t *testing.T) {
|
func TestStreamSetColWidth(t *testing.T) {
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, streamWriter.SetColWidth(3, 2, 20))
|
assert.NoError(t, streamWriter.SetColWidth(3, 2, 20))
|
||||||
|
@ -150,6 +159,9 @@ func TestStreamSetColWidth(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamSetPanes(t *testing.T) {
|
func TestStreamSetPanes(t *testing.T) {
|
||||||
file, paneOpts := NewFile(), `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`
|
file, paneOpts := NewFile(), `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, streamWriter.SetPanes(paneOpts))
|
assert.NoError(t, streamWriter.SetPanes(paneOpts))
|
||||||
|
@ -160,6 +172,9 @@ func TestStreamSetPanes(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamTable(t *testing.T) {
|
func TestStreamTable(t *testing.T) {
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
@ -194,6 +209,9 @@ func TestStreamTable(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamMergeCells(t *testing.T) {
|
func TestStreamMergeCells(t *testing.T) {
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, streamWriter.MergeCell("A1", "D1"))
|
assert.NoError(t, streamWriter.MergeCell("A1", "D1"))
|
||||||
|
@ -207,6 +225,9 @@ func TestStreamMergeCells(t *testing.T) {
|
||||||
func TestNewStreamWriter(t *testing.T) {
|
func TestNewStreamWriter(t *testing.T) {
|
||||||
// Test error exceptions
|
// Test error exceptions
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
_, err := file.NewStreamWriter("Sheet1")
|
_, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
_, err = file.NewStreamWriter("SheetN")
|
_, err = file.NewStreamWriter("SheetN")
|
||||||
|
@ -223,6 +244,9 @@ func TestStreamMarshalAttrs(t *testing.T) {
|
||||||
func TestStreamSetRow(t *testing.T) {
|
func TestStreamSetRow(t *testing.T) {
|
||||||
// Test error exceptions
|
// Test error exceptions
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualError(t, streamWriter.SetRow("A", []interface{}{}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
assert.EqualError(t, streamWriter.SetRow("A", []interface{}{}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
||||||
|
@ -233,6 +257,9 @@ func TestStreamSetRow(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamSetRowNilValues(t *testing.T) {
|
func TestStreamSetRowNilValues(t *testing.T) {
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
streamWriter, err := file.NewStreamWriter("Sheet1")
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, streamWriter.SetRow("A1", []interface{}{nil, nil, Cell{Value: "foo"}}))
|
assert.NoError(t, streamWriter.SetRow("A1", []interface{}{nil, nil, Cell{Value: "foo"}}))
|
||||||
|
@ -244,6 +271,9 @@ func TestStreamSetRowNilValues(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamSetRowWithStyle(t *testing.T) {
|
func TestStreamSetRowWithStyle(t *testing.T) {
|
||||||
file := NewFile()
|
file := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, file.Close())
|
||||||
|
}()
|
||||||
zeroStyleID := 0
|
zeroStyleID := 0
|
||||||
grayStyleID, err := file.NewStyle(&Style{Font: &Font{Color: "#777777"}})
|
grayStyleID, err := file.NewStyle(&Style{Font: &Font{Color: "#777777"}})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -273,6 +303,9 @@ func TestStreamSetRowWithStyle(t *testing.T) {
|
||||||
|
|
||||||
func TestStreamSetCellValFunc(t *testing.T) {
|
func TestStreamSetCellValFunc(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, f.Close())
|
||||||
|
}()
|
||||||
sw, err := f.NewStreamWriter("Sheet1")
|
sw, err := f.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
c := &xlsxC{}
|
c := &xlsxC{}
|
||||||
|
|
Loading…
Reference in New Issue