浏览代码

- Initialize theme support;
- RGBA, HSL color convert has been added;
- go test updated

xuri 7 年之前
父节点
当前提交
d6468fc114
共有 6 个文件被更改,包括 336 次插入0 次删除
  1. 2 0
      excelize.go
  2. 26 0
      excelize_test.go
  3. 1 0
      file.go
  4. 141 0
      hsl.go
  5. 26 0
      styles.go
  6. 140 0
      xmlTheme.go

+ 2 - 0
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
 }
 

+ 26 - 0
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] == "" {

+ 1 - 0
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
 }
 

+ 141 - 0
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
+}

+ 26 - 0
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)
+}

+ 140 - 0
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"`
+}