summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2022-11-02 08:42:00 +0800
committerxuri <xuri.me@gmail.com>2022-11-02 08:45:06 +0800
commitdb2d084ada1a08a48967506b2f1852062168deec (patch)
tree18334eb7de2deb65c822a51e1e435084831c8876
parenta410b22bdd50e9f212b0b454e5aed798e3476394 (diff)
This closes #1204, breaking changes for add comments
- Allowing insert SVG format images - Unit tests updated
-rw-r--r--.gitignore18
-rw-r--r--cell.go55
-rw-r--r--comment.go137
-rw-r--r--comment_test.go22
-rw-r--r--excelize_test.go3
-rw-r--r--picture.go23
-rw-r--r--picture_test.go4
-rw-r--r--xmlComments.go15
-rw-r--r--xmlDrawing.go37
-rw-r--r--xmlSharedStrings.go4
10 files changed, 181 insertions, 137 deletions
diff --git a/.gitignore b/.gitignore
index 44b8b09..8bf9e7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,15 @@
+.DS_Store
+.idea
+*.json
+*.out
+*.test
~$*.xlsx
+test/*.png
+test/BadWorkbook.SaveAsEmptyStruct.xlsx
+test/Encryption*.xlsx
+test/excelize-*
test/Test*.xlam
test/Test*.xlsm
test/Test*.xlsx
test/Test*.xltm
test/Test*.xltx
-# generated files
-test/Encryption*.xlsx
-test/BadWorkbook.SaveAsEmptyStruct.xlsx
-test/*.png
-test/excelize-*
-*.out
-*.test
-.idea
-.DS_Store
diff --git a/cell.go b/cell.go
index fbc84b7..eb60441 100644
--- a/cell.go
+++ b/cell.go
@@ -902,31 +902,7 @@ func getCellRichText(si *xlsxSI) (runs []RichTextRun) {
Text: v.T.Val,
}
if v.RPr != nil {
- font := Font{Underline: "none"}
- font.Bold = v.RPr.B != nil
- font.Italic = v.RPr.I != nil
- if v.RPr.U != nil {
- font.Underline = "single"
- if v.RPr.U.Val != nil {
- font.Underline = *v.RPr.U.Val
- }
- }
- if v.RPr.RFont != nil && v.RPr.RFont.Val != nil {
- font.Family = *v.RPr.RFont.Val
- }
- if v.RPr.Sz != nil && v.RPr.Sz.Val != nil {
- font.Size = *v.RPr.Sz.Val
- }
- font.Strike = v.RPr.Strike != nil
- if v.RPr.Color != nil {
- font.Color = strings.TrimPrefix(v.RPr.Color.RGB, "FF")
- if v.RPr.Color.Theme != nil {
- font.ColorTheme = v.RPr.Color.Theme
- }
- font.ColorIndexed = v.RPr.Color.Indexed
- font.ColorTint = v.RPr.Color.Tint
- }
- run.Font = &font
+ run.Font = newFont(v.RPr)
}
runs = append(runs, run)
}
@@ -985,6 +961,35 @@ func newRpr(fnt *Font) *xlsxRPr {
return &rpr
}
+// newFont create font format by given run properties for the rich text.
+func newFont(rPr *xlsxRPr) *Font {
+ font := Font{Underline: "none"}
+ font.Bold = rPr.B != nil
+ font.Italic = rPr.I != nil
+ if rPr.U != nil {
+ font.Underline = "single"
+ if rPr.U.Val != nil {
+ font.Underline = *rPr.U.Val
+ }
+ }
+ if rPr.RFont != nil && rPr.RFont.Val != nil {
+ font.Family = *rPr.RFont.Val
+ }
+ if rPr.Sz != nil && rPr.Sz.Val != nil {
+ font.Size = *rPr.Sz.Val
+ }
+ font.Strike = rPr.Strike != nil
+ if rPr.Color != nil {
+ font.Color = strings.TrimPrefix(rPr.Color.RGB, "FF")
+ if rPr.Color.Theme != nil {
+ font.ColorTheme = rPr.Color.Theme
+ }
+ font.ColorIndexed = rPr.Color.Indexed
+ font.ColorTint = rPr.Color.Tint
+ }
+ return &font
+}
+
// setRichText provides a function to set rich text of a cell.
func setRichText(runs []RichTextRun) ([]xlsxR, error) {
var (
diff --git a/comment.go b/comment.go
index 3d08324..28c6cf8 100644
--- a/comment.go
+++ b/comment.go
@@ -13,7 +13,6 @@ package excelize
import (
"bytes"
- "encoding/json"
"encoding/xml"
"fmt"
"io"
@@ -23,17 +22,6 @@ import (
"strings"
)
-// parseCommentOptions provides a function to parse the format settings of
-// the comment with default value.
-func parseCommentOptions(opts string) (*commentOptions, error) {
- options := commentOptions{
- Author: "Author:",
- Text: " ",
- }
- err := json.Unmarshal([]byte(opts), &options)
- return &options, err
-}
-
// GetComments retrieves all comments and returns a map of worksheet name to
// the worksheet comments.
func (f *File) GetComments() (comments map[string][]Comment) {
@@ -53,14 +41,18 @@ func (f *File) GetComments() (comments map[string][]Comment) {
if comment.AuthorID < len(d.Authors.Author) {
sheetComment.Author = d.Authors.Author[comment.AuthorID]
}
- sheetComment.Ref = comment.Ref
+ sheetComment.Cell = comment.Ref
sheetComment.AuthorID = comment.AuthorID
if comment.Text.T != nil {
sheetComment.Text += *comment.Text.T
}
for _, text := range comment.Text.R {
if text.T != nil {
- sheetComment.Text += text.T.Val
+ run := RichTextRun{Text: text.T.Val}
+ if text.RPr != nil {
+ run.Font = newFont(text.RPr)
+ }
+ sheetComment.Runs = append(sheetComment.Runs, run)
}
}
sheetComments = append(sheetComments, sheetComment)
@@ -92,12 +84,15 @@ func (f *File) getSheetComments(sheetFile string) string {
// author length is 255 and the max text length is 32512. For example, add a
// comment in Sheet1!$A$30:
//
-// err := f.AddComment("Sheet1", "A30", `{"author":"Excelize: ","text":"This is a comment."}`)
-func (f *File) AddComment(sheet, cell, opts string) error {
- options, err := parseCommentOptions(opts)
- if err != nil {
- return err
- }
+// err := f.AddComment(sheet, excelize.Comment{
+// Cell: "A12",
+// Author: "Excelize",
+// Runs: []excelize.RichTextRun{
+// {Text: "Excelize: ", Font: &excelize.Font{Bold: true}},
+// {Text: "This is a comment."},
+// },
+// })
+func (f *File) AddComment(sheet string, comment Comment) error {
// Read sheet data.
ws, err := f.workSheetReader(sheet)
if err != nil {
@@ -122,20 +117,19 @@ func (f *File) AddComment(sheet, cell, opts string) error {
f.addSheetLegacyDrawing(sheet, rID)
}
commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml"
- var colCount int
- for i, l := range strings.Split(options.Text, "\n") {
- if ll := len(l); ll > colCount {
- if i == 0 {
- ll += len(options.Author)
+ var rows, cols int
+ for _, runs := range comment.Runs {
+ for _, subStr := range strings.Split(runs.Text, "\n") {
+ rows++
+ if chars := len(subStr); chars > cols {
+ cols = chars
}
- colCount = ll
}
}
- err = f.addDrawingVML(commentID, drawingVML, cell, strings.Count(options.Text, "\n")+1, colCount)
- if err != nil {
+ if err = f.addDrawingVML(commentID, drawingVML, comment.Cell, rows+1, cols); err != nil {
return err
}
- f.addComment(commentsXML, cell, options)
+ f.addComment(commentsXML, comment)
f.addContentTypePart(commentID, "comments")
return err
}
@@ -280,56 +274,59 @@ func (f *File) addDrawingVML(commentID int, drawingVML, cell string, lineCount,
// addComment provides a function to create chart as xl/comments%d.xml by
// given cell and format sets.
-func (f *File) addComment(commentsXML, cell string, opts *commentOptions) {
- a := opts.Author
- t := opts.Text
- if len(a) > MaxFieldLength {
- a = a[:MaxFieldLength]
+func (f *File) addComment(commentsXML string, comment Comment) {
+ if comment.Author == "" {
+ comment.Author = "Author"
}
- if len(t) > 32512 {
- t = t[:32512]
+ if len(comment.Author) > MaxFieldLength {
+ comment.Author = comment.Author[:MaxFieldLength]
}
- comments := f.commentsReader(commentsXML)
- authorID := 0
+ comments, authorID := f.commentsReader(commentsXML), 0
if comments == nil {
- comments = &xlsxComments{Authors: xlsxAuthor{Author: []string{opts.Author}}}
+ comments = &xlsxComments{Authors: xlsxAuthor{Author: []string{comment.Author}}}
}
- if inStrSlice(comments.Authors.Author, opts.Author, true) == -1 {
- comments.Authors.Author = append(comments.Authors.Author, opts.Author)
+ if inStrSlice(comments.Authors.Author, comment.Author, true) == -1 {
+ comments.Authors.Author = append(comments.Authors.Author, comment.Author)
authorID = len(comments.Authors.Author) - 1
}
- defaultFont := f.GetDefaultFont()
- bold := ""
- cmt := xlsxComment{
- Ref: cell,
+ defaultFont, chars, cmt := f.GetDefaultFont(), 0, xlsxComment{
+ Ref: comment.Cell,
AuthorID: authorID,
- Text: xlsxText{
- R: []xlsxR{
- {
- RPr: &xlsxRPr{
- B: &bold,
- Sz: &attrValFloat{Val: float64Ptr(9)},
- Color: &xlsxColor{
- Indexed: 81,
- },
- RFont: &attrValString{Val: stringPtr(defaultFont)},
- Family: &attrValInt{Val: intPtr(2)},
- },
- T: &xlsxT{Val: a},
- },
- {
- RPr: &xlsxRPr{
- Sz: &attrValFloat{Val: float64Ptr(9)},
- Color: &xlsxColor{
- Indexed: 81,
- },
- RFont: &attrValString{Val: stringPtr(defaultFont)},
- Family: &attrValInt{Val: intPtr(2)},
- },
- T: &xlsxT{Val: t},
+ Text: xlsxText{R: []xlsxR{}},
+ }
+ if comment.Text != "" {
+ if len(comment.Text) > TotalCellChars {
+ comment.Text = comment.Text[:TotalCellChars]
+ }
+ cmt.Text.T = stringPtr(comment.Text)
+ chars += len(comment.Text)
+ }
+ for _, run := range comment.Runs {
+ if chars == TotalCellChars {
+ break
+ }
+ if chars+len(run.Text) > TotalCellChars {
+ run.Text = run.Text[:TotalCellChars-chars]
+ }
+ chars += len(run.Text)
+ r := xlsxR{
+ RPr: &xlsxRPr{
+ Sz: &attrValFloat{Val: float64Ptr(9)},
+ Color: &xlsxColor{
+ Indexed: 81,
},
+ RFont: &attrValString{Val: stringPtr(defaultFont)},
+ Family: &attrValInt{Val: intPtr(2)},
},
- },
+ T: &xlsxT{Val: run.Text, Space: xml.Attr{
+ Name: xml.Name{Space: NameSpaceXML, Local: "space"},
+ Value: "preserve",
+ }},
+ }
+ if run.Font != nil {
+ r.RPr = newRpr(run.Font)
+ }
+ cmt.Text.R = append(cmt.Text.R, r)
}
comments.CommentList.Comment = append(comments.CommentList.Comment, cmt)
f.Comments[commentsXML] = comments
diff --git a/comment_test.go b/comment_test.go
index 2beca70..019dc3b 100644
--- a/comment_test.go
+++ b/comment_test.go
@@ -26,14 +26,14 @@ func TestAddComments(t *testing.T) {
t.FailNow()
}
- s := strings.Repeat("c", 32768)
- assert.NoError(t, f.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`))
- assert.NoError(t, f.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`))
+ s := strings.Repeat("c", TotalCellChars+1)
+ assert.NoError(t, f.AddComment("Sheet1", Comment{Cell: "A30", Author: s, Text: s, Runs: []RichTextRun{{Text: s}, {Text: s}}}))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "B7", Author: "Excelize", Text: s[:TotalCellChars-1], Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}))
// Test add comment on not exists worksheet.
- assert.EqualError(t, f.AddComment("SheetN", "B7", `{"author":"Excelize: ","text":"This is a comment."}`), "sheet SheetN does not exist")
+ assert.EqualError(t, f.AddComment("SheetN", Comment{Cell: "B7", Author: "Excelize", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}), "sheet SheetN does not exist")
// Test add comment on with illegal cell reference
- assert.EqualError(t, f.AddComment("Sheet1", "A", `{"author":"Excelize: ","text":"This is a comment."}`), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.EqualError(t, f.AddComment("Sheet1", Comment{Cell: "A", Author: "Excelize", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
if assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
assert.Len(t, f.GetComments(), 2)
}
@@ -52,12 +52,12 @@ func TestDeleteComment(t *testing.T) {
t.FailNow()
}
- assert.NoError(t, f.AddComment("Sheet2", "A40", `{"author":"Excelize: ","text":"This is a comment1."}`))
- assert.NoError(t, f.AddComment("Sheet2", "A41", `{"author":"Excelize: ","text":"This is a comment2."}`))
- assert.NoError(t, f.AddComment("Sheet2", "C41", `{"author":"Excelize: ","text":"This is a comment3."}`))
- assert.NoError(t, f.AddComment("Sheet2", "C41", `{"author":"Excelize: ","text":"This is a comment3-1."}`))
- assert.NoError(t, f.AddComment("Sheet2", "C42", `{"author":"Excelize: ","text":"This is a comment4."}`))
- assert.NoError(t, f.AddComment("Sheet2", "C41", `{"author":"Excelize: ","text":"This is a comment3-2."}`))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "A40", Text: "Excelize: This is a comment1."}))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "A41", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment2."}}}))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C41", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment3."}}}))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C41", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment3-1."}}}))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C42", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment4."}}}))
+ assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C41", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment2."}}}))
assert.NoError(t, f.DeleteComment("Sheet2", "A40"))
diff --git a/excelize_test.go b/excelize_test.go
index 4c86d56..74895f5 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -946,8 +946,7 @@ func TestSetDeleteSheet(t *testing.T) {
t.FailNow()
}
f.DeleteSheet("Sheet1")
- assert.EqualError(t, f.AddComment("Sheet1", "A1", ""), "unexpected end of JSON input")
- assert.NoError(t, f.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`))
+ assert.NoError(t, f.AddComment("Sheet1", Comment{Cell: "A1", Author: "Excelize", Runs: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook4.xlsx")))
})
}
diff --git a/picture.go b/picture.go
index 05e4a51..a7c1edb 100644
--- a/picture.go
+++ b/picture.go
@@ -183,7 +183,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, opts, name, extension string, fi
drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType)
}
ws.Unlock()
- err = f.addDrawingPicture(sheet, drawingXML, cell, name, img.Width, img.Height, drawingRID, drawingHyperlinkRID, options)
+ err = f.addDrawingPicture(sheet, drawingXML, cell, name, ext, drawingRID, drawingHyperlinkRID, img, options)
if err != nil {
return err
}
@@ -263,11 +263,12 @@ func (f *File) countDrawings() (count int) {
// addDrawingPicture provides a function to add picture by given sheet,
// drawingXML, cell, file name, width, height relationship index and format
// sets.
-func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, height, rID, hyperlinkRID int, opts *pictureOptions) error {
+func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID, hyperlinkRID int, img image.Config, opts *pictureOptions) error {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return err
}
+ width, height := img.Width, img.Height
if opts.Autofit {
width, height, col, row, err = f.drawingResize(sheet, cell, float64(width), float64(height), opts)
if err != nil {
@@ -308,6 +309,19 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
}
pic.BlipFill.Blip.R = SourceRelationship.Value
pic.BlipFill.Blip.Embed = "rId" + strconv.Itoa(rID)
+ if ext == ".svg" {
+ pic.BlipFill.Blip.ExtList = &xlsxEGOfficeArtExtensionList{
+ Ext: []xlsxCTOfficeArtExtension{
+ {
+ URI: ExtURISVG,
+ SVGBlip: xlsxCTSVGBlip{
+ XMLNSaAVG: NameSpaceDrawing2016SVG.Value,
+ Embed: pic.BlipFill.Blip.Embed,
+ },
+ },
+ },
+ }
+ }
pic.SpPr.PrstGeom.Prst = "rect"
twoCellAnchor.Pic = &pic
@@ -362,7 +376,10 @@ func (f *File) addMedia(file []byte, ext string) string {
// setContentTypePartImageExtensions provides a function to set the content
// type for relationship parts and the Main Document part.
func (f *File) setContentTypePartImageExtensions() {
- imageTypes := map[string]string{"jpeg": "image/", "png": "image/", "gif": "image/", "tiff": "image/", "emf": "image/x-", "wmf": "image/x-", "emz": "image/x-", "wmz": "image/x-"}
+ imageTypes := map[string]string{
+ "jpeg": "image/", "png": "image/", "gif": "image/", "svg": "image/", "tiff": "image/",
+ "emf": "image/x-", "wmf": "image/x-", "emz": "image/x-", "wmz": "image/x-",
+ }
content := f.contentTypesReader()
content.Lock()
defer content.Unlock()
diff --git a/picture_test.go b/picture_test.go
index e90de20..c34780f 100644
--- a/picture_test.go
+++ b/picture_test.go
@@ -90,10 +90,12 @@ func TestAddPictureErrors(t *testing.T) {
image.RegisterFormat("wmf", "", decode, decodeConfig)
image.RegisterFormat("emz", "", decode, decodeConfig)
image.RegisterFormat("wmz", "", decode, decodeConfig)
+ image.RegisterFormat("svg", "", decode, decodeConfig)
assert.NoError(t, f.AddPicture("Sheet1", "Q1", filepath.Join("test", "images", "excel.emf"), ""))
assert.NoError(t, f.AddPicture("Sheet1", "Q7", filepath.Join("test", "images", "excel.wmf"), ""))
assert.NoError(t, f.AddPicture("Sheet1", "Q13", filepath.Join("test", "images", "excel.emz"), ""))
assert.NoError(t, f.AddPicture("Sheet1", "Q19", filepath.Join("test", "images", "excel.wmz"), ""))
+ assert.NoError(t, f.AddPicture("Sheet1", "Q25", "excelize.svg", `{"x_scale": 2.1}`))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPicture2.xlsx")))
assert.NoError(t, f.Close())
}
@@ -175,7 +177,7 @@ func TestGetPicture(t *testing.T) {
func TestAddDrawingPicture(t *testing.T) {
// Test addDrawingPicture with illegal cell reference.
f := NewFile()
- assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", 0, 0, 0, 0, nil), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+ assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", "", 0, 0, image.Config{}, nil), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
}
func TestAddPictureFromBytes(t *testing.T) {
diff --git a/xmlComments.go b/xmlComments.go
index 731f416..7b67e67 100644
--- a/xmlComments.go
+++ b/xmlComments.go
@@ -72,16 +72,11 @@ type xlsxPhoneticRun struct {
T string `xml:"t"`
}
-// commentOptions directly maps the format settings of the comment.
-type commentOptions struct {
- Author string `json:"author"`
- Text string `json:"text"`
-}
-
// Comment directly maps the comment information.
type Comment struct {
- Author string `json:"author"`
- AuthorID int `json:"author_id"`
- Ref string `json:"ref"`
- Text string `json:"text"`
+ Author string `json:"author"`
+ AuthorID int `json:"author_id"`
+ Cell string `json:"cell"`
+ Text string `json:"string"`
+ Runs []RichTextRun `json:"runs"`
}
diff --git a/xmlDrawing.go b/xmlDrawing.go
index dc48ccc..56ddc0e 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -29,6 +29,7 @@ var (
NameSpaceDrawingML = xml.Attr{Name: xml.Name{Local: "a", Space: "xmlns"}, Value: "http://schemas.openxmlformats.org/drawingml/2006/main"}
NameSpaceDrawingMLChart = xml.Attr{Name: xml.Name{Local: "c", Space: "xmlns"}, Value: "http://schemas.openxmlformats.org/drawingml/2006/chart"}
NameSpaceDrawingMLSpreadSheet = xml.Attr{Name: xml.Name{Local: "xdr", Space: "xmlns"}, Value: "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"}
+ NameSpaceDrawing2016SVG = xml.Attr{Name: xml.Name{Local: "asvg", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/drawing/2016/SVG/main"}
NameSpaceSpreadSheetX15 = xml.Attr{Name: xml.Name{Local: "x15", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"}
NameSpaceSpreadSheetExcel2006Main = xml.Attr{Name: xml.Name{Local: "xne", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/excel/2006/main"}
NameSpaceMacExcel2008Main = xml.Attr{Name: xml.Name{Local: "mx", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/mac/excel/2008/main"}
@@ -95,6 +96,7 @@ const (
ExtURITimelineRefs = "{7E03D99C-DC04-49d9-9315-930204A7B6E9}"
ExtURIDrawingBlip = "{28A0092B-C50C-407E-A947-70E740481C1C}"
ExtURIMacExcelMX = "{64002731-A6B0-56B0-2670-7721B7C09600}"
+ ExtURISVG = "{96DAC541-7B7A-43D3-8B79-37D633B846F1}"
)
// Excel specifications and limits
@@ -163,7 +165,11 @@ var IndexedColorMapping = []string{
}
// supportedImageTypes defined supported image types.
-var supportedImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png", ".tif": ".tiff", ".tiff": ".tiff", ".emf": ".emf", ".wmf": ".wmf", ".emz": ".emz", ".wmz": ".wmz"}
+var supportedImageTypes = map[string]string{
+ ".emf": ".emf", ".emz": ".emz", ".gif": ".gif", ".jpeg": ".jpeg",
+ ".jpg": ".jpeg", ".png": ".png", ".svg": ".svg", ".tif": ".tiff",
+ ".tiff": ".tiff", ".wmf": ".wmf", ".wmz": ".wmz",
+}
// supportedContentTypes defined supported file format types.
var supportedContentTypes = map[string]string{
@@ -231,9 +237,10 @@ type xlsxPicLocks struct {
// xlsxBlip element specifies the existence of an image (binary large image or
// picture) and contains a reference to the image data.
type xlsxBlip struct {
- Embed string `xml:"r:embed,attr"`
- Cstate string `xml:"cstate,attr,omitempty"`
- R string `xml:"xmlns:r,attr"`
+ Embed string `xml:"r:embed,attr"`
+ Cstate string `xml:"cstate,attr,omitempty"`
+ R string `xml:"xmlns:r,attr"`
+ ExtList *xlsxEGOfficeArtExtensionList `xml:"a:extLst"`
}
// xlsxStretch directly maps the stretch element. This element specifies that a
@@ -293,6 +300,28 @@ type xlsxNvPicPr struct {
CNvPicPr xlsxCNvPicPr `xml:"xdr:cNvPicPr"`
}
+// xlsxCTSVGBlip specifies a graphic element in Scalable Vector Graphics (SVG)
+// format.
+type xlsxCTSVGBlip struct {
+ XMLNSaAVG string `xml:"xmlns:asvg,attr"`
+ Embed string `xml:"r:embed,attr"`
+ Link string `xml:"r:link,attr,omitempty"`
+}
+
+// xlsxCTOfficeArtExtension used for future extensibility and is seen elsewhere
+// throughout the drawing area.
+type xlsxCTOfficeArtExtension struct {
+ XMLName xml.Name `xml:"a:ext"`
+ URI string `xml:"uri,attr"`
+ SVGBlip xlsxCTSVGBlip `xml:"asvg:svgBlip"`
+}
+
+// xlsxEGOfficeArtExtensionList used for future extensibility and is seen
+// elsewhere throughout the drawing area.
+type xlsxEGOfficeArtExtensionList struct {
+ Ext []xlsxCTOfficeArtExtension `xml:"ext"`
+}
+
// xlsxBlipFill directly maps the blipFill (Picture Fill). This element
// specifies the kind of picture fill that the picture object has. Because a
// picture has a picture fill already by default, it is possible to have two
diff --git a/xmlSharedStrings.go b/xmlSharedStrings.go
index 3249eca..7dac544 100644
--- a/xmlSharedStrings.go
+++ b/xmlSharedStrings.go
@@ -83,6 +83,6 @@ type xlsxRPr struct {
// RichTextRun directly maps the settings of the rich text run.
type RichTextRun struct {
- Font *Font
- Text string
+ Font *Font `json:"font"`
+ Text string `json:"text"`
}