|
@@ -9,8 +9,10 @@ package xlsx
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"encoding/xml"
|
|
"encoding/xml"
|
|
|
|
|
+ "fmt"
|
|
|
"strconv"
|
|
"strconv"
|
|
|
"strings"
|
|
"strings"
|
|
|
|
|
+ "sync"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// xlsxStyle directly maps the styleSheet element in the namespace
|
|
// xlsxStyle directly maps the styleSheet element in the namespace
|
|
@@ -26,6 +28,312 @@ type xlsxStyleSheet struct {
|
|
|
CellStyleXfs xlsxCellStyleXfs `xml:"cellStyleXfs,omitempty"`
|
|
CellStyleXfs xlsxCellStyleXfs `xml:"cellStyleXfs,omitempty"`
|
|
|
CellXfs xlsxCellXfs `xml:"cellXfs,omitempty"`
|
|
CellXfs xlsxCellXfs `xml:"cellXfs,omitempty"`
|
|
|
NumFmts xlsxNumFmts `xml:"numFmts,omitempty"`
|
|
NumFmts xlsxNumFmts `xml:"numFmts,omitempty"`
|
|
|
|
|
+
|
|
|
|
|
+ styleCache map[int]*Style // `-`
|
|
|
|
|
+ numFmtRefTable map[int]xlsxNumFmt `xml:"-"`
|
|
|
|
|
+ lock *sync.RWMutex
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func newXlsxStyleSheet() *xlsxStyleSheet {
|
|
|
|
|
+ stylesheet := new(xlsxStyleSheet)
|
|
|
|
|
+ stylesheet.styleCache = make(map[int]*Style)
|
|
|
|
|
+ stylesheet.lock = new(sync.RWMutex)
|
|
|
|
|
+ return stylesheet
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) reset() {
|
|
|
|
|
+ styles.Fonts = xlsxFonts{}
|
|
|
|
|
+ styles.Fills = xlsxFills{}
|
|
|
|
|
+ styles.Borders = xlsxBorders{}
|
|
|
|
|
+ styles.CellStyleXfs = xlsxCellStyleXfs{}
|
|
|
|
|
+ styles.CellXfs = xlsxCellXfs{}
|
|
|
|
|
+ styles.NumFmts = xlsxNumFmts{}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style *Style) {
|
|
|
|
|
+ styles.lock.RLock()
|
|
|
|
|
+ style, ok := styles.styleCache[styleIndex]
|
|
|
|
|
+ styles.lock.RUnlock()
|
|
|
|
|
+ if ok {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ var styleXf xlsxXf
|
|
|
|
|
+ style = &Style{}
|
|
|
|
|
+ style.Border = Border{}
|
|
|
|
|
+ style.Fill = Fill{}
|
|
|
|
|
+ style.Font = Font{}
|
|
|
|
|
+
|
|
|
|
|
+ xfCount := styles.CellXfs.Count
|
|
|
|
|
+ if styleIndex > -1 && xfCount > 0 && styleIndex <= xfCount {
|
|
|
|
|
+ xf := styles.CellXfs.Xf[styleIndex]
|
|
|
|
|
+
|
|
|
|
|
+ // Google docs can produce output that has fewer
|
|
|
|
|
+ // CellStyleXfs than CellXfs - this copes with that.
|
|
|
|
|
+ if styleIndex < styles.CellStyleXfs.Count {
|
|
|
|
|
+ styleXf = styles.CellStyleXfs.Xf[styleIndex]
|
|
|
|
|
+ } else {
|
|
|
|
|
+ styleXf = xlsxXf{}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ style.ApplyBorder = xf.ApplyBorder || styleXf.ApplyBorder
|
|
|
|
|
+ style.ApplyFill = xf.ApplyFill || styleXf.ApplyFill
|
|
|
|
|
+ style.ApplyFont = xf.ApplyFont || styleXf.ApplyFont
|
|
|
|
|
+
|
|
|
|
|
+ if xf.BorderId > -1 && xf.BorderId < styles.Borders.Count {
|
|
|
|
|
+ var border xlsxBorder
|
|
|
|
|
+ border = styles.Borders.Border[xf.BorderId]
|
|
|
|
|
+ style.Border.Left = border.Left.Style
|
|
|
|
|
+ style.Border.Right = border.Right.Style
|
|
|
|
|
+ style.Border.Top = border.Top.Style
|
|
|
|
|
+ style.Border.Bottom = border.Bottom.Style
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if xf.FillId > -1 && xf.FillId < styles.Fills.Count {
|
|
|
|
|
+ xFill := styles.Fills.Fill[xf.FillId]
|
|
|
|
|
+ style.Fill.PatternType = xFill.PatternFill.PatternType
|
|
|
|
|
+ style.Fill.FgColor = xFill.PatternFill.FgColor.RGB
|
|
|
|
|
+ style.Fill.BgColor = xFill.PatternFill.BgColor.RGB
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if xf.FontId > -1 && xf.FontId < styles.Fonts.Count {
|
|
|
|
|
+ xfont := styles.Fonts.Font[xf.FontId]
|
|
|
|
|
+ style.Font.Size, _ = strconv.Atoi(xfont.Sz.Val)
|
|
|
|
|
+ style.Font.Name = xfont.Name.Val
|
|
|
|
|
+ style.Font.Family, _ = strconv.Atoi(xfont.Family.Val)
|
|
|
|
|
+ style.Font.Charset, _ = strconv.Atoi(xfont.Charset.Val)
|
|
|
|
|
+ }
|
|
|
|
|
+ styles.lock.Lock()
|
|
|
|
|
+ styles.styleCache[styleIndex] = style
|
|
|
|
|
+ styles.lock.Unlock()
|
|
|
|
|
+ }
|
|
|
|
|
+ return style
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Excel styles can reference number formats that are built-in, all of which
|
|
|
|
|
+// have an id less than 164. This is a possibly incomplete list comprised of as
|
|
|
|
|
+// many of them as I could find.
|
|
|
|
|
+func getBuiltinNumberFormat(numFmtId int) string {
|
|
|
|
|
+ switch numFmtId {
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ return "0"
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ return "0.00"
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ return "#,##0"
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ return "#,##0.00"
|
|
|
|
|
+ case 9:
|
|
|
|
|
+ return "0%"
|
|
|
|
|
+ case 10:
|
|
|
|
|
+ return "0.00%"
|
|
|
|
|
+ case 11:
|
|
|
|
|
+ return "0.00E+00"
|
|
|
|
|
+ case 12:
|
|
|
|
|
+ return "# ?/?"
|
|
|
|
|
+ case 13:
|
|
|
|
|
+ return "# ??/??"
|
|
|
|
|
+ case 14:
|
|
|
|
|
+ return "mm-dd-yy"
|
|
|
|
|
+ case 15:
|
|
|
|
|
+ return "d-mmm-yy"
|
|
|
|
|
+ case 16:
|
|
|
|
|
+ return "d-mmm"
|
|
|
|
|
+ case 17:
|
|
|
|
|
+ return "mmm-yy"
|
|
|
|
|
+ case 18:
|
|
|
|
|
+ return "h:mm AM/PM"
|
|
|
|
|
+ case 19:
|
|
|
|
|
+ return "h:mm:ss AM/PM"
|
|
|
|
|
+ case 20:
|
|
|
|
|
+ return "h:mm"
|
|
|
|
|
+ case 21:
|
|
|
|
|
+ return "h:mm:ss"
|
|
|
|
|
+ case 22:
|
|
|
|
|
+ return "m/d/yy h:mm"
|
|
|
|
|
+ case 37:
|
|
|
|
|
+ return "#,##0 ;(#,##0)"
|
|
|
|
|
+ case 39:
|
|
|
|
|
+ return "#,##0.00;(#,##0.00)"
|
|
|
|
|
+ case 40:
|
|
|
|
|
+ return "#,##0.00;[Red](#,##0.00)"
|
|
|
|
|
+ case 41:
|
|
|
|
|
+ return `_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)`
|
|
|
|
|
+ case 42:
|
|
|
|
|
+ return `_("$"* #,##0_);_("$* \(#,##0\);_("$"* "-"_);_(@_)`
|
|
|
|
|
+ case 43:
|
|
|
|
|
+ return `_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)`
|
|
|
|
|
+ case 44:
|
|
|
|
|
+ return `_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)`
|
|
|
|
|
+ case 45:
|
|
|
|
|
+ return "mm:ss"
|
|
|
|
|
+ case 46:
|
|
|
|
|
+ return "[h]:mm:ss"
|
|
|
|
|
+ case 47:
|
|
|
|
|
+ return "mmss.0"
|
|
|
|
|
+ case 48:
|
|
|
|
|
+ return "##0.0E+0"
|
|
|
|
|
+ case 49:
|
|
|
|
|
+ return "@"
|
|
|
|
|
+ }
|
|
|
|
|
+ return ""
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) getNumberFormat(styleIndex int) string {
|
|
|
|
|
+ if styles.CellXfs.Xf == nil || styles.numFmtRefTable == nil {
|
|
|
|
|
+ return ""
|
|
|
|
|
+ }
|
|
|
|
|
+ var numberFormat string = ""
|
|
|
|
|
+ if styleIndex > -1 && styleIndex <= styles.CellXfs.Count {
|
|
|
|
|
+ xf := styles.CellXfs.Xf[styleIndex]
|
|
|
|
|
+ if xf.NumFmtId < 164 {
|
|
|
|
|
+ return getBuiltinNumberFormat(xf.NumFmtId)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ numFmt := styles.numFmtRefTable[xf.NumFmtId]
|
|
|
|
|
+ numberFormat = numFmt.FormatCode
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return strings.ToLower(numberFormat)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) addFont(xFont xlsxFont) (index int) {
|
|
|
|
|
+ var font xlsxFont
|
|
|
|
|
+ if xFont.Name.Val == "" {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+ for index, font = range styles.Fonts.Font {
|
|
|
|
|
+ if font.Equals(xFont) {
|
|
|
|
|
+ return index
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ styles.Fonts.Font = append(styles.Fonts.Font, xFont)
|
|
|
|
|
+ index = styles.Fonts.Count
|
|
|
|
|
+ styles.Fonts.Count += 1
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) addFill(xFill xlsxFill) (index int) {
|
|
|
|
|
+ var fill xlsxFill
|
|
|
|
|
+ for index, fill = range styles.Fills.Fill {
|
|
|
|
|
+ if fill.Equals(xFill) {
|
|
|
|
|
+ return index
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ styles.Fills.Fill = append(styles.Fills.Fill, xFill)
|
|
|
|
|
+ index = styles.Fills.Count
|
|
|
|
|
+ styles.Fills.Count += 1
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) addBorder(xBorder xlsxBorder) (index int) {
|
|
|
|
|
+ var border xlsxBorder
|
|
|
|
|
+ for index, border = range styles.Borders.Border {
|
|
|
|
|
+ if border.Equals(xBorder) {
|
|
|
|
|
+ return index
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ styles.Borders.Border = append(styles.Borders.Border, xBorder)
|
|
|
|
|
+ index = styles.Borders.Count
|
|
|
|
|
+ styles.Borders.Count += 1
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) addCellStyleXf(xCellStyleXf xlsxXf) (index int) {
|
|
|
|
|
+ var cellStyleXf xlsxXf
|
|
|
|
|
+ for index, cellStyleXf = range styles.CellStyleXfs.Xf {
|
|
|
|
|
+ if cellStyleXf.Equals(xCellStyleXf) {
|
|
|
|
|
+ return index
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ styles.CellStyleXfs.Xf = append(styles.CellStyleXfs.Xf, xCellStyleXf)
|
|
|
|
|
+ index = styles.CellStyleXfs.Count
|
|
|
|
|
+ styles.CellStyleXfs.Count += 1
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) addCellXf(xCellXf xlsxXf) (index int) {
|
|
|
|
|
+ var cellXf xlsxXf
|
|
|
|
|
+ for index, cellXf = range styles.CellXfs.Xf {
|
|
|
|
|
+ if cellXf.Equals(xCellXf) {
|
|
|
|
|
+ return index
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ styles.CellXfs.Xf = append(styles.CellXfs.Xf, xCellXf)
|
|
|
|
|
+ index = styles.CellXfs.Count
|
|
|
|
|
+ styles.CellXfs.Count += 1
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) addNumFmt(xNumFmt xlsxNumFmt) (index int) {
|
|
|
|
|
+ numFmt, ok := styles.numFmtRefTable[xNumFmt.NumFmtId]
|
|
|
|
|
+ if !ok {
|
|
|
|
|
+ if styles.numFmtRefTable == nil {
|
|
|
|
|
+ styles.numFmtRefTable = make(map[int]xlsxNumFmt)
|
|
|
|
|
+ }
|
|
|
|
|
+ styles.NumFmts.NumFmt = append(styles.NumFmts.NumFmt, xNumFmt)
|
|
|
|
|
+ styles.numFmtRefTable[xNumFmt.NumFmtId] = xNumFmt
|
|
|
|
|
+ index = styles.NumFmts.Count
|
|
|
|
|
+ styles.NumFmts.Count += 1
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ numFmt.FormatCode = xNumFmt.FormatCode
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (styles *xlsxStyleSheet) Marshal() (result string, err error) {
|
|
|
|
|
+ var xNumFmts string
|
|
|
|
|
+ var xfonts string
|
|
|
|
|
+ var xfills string
|
|
|
|
|
+ var xborders string
|
|
|
|
|
+ var xcellStyleXfs string
|
|
|
|
|
+ var xcellXfs string
|
|
|
|
|
+
|
|
|
|
|
+ var outputFontMap map[int]int = make(map[int]int)
|
|
|
|
|
+ var outputFillMap map[int]int = make(map[int]int)
|
|
|
|
|
+ var outputBorderMap map[int]int = make(map[int]int)
|
|
|
|
|
+
|
|
|
|
|
+ result = xml.Header
|
|
|
|
|
+ result += `<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`
|
|
|
|
|
+
|
|
|
|
|
+ xNumFmts, err = styles.NumFmts.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xNumFmts
|
|
|
|
|
+
|
|
|
|
|
+ xfonts, err = styles.Fonts.Marshal(outputFontMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xfonts
|
|
|
|
|
+
|
|
|
|
|
+ xfills, err = styles.Fills.Marshal(outputFillMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xfills
|
|
|
|
|
+
|
|
|
|
|
+ xborders, err = styles.Borders.Marshal(outputBorderMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xborders
|
|
|
|
|
+
|
|
|
|
|
+ xcellStyleXfs, err = styles.CellStyleXfs.Marshal(outputBorderMap, outputFillMap, outputFontMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xcellStyleXfs
|
|
|
|
|
+
|
|
|
|
|
+ xcellXfs, err = styles.CellXfs.Marshal(outputBorderMap, outputFillMap, outputFontMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xcellXfs
|
|
|
|
|
+
|
|
|
|
|
+ result += `</styleSheet>`
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// xlsxNumFmts directly maps the numFmts element in the namespace
|
|
// xlsxNumFmts directly maps the numFmts element in the namespace
|
|
@@ -37,13 +345,33 @@ type xlsxNumFmts struct {
|
|
|
NumFmt []xlsxNumFmt `xml:"numFmt,omitempty"`
|
|
NumFmt []xlsxNumFmt `xml:"numFmt,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (numFmts *xlsxNumFmts) Marshal() (result string, err error) {
|
|
|
|
|
+ if numFmts.Count > 0 {
|
|
|
|
|
+ result = fmt.Sprintf(`<numFmts count="%d">`, numFmts.Count)
|
|
|
|
|
+ for _, numFmt := range numFmts.NumFmt {
|
|
|
|
|
+ var xNumFmt string
|
|
|
|
|
+ xNumFmt, err = numFmt.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xNumFmt
|
|
|
|
|
+ }
|
|
|
|
|
+ result += `</numFmts>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxNumFmt directly maps the numFmt element in the namespace
|
|
// xlsxNumFmt directly maps the numFmt element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
|
// as I need.
|
|
// as I need.
|
|
|
type xlsxNumFmt struct {
|
|
type xlsxNumFmt struct {
|
|
|
- NumFmtId int `xml:"numFmtId,omitempty"`
|
|
|
|
|
- FormatCode string `xml:"formatCode,omitempty"`
|
|
|
|
|
|
|
+ NumFmtId int `xml:"numFmtId,attr,omitempty"`
|
|
|
|
|
+ FormatCode string `xml:"formatCode,attr,omitempty"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (numFmt *xlsxNumFmt) Marshal() (result string, err error) {
|
|
|
|
|
+ return fmt.Sprintf(`<numFmt numFmtId="%d" formatCode="%s"/>`, numFmt.NumFmtId, numFmt.FormatCode), nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// xlsxFonts directly maps the fonts element in the namespace
|
|
// xlsxFonts directly maps the fonts element in the namespace
|
|
@@ -51,10 +379,36 @@ type xlsxNumFmt struct {
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
|
// as I need.
|
|
// as I need.
|
|
|
type xlsxFonts struct {
|
|
type xlsxFonts struct {
|
|
|
|
|
+ XMLName xml.Name `xml:"fonts"`
|
|
|
|
|
+
|
|
|
Count int `xml:"count,attr"`
|
|
Count int `xml:"count,attr"`
|
|
|
Font []xlsxFont `xml:"font,omitempty"`
|
|
Font []xlsxFont `xml:"font,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (fonts *xlsxFonts) Marshal(outputFontMap map[int]int) (result string, err error) {
|
|
|
|
|
+ emittedCount := 0
|
|
|
|
|
+ subparts := ""
|
|
|
|
|
+
|
|
|
|
|
+ for i, font := range fonts.Font {
|
|
|
|
|
+ var xfont string
|
|
|
|
|
+ xfont, err = font.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if xfont != "" {
|
|
|
|
|
+ outputFontMap[i] = emittedCount
|
|
|
|
|
+ emittedCount += 1
|
|
|
|
|
+ subparts += xfont
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if emittedCount > 0 {
|
|
|
|
|
+ result = fmt.Sprintf(`<fonts count="%d">`, fonts.Count)
|
|
|
|
|
+ result += subparts
|
|
|
|
|
+ result += `</fonts>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxFont directly maps the font element in the namespace
|
|
// xlsxFont directly maps the font element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -67,6 +421,31 @@ type xlsxFont struct {
|
|
|
Color xlsxColor `xml:"color,omitempty"`
|
|
Color xlsxColor `xml:"color,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (font *xlsxFont) Equals(other xlsxFont) bool {
|
|
|
|
|
+ return font.Sz.Equals(other.Sz) && font.Name.Equals(other.Name) && font.Family.Equals(other.Family) && font.Charset.Equals(other.Charset) && font.Color.Equals(other.Color)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (font *xlsxFont) Marshal() (result string, err error) {
|
|
|
|
|
+ result = `<font>`
|
|
|
|
|
+ if font.Sz.Val != "" {
|
|
|
|
|
+ result += fmt.Sprintf(`<sz val="%s"/>`, font.Sz.Val)
|
|
|
|
|
+ }
|
|
|
|
|
+ if font.Name.Val != "" {
|
|
|
|
|
+ result += fmt.Sprintf(`<name val="%s"/>`, font.Name.Val)
|
|
|
|
|
+ }
|
|
|
|
|
+ if font.Family.Val != "" {
|
|
|
|
|
+ result += fmt.Sprintf(`<family val="%s"/>`, font.Family.Val)
|
|
|
|
|
+ }
|
|
|
|
|
+ if font.Charset.Val != "" {
|
|
|
|
|
+ result += fmt.Sprintf(`<charset val="%s"/>`, font.Charset.Val)
|
|
|
|
|
+ }
|
|
|
|
|
+ if font.Color.RGB != "" {
|
|
|
|
|
+ result += fmt.Sprintf(`<color rgb="%s"/>`, font.Color.RGB)
|
|
|
|
|
+ }
|
|
|
|
|
+ result += `</font>`
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxVal directly maps the val element in the namespace
|
|
// xlsxVal directly maps the val element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -75,6 +454,10 @@ type xlsxVal struct {
|
|
|
Val string `xml:"val,attr,omitempty"`
|
|
Val string `xml:"val,attr,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (val *xlsxVal) Equals(other xlsxVal) bool {
|
|
|
|
|
+ return val.Val == other.Val
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxFills directly maps the fills element in the namespace
|
|
// xlsxFills directly maps the fills element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -84,6 +467,29 @@ type xlsxFills struct {
|
|
|
Fill []xlsxFill `xml:"fill,omitempty"`
|
|
Fill []xlsxFill `xml:"fill,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (fills *xlsxFills) Marshal(outputFillMap map[int]int) (result string, err error) {
|
|
|
|
|
+ emittedCount := 0
|
|
|
|
|
+ subparts := ""
|
|
|
|
|
+ for i, fill := range fills.Fill {
|
|
|
|
|
+ var xfill string
|
|
|
|
|
+ xfill, err = fill.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if xfill != "" {
|
|
|
|
|
+ outputFillMap[i] = emittedCount
|
|
|
|
|
+ emittedCount += 1
|
|
|
|
|
+ subparts += xfill
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if emittedCount > 0 {
|
|
|
|
|
+ result = fmt.Sprintf(`<fills count="%d">`, emittedCount)
|
|
|
|
|
+ result += subparts
|
|
|
|
|
+ result += `</fills>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxFill directly maps the fill element in the namespace
|
|
// xlsxFill directly maps the fill element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -92,6 +498,25 @@ type xlsxFill struct {
|
|
|
PatternFill xlsxPatternFill `xml:"patternFill,omitempty"`
|
|
PatternFill xlsxPatternFill `xml:"patternFill,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (fill *xlsxFill) Equals(other xlsxFill) bool {
|
|
|
|
|
+ return fill.PatternFill.Equals(other.PatternFill)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (fill *xlsxFill) Marshal() (result string, err error) {
|
|
|
|
|
+ if fill.PatternFill.PatternType != "" {
|
|
|
|
|
+ var xpatternFill string
|
|
|
|
|
+ result = `<fill>`
|
|
|
|
|
+
|
|
|
|
|
+ xpatternFill, err = fill.PatternFill.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xpatternFill
|
|
|
|
|
+ result += `</fill>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxPatternFill directly maps the patternFill element in the namespace
|
|
// xlsxPatternFill directly maps the patternFill element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -102,6 +527,31 @@ type xlsxPatternFill struct {
|
|
|
BgColor xlsxColor `xml:"bgColor,omitempty"`
|
|
BgColor xlsxColor `xml:"bgColor,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (patternFill *xlsxPatternFill) Equals(other xlsxPatternFill) bool {
|
|
|
|
|
+ return patternFill.PatternType == other.PatternType && patternFill.FgColor.Equals(other.FgColor) && patternFill.BgColor.Equals(other.BgColor)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (patternFill *xlsxPatternFill) Marshal() (result string, err error) {
|
|
|
|
|
+ result = fmt.Sprintf(`<patternFill patternType="%s"`, patternFill.PatternType)
|
|
|
|
|
+ ending := `/>`
|
|
|
|
|
+ terminator := ""
|
|
|
|
|
+ subparts := ""
|
|
|
|
|
+ if patternFill.FgColor.RGB != "" {
|
|
|
|
|
+ ending = `>`
|
|
|
|
|
+ terminator = "</patternFill>"
|
|
|
|
|
+ subparts += fmt.Sprintf(`<fgColor rgb="%s"/>`, patternFill.FgColor.RGB)
|
|
|
|
|
+ }
|
|
|
|
|
+ if patternFill.BgColor.RGB != "" {
|
|
|
|
|
+ ending = `>`
|
|
|
|
|
+ terminator = "</patternFill>"
|
|
|
|
|
+ subparts += fmt.Sprintf(`<bgColor rgb="%s"/>`, patternFill.BgColor.RGB)
|
|
|
|
|
+ }
|
|
|
|
|
+ result += ending
|
|
|
|
|
+ result += subparts
|
|
|
|
|
+ result += terminator
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxColor is a common mapping used for both the fgColor and bgColor
|
|
// xlsxColor is a common mapping used for both the fgColor and bgColor
|
|
|
// elements in the namespace
|
|
// elements in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
@@ -111,6 +561,10 @@ type xlsxColor struct {
|
|
|
RGB string `xml:"rgb,attr,omitempty"`
|
|
RGB string `xml:"rgb,attr,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (color *xlsxColor) Equals(other xlsxColor) bool {
|
|
|
|
|
+ return color.RGB == other.RGB
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxBorders directly maps the borders element in the namespace
|
|
// xlsxBorders directly maps the borders element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -120,6 +574,30 @@ type xlsxBorders struct {
|
|
|
Border []xlsxBorder `xml:"border,omitempty"`
|
|
Border []xlsxBorder `xml:"border,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (borders *xlsxBorders) Marshal(outputBorderMap map[int]int) (result string, err error) {
|
|
|
|
|
+ result = ""
|
|
|
|
|
+ emittedCount := 0
|
|
|
|
|
+ subparts := ""
|
|
|
|
|
+ for i, border := range borders.Border {
|
|
|
|
|
+ var xborder string
|
|
|
|
|
+ xborder, err = border.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if xborder != "" {
|
|
|
|
|
+ outputBorderMap[i] = emittedCount
|
|
|
|
|
+ emittedCount += 1
|
|
|
|
|
+ subparts += xborder
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if emittedCount > 0 {
|
|
|
|
|
+ result += fmt.Sprintf(`<borders count="%d">`, emittedCount)
|
|
|
|
|
+ result += subparts
|
|
|
|
|
+ result += `</borders>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxBorder directly maps the border element in the namespace
|
|
// xlsxBorder directly maps the border element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -131,6 +609,37 @@ type xlsxBorder struct {
|
|
|
Bottom xlsxLine `xml:"bottom,omitempty"`
|
|
Bottom xlsxLine `xml:"bottom,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (border *xlsxBorder) Equals(other xlsxBorder) bool {
|
|
|
|
|
+ return border.Left.Equals(other.Left) && border.Right.Equals(other.Right) && border.Top.Equals(other.Top) && border.Bottom.Equals(other.Bottom)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (border *xlsxBorder) Marshal() (result string, err error) {
|
|
|
|
|
+ emit := false
|
|
|
|
|
+ subparts := ""
|
|
|
|
|
+ if border.Left.Style != "" {
|
|
|
|
|
+ emit = true
|
|
|
|
|
+ subparts += fmt.Sprintf(`<left style="%s"/>`, border.Left.Style)
|
|
|
|
|
+ }
|
|
|
|
|
+ if border.Right.Style != "" {
|
|
|
|
|
+ emit = true
|
|
|
|
|
+ subparts += fmt.Sprintf(`<right style="%s"/>`, border.Right.Style)
|
|
|
|
|
+ }
|
|
|
|
|
+ if border.Top.Style != "" {
|
|
|
|
|
+ emit = true
|
|
|
|
|
+ subparts += fmt.Sprintf(`<top style="%s"/>`, border.Top.Style)
|
|
|
|
|
+ }
|
|
|
|
|
+ if border.Bottom.Style != "" {
|
|
|
|
|
+ emit = true
|
|
|
|
|
+ subparts += fmt.Sprintf(`<bottom style="%s"/>`, border.Bottom.Style)
|
|
|
|
|
+ }
|
|
|
|
|
+ if emit {
|
|
|
|
|
+ result += `<border>`
|
|
|
|
|
+ result += subparts
|
|
|
|
|
+ result += `</border>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxLine directly maps the line style element in the namespace
|
|
// xlsxLine directly maps the line style element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -139,6 +648,10 @@ type xlsxLine struct {
|
|
|
Style string `xml:"style,attr,omitempty"`
|
|
Style string `xml:"style,attr,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (line *xlsxLine) Equals(other xlsxLine) bool {
|
|
|
|
|
+ return line.Style == other.Style
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxCellStyleXfs directly maps the cellStyleXfs element in the
|
|
// xlsxCellStyleXfs directly maps the cellStyleXfs element in the
|
|
|
// namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
|
|
// namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
|
|
|
// - currently I have not checked it for completeness - it does as
|
|
// - currently I have not checked it for completeness - it does as
|
|
@@ -148,6 +661,22 @@ type xlsxCellStyleXfs struct {
|
|
|
Xf []xlsxXf `xml:"xf,omitempty"`
|
|
Xf []xlsxXf `xml:"xf,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (cellStyleXfs *xlsxCellStyleXfs) Marshal(outputBorderMap, outputFillMap, outputFontMap map[int]int) (result string, err error) {
|
|
|
|
|
+ if cellStyleXfs.Count > 0 {
|
|
|
|
|
+ result = fmt.Sprintf(`<cellStyleXfs count="%d">`, cellStyleXfs.Count)
|
|
|
|
|
+ for _, xf := range cellStyleXfs.Xf {
|
|
|
|
|
+ var xxf string
|
|
|
|
|
+ xxf, err = xf.Marshal(outputBorderMap, outputFillMap, outputFontMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xxf
|
|
|
|
|
+ }
|
|
|
|
|
+ result += `</cellStyleXfs>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxCellXfs directly maps the cellXfs element in the namespace
|
|
// xlsxCellXfs directly maps the cellXfs element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -157,6 +686,22 @@ type xlsxCellXfs struct {
|
|
|
Xf []xlsxXf `xml:"xf,omitempty"`
|
|
Xf []xlsxXf `xml:"xf,omitempty"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (cellXfs *xlsxCellXfs) Marshal(outputBorderMap, outputFillMap, outputFontMap map[int]int) (result string, err error) {
|
|
|
|
|
+ if cellXfs.Count > 0 {
|
|
|
|
|
+ result = fmt.Sprintf(`<cellXfs count="%d">`, cellXfs.Count)
|
|
|
|
|
+ for _, xf := range cellXfs.Xf {
|
|
|
|
|
+ var xxf string
|
|
|
|
|
+ xxf, err = xf.Marshal(outputBorderMap, outputFillMap, outputFontMap)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xxf
|
|
|
|
|
+ }
|
|
|
|
|
+ result += `</cellXfs>`
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// xlsxXf directly maps the xf element in the namespace
|
|
// xlsxXf directly maps the xf element in the namespace
|
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
|
|
// currently I have not checked it for completeness - it does as much
|
|
// currently I have not checked it for completeness - it does as much
|
|
@@ -171,7 +716,32 @@ type xlsxXf struct {
|
|
|
FillId int `xml:"fillId,attr"`
|
|
FillId int `xml:"fillId,attr"`
|
|
|
FontId int `xml:"fontId,attr"`
|
|
FontId int `xml:"fontId,attr"`
|
|
|
NumFmtId int `xml:"numFmtId,attr"`
|
|
NumFmtId int `xml:"numFmtId,attr"`
|
|
|
- alignment xlsxAlignment `xml:"alignment"`
|
|
|
|
|
|
|
+ Alignment xlsxAlignment `xml:"alignment"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (xf *xlsxXf) Equals(other xlsxXf) bool {
|
|
|
|
|
+ return xf.ApplyAlignment == other.ApplyAlignment &&
|
|
|
|
|
+ xf.ApplyBorder == other.ApplyBorder &&
|
|
|
|
|
+ xf.ApplyFont == other.ApplyFont &&
|
|
|
|
|
+ xf.ApplyFill == other.ApplyFill &&
|
|
|
|
|
+ xf.ApplyProtection == other.ApplyProtection &&
|
|
|
|
|
+ xf.BorderId == other.BorderId &&
|
|
|
|
|
+ xf.FillId == other.FillId &&
|
|
|
|
|
+ xf.FontId == other.FontId &&
|
|
|
|
|
+ xf.NumFmtId == other.NumFmtId &&
|
|
|
|
|
+ xf.Alignment.Equals(other.Alignment)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (xf *xlsxXf) Marshal(outputBorderMap, outputFillMap, outputFontMap map[int]int) (result string, err error) {
|
|
|
|
|
+ var xAlignment string
|
|
|
|
|
+ result = fmt.Sprintf(`<xf applyAlignment="%b" applyBorder="%b" applyFont="%b" applyFill="%b" applyProtection="%b" borderId="%d" fillId="%d" fontId="%d" numFmtId="%d">`, bool2Int(xf.ApplyAlignment), bool2Int(xf.ApplyBorder), bool2Int(xf.ApplyFont), bool2Int(xf.ApplyFill), bool2Int(xf.ApplyProtection), outputBorderMap[xf.BorderId], outputFillMap[xf.FillId], outputFontMap[xf.FontId], xf.NumFmtId)
|
|
|
|
|
+ xAlignment, err = xf.Alignment.Marshal()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ result += xAlignment
|
|
|
|
|
+ result += `</xf>`
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
type xlsxAlignment struct {
|
|
type xlsxAlignment struct {
|
|
@@ -183,99 +753,23 @@ type xlsxAlignment struct {
|
|
|
WrapText bool `xml:"wrapText,attr"`
|
|
WrapText bool `xml:"wrapText,attr"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (styles *xlsxStyleSheet) getStyle(styleIndex int) (style Style) {
|
|
|
|
|
- var styleXf xlsxXf
|
|
|
|
|
- style = Style{}
|
|
|
|
|
- style.Border = Border{}
|
|
|
|
|
- style.Fill = Fill{}
|
|
|
|
|
- style.Font = Font{}
|
|
|
|
|
-
|
|
|
|
|
- xfCount := styles.CellXfs.Count
|
|
|
|
|
- if styleIndex > -1 && xfCount > 0 && styleIndex <= xfCount {
|
|
|
|
|
- xf := styles.CellXfs.Xf[styleIndex]
|
|
|
|
|
-
|
|
|
|
|
- // Google docs can produce output that has fewer
|
|
|
|
|
- // CellStyleXfs than CellXfs - this copes with that.
|
|
|
|
|
- if styleIndex < styles.CellStyleXfs.Count {
|
|
|
|
|
- styleXf = styles.CellStyleXfs.Xf[styleIndex]
|
|
|
|
|
- } else {
|
|
|
|
|
- styleXf = xlsxXf{}
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- style.ApplyBorder = xf.ApplyBorder || styleXf.ApplyBorder
|
|
|
|
|
- style.ApplyFill = xf.ApplyFill || styleXf.ApplyFill
|
|
|
|
|
- style.ApplyFont = xf.ApplyFont || styleXf.ApplyFont
|
|
|
|
|
-
|
|
|
|
|
- if xf.BorderId > -1 && xf.BorderId < styles.Borders.Count {
|
|
|
|
|
- style.Border.Left = styles.Borders.Border[xf.BorderId].Left.Style
|
|
|
|
|
- style.Border.Right = styles.Borders.Border[xf.BorderId].Right.Style
|
|
|
|
|
- style.Border.Top = styles.Borders.Border[xf.BorderId].Top.Style
|
|
|
|
|
- style.Border.Bottom = styles.Borders.Border[xf.BorderId].Bottom.Style
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if xf.FillId > -1 && xf.FillId < styles.Fills.Count {
|
|
|
|
|
- xFill := styles.Fills.Fill[xf.FillId]
|
|
|
|
|
- style.Fill.PatternType = xFill.PatternFill.PatternType
|
|
|
|
|
- style.Fill.FgColor = xFill.PatternFill.FgColor.RGB
|
|
|
|
|
- style.Fill.BgColor = xFill.PatternFill.BgColor.RGB
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if xf.FontId > -1 && xf.FontId < styles.Fonts.Count {
|
|
|
|
|
- xfont := styles.Fonts.Font[xf.FontId]
|
|
|
|
|
- style.Font.Size, _ = strconv.Atoi(xfont.Sz.Val)
|
|
|
|
|
- style.Font.Name = xfont.Name.Val
|
|
|
|
|
- style.Font.Family, _ = strconv.Atoi(xfont.Family.Val)
|
|
|
|
|
- style.Font.Charset, _ = strconv.Atoi(xfont.Charset.Val)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return style
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-func (styles *xlsxStyleSheet) getNumberFormat(styleIndex int, numFmtRefTable map[int]xlsxNumFmt) string {
|
|
|
|
|
- if styles.CellXfs.Xf == nil {
|
|
|
|
|
- return ""
|
|
|
|
|
- }
|
|
|
|
|
- var numberFormat string = ""
|
|
|
|
|
- if styleIndex > -1 && styleIndex <= styles.CellXfs.Count {
|
|
|
|
|
- xf := styles.CellXfs.Xf[styleIndex]
|
|
|
|
|
- numFmt := numFmtRefTable[xf.NumFmtId]
|
|
|
|
|
- numberFormat = numFmt.FormatCode
|
|
|
|
|
- }
|
|
|
|
|
- return strings.ToLower(numberFormat)
|
|
|
|
|
|
|
+func (alignment *xlsxAlignment) Equals(other xlsxAlignment) bool {
|
|
|
|
|
+ return alignment.Horizontal == other.Horizontal &&
|
|
|
|
|
+ alignment.Indent == other.Indent &&
|
|
|
|
|
+ alignment.ShrinkToFit == other.ShrinkToFit &&
|
|
|
|
|
+ alignment.TextRotation == other.TextRotation &&
|
|
|
|
|
+ alignment.Vertical == other.Vertical &&
|
|
|
|
|
+ alignment.WrapText == other.WrapText
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (styles *xlsxStyleSheet) addFont(xFont xlsxFont) (index int) {
|
|
|
|
|
- styles.Fonts.Font = append(styles.Fonts.Font, xFont)
|
|
|
|
|
- index = styles.Fonts.Count
|
|
|
|
|
- styles.Fonts.Count += 1
|
|
|
|
|
|
|
+func (alignment *xlsxAlignment) Marshal() (result string, err error) {
|
|
|
|
|
+ result = fmt.Sprintf(`<alignment horizontal="%s" indent="%d" shrinkToFit="%b" textRotation="%d" vertical="%s" wrapText="%b"/>`, alignment.Horizontal, alignment.Indent, bool2Int(alignment.ShrinkToFit), alignment.TextRotation, alignment.Vertical, bool2Int(alignment.WrapText))
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (styles *xlsxStyleSheet) addFill(xFill xlsxFill) (index int) {
|
|
|
|
|
- styles.Fills.Fill = append(styles.Fills.Fill, xFill)
|
|
|
|
|
- index = styles.Fills.Count
|
|
|
|
|
- styles.Fills.Count += 1
|
|
|
|
|
- return
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-func (styles *xlsxStyleSheet) addBorder(xBorder xlsxBorder) (index int) {
|
|
|
|
|
- styles.Borders.Border = append(styles.Borders.Border, xBorder)
|
|
|
|
|
- index = styles.Borders.Count
|
|
|
|
|
- styles.Borders.Count += 1
|
|
|
|
|
- return
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-func (styles *xlsxStyleSheet) addCellStyleXf(xCellStyleXf xlsxXf) (index int) {
|
|
|
|
|
- styles.CellStyleXfs.Xf = append(styles.CellStyleXfs.Xf, xCellStyleXf)
|
|
|
|
|
- index = styles.CellStyleXfs.Count
|
|
|
|
|
- styles.CellStyleXfs.Count += 1
|
|
|
|
|
- return
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-func (styles *xlsxStyleSheet) addCellXf(xCellXf xlsxXf) (index int) {
|
|
|
|
|
- styles.CellXfs.Xf = append(styles.CellXfs.Xf, xCellXf)
|
|
|
|
|
- index = styles.CellXfs.Count
|
|
|
|
|
- styles.CellXfs.Count += 1
|
|
|
|
|
- return
|
|
|
|
|
|
|
+func bool2Int(b bool) int {
|
|
|
|
|
+ if b {
|
|
|
|
|
+ return 1
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0
|
|
|
}
|
|
}
|