From 7e429c5b464b53f305e94cc355f14ba9e1d9849c Mon Sep 17 00:00:00 2001
From: xuri <xuri.me@gmail.com>
Date: Fri, 30 Apr 2021 00:14:42 +0800
Subject: Fixe issue generated file corrupted caused by incorrect default XML
 namespace attributes

---
 README.md        |  2 +-
 README_zh.md     |  2 +-
 excelize_test.go |  2 +-
 lib.go           |  3 +++
 lib_test.go      |  6 ++++++
 stream.go        | 10 +++++-----
 stream_test.go   | 12 +++++++++++-
 styles.go        |  7 +++----
 table.go         |  2 +-
 xmlDrawing.go    |  1 +
 xmlStyles.go     | 14 +++++++-------
 11 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index ce7cf3d..3e6728f 100644
--- a/README.md
+++ b/README.md
@@ -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
 
diff --git a/README_zh.md b/README_zh.md
index cf9888b..4e0a499 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -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/)。
 
 ## 开源许可
 
diff --git a/excelize_test.go b/excelize_test.go
index f663ae0..0dcfacb 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -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.")
diff --git a/lib.go b/lib.go
index 26d402a..3a9e807 100644
--- a/lib.go
+++ b/lib.go
@@ -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
 		}
diff --git a/lib_test.go b/lib_test.go
index f3e9b3e..10d7c3a 100644
--- a/lib_test.go
+++ b/lib_test.go
@@ -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">`)
+}
diff --git a/stream.go b/stream.go
index fdada74..57bf4a2 100644
--- a/stream.go
+++ b/stream.go
@@ -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 {
diff --git a/stream_test.go b/stream_test.go
index 26732d8..d36883a 100644
--- a/stream_test.go
+++ b/stream_test.go
@@ -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) {
diff --git a/styles.go b/styles.go
index 15234fd..4369f29 100644
--- a/styles.go
+++ b/styles.go
@@ -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 {
diff --git a/table.go b/table.go
index 973a416..12ef41a 100644
--- a/table.go
+++ b/table.go
@@ -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:
 //
diff --git a/xmlDrawing.go b/xmlDrawing.go
index a18c588..4b51b63 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -91,6 +91,7 @@ const (
 
 // Excel specifications and limits
 const (
+	StreamChunkSize      = 1 << 24
 	MaxFontFamilyLength  = 31
 	MaxFontSize          = 409
 	MaxFileNameLength    = 207
diff --git a/xmlStyles.go b/xmlStyles.go
index 46604dc..92e4e6a 100644
--- a/xmlStyles.go
+++ b/xmlStyles.go
@@ -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"`
-- 
cgit v1.2.1