浏览代码

Fix #622, storage string to SST (shared string table)

xuri 5 年之前
父节点
当前提交
5c99300ee4
共有 3 个文件被更改,包括 46 次插入12 次删除
  1. 35 11
      cell.go
  2. 10 0
      rows.go
  3. 1 1
      xmlSharedStrings.go

+ 35 - 11
cell.go

@@ -274,10 +274,43 @@ func (f *File) SetCellStr(sheet, axis, value string) error {
 		return err
 	}
 	cellData.S = f.prepareCellStyle(xlsx, col, cellData.S)
-	cellData.T, cellData.V, cellData.XMLSpace = setCellStr(value)
+	cellData.T, cellData.V, cellData.XMLSpace = 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, ns xml.Attr) {
+	if len(value) > 32767 {
+		value = value[0:32767]
+	}
+	// 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",
+		}
+	}
+	t = "s"
+	v = strconv.Itoa(f.setSharedString(value))
+	return
+}
+
+// setSharedString provides a function to add string to the share string table.
+func (f *File) setSharedString(val string) int {
+	sst := f.sharedStringsReader()
+	for i, si := range sst.SI {
+		if si.T == val {
+			return i
+		}
+	}
+	sst.Count++
+	sst.UniqueCount++
+	sst.SI = append(sst.SI, xlsxSI{T: val})
+	return sst.UniqueCount - 1
+}
+
+// setCellStr provides a function to set string type to cell.
 func setCellStr(value string) (t string, v string, ns xml.Attr) {
 	if len(value) > 32767 {
 		value = value[0:32767]
@@ -590,7 +623,7 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
 	for _, textRun := range runs {
 		run := xlsxR{T: &xlsxT{Val: textRun.Text}}
 		if strings.ContainsAny(textRun.Text, "\r\n ") {
-			run.T.Space = "preserve"
+			run.T.Space = xml.Attr{Name: xml.Name{Space: NameSpaceXML, Local: "space"}, Value: "preserve"}
 		}
 		fnt := textRun.Font
 		if fnt != nil {
@@ -625,15 +658,6 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
 	sst.Count++
 	sst.UniqueCount++
 	cellData.T, cellData.V = "s", strconv.Itoa(len(sst.SI)-1)
-	f.addContentTypePart(0, "sharedStrings")
-	rels := f.relsReader("xl/_rels/workbook.xml.rels")
-	for _, rel := range rels.Relationships {
-		if rel.Target == "sharedStrings.xml" {
-			return err
-		}
-	}
-	// Update xl/_rels/workbook.xml.rels
-	f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipSharedStrings, "sharedStrings.xml", "")
 	return err
 }
 

+ 10 - 0
rows.go

@@ -285,12 +285,22 @@ func (f *File) sharedStringsReader() *xlsxSST {
 		ss := f.readXML("xl/sharedStrings.xml")
 		if len(ss) == 0 {
 			ss = f.readXML("xl/SharedStrings.xml")
+			delete(f.XLSX, "xl/SharedStrings.xml")
 		}
 		if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(ss))).
 			Decode(&sharedStrings); err != nil && err != io.EOF {
 			log.Printf("xml decode error: %s", err)
 		}
 		f.SharedStrings = &sharedStrings
+		f.addContentTypePart(0, "sharedStrings")
+		rels := f.relsReader("xl/_rels/workbook.xml.rels")
+		for _, rel := range rels.Relationships {
+			if rel.Target == "sharedStrings.xml" {
+				return f.SharedStrings
+			}
+		}
+		// Update xl/_rels/workbook.xml.rels
+		f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipSharedStrings, "sharedStrings.xml", "")
 	}
 
 	return f.SharedStrings

+ 1 - 1
xmlSharedStrings.go

@@ -66,7 +66,7 @@ type xlsxR struct {
 // xlsxT directly maps the t element in the run properties.
 type xlsxT struct {
 	XMLName xml.Name `xml:"t"`
-	Space   string   `xml:"xml:space,attr,omitempty"`
+	Space   xml.Attr `xml:"space,attr,omitempty"`
 	Val     string   `xml:",innerxml"`
 }