summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2018-07-07 15:59:48 +0800
committerxuri <xuri.me@gmail.com>2018-07-07 15:59:48 +0800
commitd6468fc114217678e8bc8b4324fd6185794e0182 (patch)
tree92e193d6a5c38c754c7719161af0062b46f58492
parent9cb0e9308b7e65d5a277b0c6af9fa0e8680b3658 (diff)
- Initialize theme support;
- RGBA, HSL color convert has been added; - go test updated
-rw-r--r--excelize.go2
-rw-r--r--excelize_test.go26
-rw-r--r--file.go1
-rw-r--r--hsl.go141
-rw-r--r--styles.go26
-rw-r--r--xmlTheme.go140
6 files changed, 336 insertions, 0 deletions
diff --git a/excelize.go b/excelize.go
index 0972e96..99243a7 100644
--- a/excelize.go
+++ b/excelize.go
@@ -21,6 +21,7 @@ type File struct {
Sheet map[string]*xlsxWorksheet
SheetCount int
Styles *xlsxStyleSheet
+ Theme *xlsxTheme
WorkBook *xlsxWorkbook
WorkBookRels *xlsxWorkbookRels
XLSX map[string][]byte
@@ -66,6 +67,7 @@ func OpenReader(r io.Reader) (*File, error) {
}
f.sheetMap = f.getSheetMap()
f.Styles = f.stylesReader()
+ f.Theme = f.themeReader()
return f, nil
}
diff --git a/excelize_test.go b/excelize_test.go
index aca33b4..549190c 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -2,6 +2,7 @@ package excelize
import (
"fmt"
+ "image/color"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
@@ -1145,6 +1146,31 @@ func TestOutlineLevel(t *testing.T) {
xlsx.SetColOutlineLevel("Sheet2", "B", 2)
}
+func TestThemeColor(t *testing.T) {
+ t.Log(ThemeColor("000000", -0.1))
+ t.Log(ThemeColor("000000", 0))
+ t.Log(ThemeColor("000000", 1))
+}
+
+func TestHSL(t *testing.T) {
+ var hsl HSL
+ t.Log(hsl.RGBA())
+ t.Log(hslModel(hsl))
+ t.Log(hslModel(color.Gray16{Y: uint16(1)}))
+ t.Log(HSLToRGB(0, 1, 0.4))
+ t.Log(HSLToRGB(0, 1, 0.6))
+ t.Log(hueToRGB(0, 0, -1))
+ t.Log(hueToRGB(0, 0, 2))
+ t.Log(hueToRGB(0, 0, 1.0/7))
+ t.Log(hueToRGB(0, 0, 0.4))
+ t.Log(hueToRGB(0, 0, 2.0/4))
+ t.Log(RGBToHSL(255, 255, 0))
+ t.Log(RGBToHSL(0, 255, 255))
+ t.Log(RGBToHSL(250, 100, 50))
+ t.Log(RGBToHSL(50, 100, 250))
+ t.Log(RGBToHSL(250, 50, 100))
+}
+
func trimSliceSpace(s []string) []string {
for {
if len(s) > 0 && s[len(s)-1] == "" {
diff --git a/file.go b/file.go
index 4f06d1e..2b1f1e0 100644
--- a/file.go
+++ b/file.go
@@ -36,6 +36,7 @@ func NewFile() *File {
f.WorkBookRels = f.workbookRelsReader()
f.Sheet["xl/worksheets/sheet1.xml"] = f.workSheetReader("Sheet1")
f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
+ f.Theme = f.themeReader()
return f
}
diff --git a/hsl.go b/hsl.go
new file mode 100644
index 0000000..bd868b1
--- /dev/null
+++ b/hsl.go
@@ -0,0 +1,141 @@
+/*
+Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package excelize
+
+import (
+ "image/color"
+ "math"
+)
+
+// HSLModel converts any color.Color to a HSL color.
+var HSLModel = color.ModelFunc(hslModel)
+
+// HSL represents a cylindrical coordinate of points in an RGB color model.
+//
+// Values are in the range 0 to 1.
+type HSL struct {
+ H, S, L float64
+}
+
+// RGBA returns the alpha-premultiplied red, green, blue and alpha values
+// for the HSL.
+func (c HSL) RGBA() (uint32, uint32, uint32, uint32) {
+ r, g, b := HSLToRGB(c.H, c.S, c.L)
+ return uint32(r) * 0x101, uint32(g) * 0x101, uint32(b) * 0x101, 0xffff
+}
+
+// hslModel converts a color.Color to HSL.
+func hslModel(c color.Color) color.Color {
+ if _, ok := c.(HSL); ok {
+ return c
+ }
+ r, g, b, _ := c.RGBA()
+ h, s, l := RGBToHSL(uint8(r>>8), uint8(g>>8), uint8(b>>8))
+ return HSL{h, s, l}
+}
+
+// RGBToHSL converts an RGB triple to a HSL triple.
+func RGBToHSL(r, g, b uint8) (h, s, l float64) {
+ fR := float64(r) / 255
+ fG := float64(g) / 255
+ fB := float64(b) / 255
+ max := math.Max(math.Max(fR, fG), fB)
+ min := math.Min(math.Min(fR, fG), fB)
+ l = (max + min) / 2
+ if max == min {
+ // Achromatic.
+ h, s = 0, 0
+ } else {
+ // Chromatic.
+ d := max - min
+ if l > 0.5 {
+ s = d / (2.0 - max - min)
+ } else {
+ s = d / (max + min)
+ }
+ switch max {
+ case fR:
+ h = (fG - fB) / d
+ if fG < fB {
+ h += 6
+ }
+ case fG:
+ h = (fB-fR)/d + 2
+ case fB:
+ h = (fR-fG)/d + 4
+ }
+ h /= 6
+ }
+ return
+}
+
+// HSLToRGB converts an HSL triple to a RGB triple.
+func HSLToRGB(h, s, l float64) (r, g, b uint8) {
+ var fR, fG, fB float64
+ if s == 0 {
+ fR, fG, fB = l, l, l
+ } else {
+ var q float64
+ if l < 0.5 {
+ q = l * (1 + s)
+ } else {
+ q = l + s - s*l
+ }
+ p := 2*l - q
+ fR = hueToRGB(p, q, h+1.0/3)
+ fG = hueToRGB(p, q, h)
+ fB = hueToRGB(p, q, h-1.0/3)
+ }
+ r = uint8((fR * 255) + 0.5)
+ g = uint8((fG * 255) + 0.5)
+ b = uint8((fB * 255) + 0.5)
+ return
+}
+
+// hueToRGB is a helper function for HSLToRGB.
+func hueToRGB(p, q, t float64) float64 {
+ if t < 0 {
+ t++
+ }
+ if t > 1 {
+ t--
+ }
+ if t < 1.0/6 {
+ return p + (q-p)*6*t
+ }
+ if t < 0.5 {
+ return q
+ }
+ if t < 2.0/3 {
+ return p + (q-p)*(2.0/3-t)*6
+ }
+ return p
+}
diff --git a/styles.go b/styles.go
index 32350ca..e2a1ae6 100644
--- a/styles.go
+++ b/styles.go
@@ -2723,3 +2723,29 @@ func drawConfFmtExp(p int, ct string, format *formatConditional) *xlsxCfRule {
func getPaletteColor(color string) string {
return "FF" + strings.Replace(strings.ToUpper(color), "#", "", -1)
}
+
+// themeReader provides function to get the pointer to the xl/theme/theme1.xml
+// structure after deserialization.
+func (f *File) themeReader() *xlsxTheme {
+ var theme xlsxTheme
+ _ = xml.Unmarshal([]byte(f.readXML("xl/theme/theme1.xml")), &theme)
+ return &theme
+}
+
+// ThemeColor applied the color with tint value.
+func ThemeColor(baseColor string, tint float64) string {
+ if tint == 0 {
+ return "FF" + baseColor
+ }
+ r, _ := strconv.ParseInt(baseColor[0:2], 16, 64)
+ g, _ := strconv.ParseInt(baseColor[2:4], 16, 64)
+ b, _ := strconv.ParseInt(baseColor[4:6], 16, 64)
+ h, s, l := RGBToHSL(uint8(r), uint8(g), uint8(b))
+ if tint < 0 {
+ l *= (1 + tint)
+ } else {
+ l = l*(1-tint) + (1 - (1 - tint))
+ }
+ br, bg, bb := HSLToRGB(h, s, l)
+ return fmt.Sprintf("FF%02X%02X%02X", br, bg, bb)
+}
diff --git a/xmlTheme.go b/xmlTheme.go
new file mode 100644
index 0000000..d2ab343
--- /dev/null
+++ b/xmlTheme.go
@@ -0,0 +1,140 @@
+package excelize
+
+import "encoding/xml"
+
+// xlsxTheme directly maps the theme element in the namespace
+// http://schemas.openxmlformats.org/drawingml/2006/main
+type xlsxTheme struct {
+ ThemeElements xlsxThemeElements `xml:"themeElements"`
+ ObjectDefaults xlsxObjectDefaults `xml:"objectDefaults"`
+ ExtraClrSchemeLst xlsxExtraClrSchemeLst `xml:"extraClrSchemeLst"`
+ ExtLst *xlsxExtLst `xml:"extLst"`
+}
+
+// objectDefaults element allows for the definition of default shape, line,
+// and textbox formatting properties. An application can use this information
+// to format a shape (or text) initially on insertion into a document.
+type xlsxObjectDefaults struct {
+ ObjectDefaults string `xml:",innerxml"`
+}
+
+// xlsxExtraClrSchemeLst element is a container for the list of extra color
+// schemes present in a document.
+type xlsxExtraClrSchemeLst struct {
+ ExtraClrSchemeLst string `xml:",innerxml"`
+}
+
+// xlsxThemeElements directly maps the element defines the theme formatting
+// options for the theme and is the workhorse of the theme. This is where the
+// bulk of the shared theme information is contained and used by a document.
+// This element contains the color scheme, font scheme, and format scheme
+// elements which define the different formatting aspects of what a theme
+// defines.
+type xlsxThemeElements struct {
+ ClrScheme xlsxClrScheme `xml:"clrScheme"`
+ FontScheme xlsxFontScheme `xml:"fontScheme"`
+ FmtScheme xlsxFmtScheme `xml:"fmtScheme"`
+}
+
+// xlsxClrScheme element specifies the theme color, stored in the document's
+// Theme part to which the value of this theme color shall be mapped. This
+// mapping enables multiple theme colors to be chained together.
+type xlsxClrScheme struct {
+ Name string `xml:"name,attr"`
+ Children []xlsxClrSchemeEl `xml:",any"`
+}
+
+// xlsxFontScheme element defines the font scheme within the theme. The font
+// scheme consists of a pair of major and minor fonts for which to use in a
+// document. The major font corresponds well with the heading areas of a
+// document, and the minor font corresponds well with the normal text or
+// paragraph areas.
+type xlsxFontScheme struct {
+ Name string `xml:"name,attr"`
+ MajorFont xlsxMajorFont `xml:"majorFont"`
+ MinorFont xlsxMinorFont `xml:"minorFont"`
+ ExtLst *xlsxExtLst `xml:"extLst"`
+}
+
+// xlsxMajorFont element defines the set of major fonts which are to be used
+// under different languages or locals.
+type xlsxMajorFont struct {
+ Children []xlsxFontSchemeEl `xml:",any"`
+}
+
+// xlsxMinorFont element defines the set of minor fonts that are to be used
+// under different languages or locals.
+type xlsxMinorFont struct {
+ Children []xlsxFontSchemeEl `xml:",any"`
+}
+
+// xlsxFmtScheme element contains the background fill styles, effect styles,
+// fill styles, and line styles which define the style matrix for a theme. The
+// style matrix consists of subtle, moderate, and intense fills, lines, and
+// effects. The background fills are not generally thought of to directly be
+// associated with the matrix, but do play a role in the style of the overall
+// document. Usually, a given object chooses a single line style, a single
+// fill style, and a single effect style in order to define the overall final
+// look of the object.
+type xlsxFmtScheme struct {
+ Name string `xml:"name,attr"`
+ FillStyleLst xlsxFillStyleLst `xml:"fillStyleLst"`
+ LnStyleLst xlsxLnStyleLst `xml:"lnStyleLst"`
+ EffectStyleLst xlsxEffectStyleLst `xml:"effectStyleLst"`
+ BgFillStyleLst xlsxBgFillStyleLst `xml:"bgFillStyleLst"`
+}
+
+// xlsxFillStyleLst element defines a set of three fill styles that are used
+// within a theme. The three fill styles are arranged in order from subtle to
+// moderate to intense.
+type xlsxFillStyleLst struct {
+ FillStyleLst string `xml:",innerxml"`
+}
+
+// xlsxLnStyleLst element defines a list of three line styles for use within a
+// theme. The three line styles are arranged in order from subtle to moderate
+// to intense versions of lines. This list makes up part of the style matrix.
+type xlsxLnStyleLst struct {
+ LnStyleLst string `xml:",innerxml"`
+}
+
+// xlsxEffectStyleLst element defines a set of three effect styles that create
+// the effect style list for a theme. The effect styles are arranged in order
+// of subtle to moderate to intense.
+type xlsxEffectStyleLst struct {
+ EffectStyleLst string `xml:",innerxml"`
+}
+
+// xlsxBgFillStyleLst element defines a list of background fills that are
+// used within a theme. The background fills consist of three fills, arranged
+// in order from subtle to moderate to intense.
+type xlsxBgFillStyleLst struct {
+ BgFillStyleLst string `xml:",innerxml"`
+}
+
+// xlsxClrScheme maps to children of the clrScheme element in the namespace
+// http://schemas.openxmlformats.org/drawingml/2006/main - currently I have
+// not checked it for completeness - it does as much as I need.
+type xlsxClrSchemeEl struct {
+ XMLName xml.Name
+ SysClr *xlsxSysClr `xml:"sysClr"`
+ SrgbClr *attrValString `xml:"srgbClr"`
+}
+
+// xlsxFontSchemeEl directly maps the major and minor font of the style's font
+// scheme.
+type xlsxFontSchemeEl struct {
+ XMLName xml.Name
+ Script string `xml:"script,attr,omitempty"`
+ Typeface string `xml:"typeface,attr"`
+ Panose string `xml:"panose,attr,omitempty"`
+ PitchFamily string `xml:"pitchFamily,attr,omitempty"`
+ Charset string `xml:"charset,attr,omitempty"`
+}
+
+// xlsxSysClr element specifies a color bound to predefined operating system
+// elements.
+type xlsxSysClr struct {
+ Val string `xml:"val,attr"`
+ LastClr string `xml:"lastClr,attr"`
+}