From eaf9781e7e51d5aacf238c9cb39a249097abed33 Mon Sep 17 00:00:00 2001 From: Arnie97 Date: Sat, 31 Jul 2021 14:20:29 +0800 Subject: [PATCH] Improve compatibility for SetRichText (#976) - support escaped string literal - maximum character limit added - fix missing preserve character in some case Co-authored-by: xuri --- cell.go | 34 +++++++++++++++++----------------- cell_test.go | 3 +++ errors.go | 5 ++++- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/cell.go b/cell.go index 39990d48..ad94038d 100644 --- a/cell.go +++ b/cell.go @@ -307,16 +307,8 @@ func (f *File) setSharedString(val string) int { } sst.Count++ sst.UniqueCount++ - val = bstrMarshal(val) t := xlsxT{Val: val} - // Leading and ending space(s) character detection. - if len(val) > 0 && (val[0] == 32 || val[len(val)-1] == 32) { - ns := xml.Attr{ - Name: xml.Name{Space: NameSpaceXML, Local: "space"}, - Value: "preserve", - } - t.Space = ns - } + _, val, t.Space = setCellStr(val) sst.SI = append(sst.SI, xlsxSI{T: &t}) f.sharedStringsMap[val] = sst.UniqueCount - 1 return sst.UniqueCount - 1 @@ -327,11 +319,16 @@ func setCellStr(value string) (t string, v string, ns xml.Attr) { if len(value) > TotalCellChars { value = value[0:TotalCellChars] } - // Leading and ending space(s) character detection. - if len(value) > 0 && (value[0] == 32 || value[len(value)-1] == 32) { - ns = xml.Attr{ - Name: xml.Name{Space: NameSpaceXML, Local: "space"}, - Value: "preserve", + if len(value) > 0 { + prefix, suffix := value[0], value[len(value)-1] + for _, ascii := range []byte{10, 13, 32} { + if prefix == ascii || suffix == ascii { + ns = xml.Attr{ + Name: xml.Name{Space: NameSpaceXML, Local: "space"}, + Value: "preserve", + } + break + } } } t = "str" @@ -702,11 +699,14 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error { si := xlsxSI{} sst := f.sharedStringsReader() textRuns := []xlsxR{} + totalCellChars := 0 for _, textRun := range runs { - run := xlsxR{T: &xlsxT{Val: textRun.Text}} - if strings.ContainsAny(textRun.Text, "\r\n ") { - run.T.Space = xml.Attr{Name: xml.Name{Space: NameSpaceXML, Local: "space"}, Value: "preserve"} + totalCellChars += len(textRun.Text) + if totalCellChars > TotalCellChars { + return ErrCellCharsLength } + run := xlsxR{T: &xlsxT{}} + _, run.T.Val, run.T.Space = setCellStr(textRun.Text) fnt := textRun.Font if fnt != nil { rpr := xlsxRPr{} diff --git a/cell_test.go b/cell_test.go index ea628696..3954438e 100644 --- a/cell_test.go +++ b/cell_test.go @@ -401,6 +401,9 @@ func TestSetCellRichText(t *testing.T) { assert.EqualError(t, f.SetCellRichText("SheetN", "A1", richTextRun), "sheet SheetN is not exist") // Test set cell rich text with illegal cell coordinates assert.EqualError(t, f.SetCellRichText("Sheet1", "A", richTextRun), `cannot convert cell "A" to coordinates: invalid cell name "A"`) + richTextRun = []RichTextRun{{Text: strings.Repeat("s", TotalCellChars+1)}} + // Test set cell rich text with characters over the maximum limit + assert.EqualError(t, f.SetCellRichText("Sheet1", "A1", richTextRun), ErrCellCharsLength.Error()) } func TestFormattedValue2(t *testing.T) { diff --git a/errors.go b/errors.go index 6b325636..0edb697c 100644 --- a/errors.go +++ b/errors.go @@ -45,7 +45,7 @@ var ( ErrColumnNumber = errors.New("column number exceeds maximum limit") // ErrColumnWidth defined the error message on receive an invalid column // width. - ErrColumnWidth = errors.New("the width of the column must be smaller than or equal to 255 characters") + ErrColumnWidth = fmt.Errorf("the width of the column must be smaller than or equal to %d characters", MaxColumnWidth) // ErrOutlineLevel defined the error message on receive an invalid outline // level number. ErrOutlineLevel = errors.New("invalid outline level") @@ -111,4 +111,7 @@ var ( // ErrDataValidationRange defined the error message on set decimal range // exceeds limit. ErrDataValidationRange = errors.New("data validation range exceeds limit") + // ErrCellCharsLength defined the error message for receiving a cell + // characters length that exceeds the limit. + ErrCellCharsLength = fmt.Errorf("cell value must be 0-%d characters", TotalCellChars) )