Fixe issue generated file corrupted caused by incorrect default XML namespace attributes

This commit is contained in:
xuri 2021-04-30 00:14:42 +08:00
parent af5e87dbcf
commit 7e429c5b46
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
11 changed files with 40 additions and 21 deletions

View File

@ -204,7 +204,7 @@ func main() {
## Contributing
Contributions are welcome! Open a pull request to fix a bug, or open an issue to discuss a new feature or change. XML is compliant with [part 1 of the 5th edition of the ECMA-376 Standard for Office Open XML](http://www.ecma-international.org/publications/standards/Ecma-376.htm).
Contributions are welcome! Open a pull request to fix a bug, or open an issue to discuss a new feature or change. XML is compliant with [part 1 of the 5th edition of the ECMA-376 Standard for Office Open XML](https://www.ecma-international.org/publications-and-standards/standards/ecma-376/).
## Licenses

View File

@ -204,7 +204,7 @@ func main() {
## 社区合作
欢迎您为此项目贡献代码,提出建议或问题、修复 Bug 以及参与讨论对新功能的想法。 XML 符合标准: [part 1 of the 5th edition of the ECMA-376 Standard for Office Open XML](http://www.ecma-international.org/publications/standards/Ecma-376.htm)。
欢迎您为此项目贡献代码,提出建议或问题、修复 Bug 以及参与讨论对新功能的想法。 XML 符合标准: [part 1 of the 5th edition of the ECMA-376 Standard for Office Open XML](https://www.ecma-international.org/publications-and-standards/standards/ecma-376/)。
## 开源许可

View File

@ -54,7 +54,7 @@ func TestOpenFile(t *testing.T) {
assert.NoError(t, f.SetCellStr("Sheet2", "C11", "Knowns"))
// Test max characters in a cell.
assert.NoError(t, f.SetCellStr("Sheet2", "D11", strings.Repeat("c", 32769)))
assert.NoError(t, f.SetCellStr("Sheet2", "D11", strings.Repeat("c", TotalCellChars+2)))
f.NewSheet(":\\/?*[]Maximum 31 characters allowed in sheet title.")
// Test set worksheet name with illegal name.
f.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")

3
lib.go
View File

@ -349,6 +349,9 @@ func genXMLNamespace(attr []xml.Attr) string {
var rootElement string
for _, v := range attr {
if lastSpace := getXMLNamespace(v.Name.Space, attr); lastSpace != "" {
if lastSpace == NameSpaceXML {
lastSpace = "xml"
}
rootElement += fmt.Sprintf("%s:%s=\"%s\" ", lastSpace, v.Name.Local, v.Value)
continue
}

View File

@ -228,3 +228,9 @@ func TestStack(t *testing.T) {
assert.Equal(t, s.Peek(), nil)
assert.Equal(t, s.Pop(), nil)
}
func TestGenXMLNamespace(t *testing.T) {
assert.Equal(t, genXMLNamespace([]xml.Attr{
{Name: xml.Name{Space: NameSpaceXML, Local: "space"}, Value: "preserve"},
}), `xml:space="preserve">`)
}

View File

@ -40,8 +40,9 @@ type StreamWriter struct {
// generate new worksheet with large amounts of data. Note that after set
// rows, you must call the 'Flush' method to end the streaming writing
// process and ensure that the order of line numbers is ascending, the common
// API and stream API can't be work mixed to writing data on the worksheets.
// For example, set data for worksheet of size 102400 rows x 50 columns with
// API and stream API can't be work mixed to writing data on the worksheets,
// you can't get cell value when in-memory chunks data over 16MB. For
// example, set data for worksheet of size 102400 rows x 50 columns with
// numbers and style:
//
// file := excelize.NewFile()
@ -111,7 +112,7 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
// AddTable creates an Excel table for the StreamWriter using the given
// coordinate area and format set. For example, create a table of A1:D5:
//
// err := sw.AddTable("A1", "D5", ``)
// err := sw.AddTable("A1", "D5", "")
//
// Create a table of F2:H6 with format set:
//
@ -500,8 +501,7 @@ func (bw *bufferedWriter) Reader() (io.Reader, error) {
// buffer has grown large enough. Any error will be returned.
func (bw *bufferedWriter) Sync() (err error) {
// Try to use local storage
const chunk = 1 << 24
if bw.buf.Len() < chunk {
if bw.buf.Len() < StreamChunkSize {
return nil
}
if bw.tmp == nil {

View File

@ -40,7 +40,7 @@ func TestStreamWriter(t *testing.T) {
// Test max characters in a cell.
row := make([]interface{}, 1)
row[0] = strings.Repeat("c", 32769)
row[0] = strings.Repeat("c", TotalCellChars+2)
assert.NoError(t, streamWriter.SetRow("A1", row))
// Test leading and ending space(s) character characters in a cell.
@ -100,6 +100,16 @@ func TestStreamWriter(t *testing.T) {
file.XLSX["xl/worksheets/sheet1.xml"] = MacintoshCyrillicCharset
_, err = file.NewStreamWriter("Sheet1")
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
// Test read cell.
file = NewFile()
streamWriter, err = file.NewStreamWriter("Sheet1")
assert.NoError(t, err)
assert.NoError(t, streamWriter.SetRow("A1", []interface{}{Cell{StyleID: styleID, Value: "Data"}}))
assert.NoError(t, streamWriter.Flush())
cellValue, err := file.GetCellValue("Sheet1", "A1")
assert.NoError(t, err)
assert.Equal(t, "Data", cellValue)
}
func TestStreamTable(t *testing.T) {

View File

@ -2187,17 +2187,16 @@ func (f *File) newFont(style *Style) *xlsxFont {
Family: &attrValInt{Val: intPtr(2)},
}
if style.Font.Bold {
fnt.B = &style.Font.Bold
fnt.B = &attrValBool{Val: &style.Font.Bold}
}
if style.Font.Italic {
fnt.I = &style.Font.Italic
fnt.I = &attrValBool{Val: &style.Font.Italic}
}
if *fnt.Name.Val == "" {
*fnt.Name.Val = f.GetDefaultFont()
}
if style.Font.Strike {
strike := true
fnt.Strike = &strike
fnt.Strike = &attrValBool{Val: &style.Font.Strike}
}
val, ok := fontUnderlineType[style.Font.Underline]
if ok {

View File

@ -35,7 +35,7 @@ func parseFormatTableSet(formatSet string) (*formatTable, error) {
// name, coordinate area and format set. For example, create a table of A1:D5
// on Sheet1:
//
// err := f.AddTable("Sheet1", "A1", "D5", ``)
// err := f.AddTable("Sheet1", "A1", "D5", "")
//
// Create a table of F2:H6 on Sheet2 with format set:
//

View File

@ -91,6 +91,7 @@ const (
// Excel specifications and limits
const (
StreamChunkSize = 1 << 24
MaxFontFamilyLength = 31
MaxFontSize = 409
MaxFileNameLength = 207

View File

@ -83,13 +83,13 @@ type xlsxFonts struct {
// xlsxFont directly maps the font element. This element defines the
// properties for one of the fonts used in this workbook.
type xlsxFont struct {
B *bool `xml:"b,omitempty"`
I *bool `xml:"i,omitempty"`
Strike *bool `xml:"strike,omitempty"`
Outline *bool `xml:"outline,omitempty"`
Shadow *bool `xml:"shadow,omitempty"`
Condense *bool `xml:"condense,omitempty"`
Extend *bool `xml:"extend,omitempty"`
B *attrValBool `xml:"b,omitempty"`
I *attrValBool `xml:"i,omitempty"`
Strike *attrValBool `xml:"strike,omitempty"`
Outline *attrValBool `xml:"outline,omitempty"`
Shadow *attrValBool `xml:"shadow,omitempty"`
Condense *attrValBool `xml:"condense,omitempty"`
Extend *attrValBool `xml:"extend,omitempty"`
U *attrValString `xml:"u"`
Sz *attrValFloat `xml:"sz"`
Color *xlsxColor `xml:"color"`