From acd76425c2ee55c45a51cf7f71c8a6187a09f507 Mon Sep 17 00:00:00 2001
From: Harris <mike.harris@cerner.com>
Date: Wed, 7 Aug 2019 16:26:13 -0500
Subject: Handle multi row inline strings

The inline string struct is actually the same
as the shared strings struct, reuse it.

Note that Go version 1.10 is required.

Fixes #462
---
 README.md               |   2 +-
 excelize_test.go        |   5 +++++
 rows.go                 |  11 ++---------
 test/SharedStrings.xlsx | Bin 6462 -> 9419 bytes
 xmlSharedStrings.go     |  16 +++++++++++++++-
 xmlWorksheet.go         |  14 ++++----------
 6 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index 91155e3..4bb7d66 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
 ## Introduction
 
 Excelize is a library written in pure Go providing a set of functions that allow you to write to and read from XLSX files. Supports reading and writing XLSX file generated by Microsoft Excel&trade; 2007 and later.
-Supports saving a file without losing original charts of XLSX. This library needs Go version 1.8 or later. The full API docs can be seen using go's built-in documentation tool, or online at [godoc.org](https://godoc.org/github.com/360EntSecGroup-Skylar/excelize) and [docs reference](https://xuri.me/excelize/).
+Supports saving a file without losing original charts of XLSX. This library needs Go version 1.10 or later. The full API docs can be seen using go's built-in documentation tool, or online at [godoc.org](https://godoc.org/github.com/360EntSecGroup-Skylar/excelize) and [docs reference](https://xuri.me/excelize/).
 
 ## Basic Usage
 
diff --git a/excelize_test.go b/excelize_test.go
index 4169983..d61dd7b 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -1008,6 +1008,11 @@ func TestSharedStrings(t *testing.T) {
 		t.FailNow()
 	}
 	assert.Equal(t, "A", rows[0][0])
+	rows, err = f.GetRows("Sheet2")
+	if !assert.NoError(t, err) {
+		t.FailNow()
+	}
+	assert.Equal(t, "Test Weight (Kgs)", rows[0][0])
 }
 
 func TestSetSheetRow(t *testing.T) {
diff --git a/rows.go b/rows.go
index 220c233..c17179f 100644
--- a/rows.go
+++ b/rows.go
@@ -206,18 +206,11 @@ func (xlsx *xlsxC) getValueFrom(f *File, d *xlsxSST) (string, error) {
 	case "s":
 		xlsxSI := 0
 		xlsxSI, _ = strconv.Atoi(xlsx.V)
-		if len(d.SI[xlsxSI].R) > 0 {
-			value := ""
-			for _, v := range d.SI[xlsxSI].R {
-				value += v.T
-			}
-			return value, nil
-		}
-		return f.formattedValue(xlsx.S, d.SI[xlsxSI].T), nil
+		return f.formattedValue(xlsx.S, d.SI[xlsxSI].String()), nil
 	case "str":
 		return f.formattedValue(xlsx.S, xlsx.V), nil
 	case "inlineStr":
-		return f.formattedValue(xlsx.S, xlsx.IS.T), nil
+		return f.formattedValue(xlsx.S, xlsx.IS.String()), nil
 	default:
 		return f.formattedValue(xlsx.S, xlsx.V), nil
 	}
diff --git a/test/SharedStrings.xlsx b/test/SharedStrings.xlsx
index 7b722d9..d6004c0 100644
Binary files a/test/SharedStrings.xlsx and b/test/SharedStrings.xlsx differ
diff --git a/xmlSharedStrings.go b/xmlSharedStrings.go
index 3fcf3d5..48d4464 100644
--- a/xmlSharedStrings.go
+++ b/xmlSharedStrings.go
@@ -9,7 +9,10 @@
 
 package excelize
 
-import "encoding/xml"
+import (
+	"encoding/xml"
+	"strings"
+)
 
 // xlsxSST directly maps the sst element from the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main. String values may
@@ -33,6 +36,17 @@ type xlsxSI struct {
 	R []xlsxR `xml:"r"`
 }
 
+func (x xlsxSI) String() string {
+	if len(x.R) > 0 {
+		var rows strings.Builder
+		for _, s := range x.R {
+			rows.WriteString(s.T)
+		}
+		return rows.String()
+	}
+	return x.T
+}
+
 // xlsxR directly maps the r element from the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main - currently I have
 // not checked this for completeness - it does as much as I need.
diff --git a/xmlWorksheet.go b/xmlWorksheet.go
index 9727866..a5db776 100644
--- a/xmlWorksheet.go
+++ b/xmlWorksheet.go
@@ -9,7 +9,9 @@
 
 package excelize
 
-import "encoding/xml"
+import (
+	"encoding/xml"
+)
 
 // xlsxWorksheet directly maps the worksheet element in the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main - currently I have
@@ -424,18 +426,10 @@ type xlsxC struct {
 	T        string   `xml:"t,attr,omitempty"` // Type.
 	F        *xlsxF   `xml:"f,omitempty"`      // Formula
 	V        string   `xml:"v,omitempty"`      // Value
-	IS       *xlsxIS  `xml:"is"`
+	IS       *xlsxSI  `xml:"is"`
 	XMLSpace xml.Attr `xml:"space,attr,omitempty"`
 }
 
-// xlsxIS directly maps the t element. Cell containing an (inline) rich
-// string, i.e., one not in the shared string table. If this cell type is
-// used, then the cell value is in the is element rather than the v element in
-// the cell (c element).
-type xlsxIS struct {
-	T string `xml:"t"`
-}
-
 // xlsxF directly maps the f element in the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main - currently I have
 // not checked it for completeness - it does as much as I need.
-- 
cgit v1.2.1