forked from p30928647/excelize
Support to create of 17 kinds of fill variants styles
- Update the unit tests - Update the `SetHeaderFooter` function parameters name - Update document for the `SetDocProps` and `SetCellHyperLink` functions
This commit is contained in:
parent
be36b09c8a
commit
85e0b6c56e
2
cell.go
2
cell.go
|
@ -835,7 +835,7 @@ type HyperlinkOpts struct {
|
||||||
//
|
//
|
||||||
// display, tooltip := "https://github.com/xuri/excelize", "Excelize on GitHub"
|
// display, tooltip := "https://github.com/xuri/excelize", "Excelize on GitHub"
|
||||||
// if err := f.SetCellHyperLink("Sheet1", "A3",
|
// if err := f.SetCellHyperLink("Sheet1", "A3",
|
||||||
// "https://github.com/xuri/excelize", "External", excelize.HyperlinkOpts{
|
// display, "External", excelize.HyperlinkOpts{
|
||||||
// Display: &display,
|
// Display: &display,
|
||||||
// Tooltip: &tooltip,
|
// Tooltip: &tooltip,
|
||||||
// }); err != nil {
|
// }); err != nil {
|
||||||
|
|
32
docProps.go
32
docProps.go
|
@ -120,39 +120,45 @@ func (f *File) GetAppProps() (ret *AppProperties, err error) {
|
||||||
// properties that can be set are:
|
// properties that can be set are:
|
||||||
//
|
//
|
||||||
// Property | Description
|
// Property | Description
|
||||||
// ----------------+-----------------------------------------------------------------------------
|
// ----------------+-----------------------------------------------------------
|
||||||
// Title | The name given to the resource.
|
// Title | The name given to the resource.
|
||||||
// |
|
// |
|
||||||
// Subject | The topic of the content of the resource.
|
// Subject | The topic of the content of the resource.
|
||||||
// |
|
// |
|
||||||
// Creator | An entity primarily responsible for making the content of the resource.
|
// Creator | An entity primarily responsible for making the content of
|
||||||
|
// | the resource.
|
||||||
// |
|
// |
|
||||||
// Keywords | A delimited set of keywords to support searching and indexing. This is
|
// Keywords | A delimited set of keywords to support searching and
|
||||||
// | typically a list of terms that are not available elsewhere in the properties.
|
// | indexing. This is typically a list of terms that are not
|
||||||
|
// | available elsewhere in the properties.
|
||||||
// |
|
// |
|
||||||
// Description | An explanation of the content of the resource.
|
// Description | An explanation of the content of the resource.
|
||||||
// |
|
// |
|
||||||
// LastModifiedBy | The user who performed the last modification. The identification is
|
// LastModifiedBy | The user who performed the last modification. The
|
||||||
// | environment-specific.
|
// | identification is environment-specific.
|
||||||
// |
|
// |
|
||||||
// Language | The language of the intellectual content of the resource.
|
// Language | The language of the intellectual content of the resource.
|
||||||
// |
|
// |
|
||||||
// Identifier | An unambiguous reference to the resource within a given context.
|
// Identifier | An unambiguous reference to the resource within a given
|
||||||
|
// | context.
|
||||||
// |
|
// |
|
||||||
// Revision | The topic of the content of the resource.
|
// Revision | The topic of the content of the resource.
|
||||||
// |
|
// |
|
||||||
// ContentStatus | The status of the content. For example: Values might include "Draft",
|
// ContentStatus | The status of the content. For example: Values might
|
||||||
// | "Reviewed" and "Final"
|
// | include "Draft", "Reviewed" and "Final"
|
||||||
// |
|
// |
|
||||||
// Category | A categorization of the content of this package.
|
// Category | A categorization of the content of this package.
|
||||||
// |
|
// |
|
||||||
// Version | The version number. This value is set by the user or by the application.
|
// Version | The version number. This value is set by the user or by
|
||||||
|
// | the application.
|
||||||
// |
|
// |
|
||||||
// Modified | The created time of the content of the resource which
|
// Created | The created time of the content of the resource which
|
||||||
// | represent in ISO 8601 UTC format, for example "2019-06-04T22:00:10Z".
|
// | represent in ISO 8601 UTC format, for example
|
||||||
|
// | "2019-06-04T22:00:10Z".
|
||||||
// |
|
// |
|
||||||
// Modified | The modified time of the content of the resource which
|
// Modified | The modified time of the content of the resource which
|
||||||
// | represent in ISO 8601 UTC format, for example "2019-06-04T22:00:10Z".
|
// | represent in ISO 8601 UTC format, for example
|
||||||
|
// | "2019-06-04T22:00:10Z".
|
||||||
// |
|
// |
|
||||||
//
|
//
|
||||||
// For example:
|
// For example:
|
||||||
|
|
26
sheet.go
26
sheet.go
|
@ -1183,17 +1183,17 @@ func attrValToBool(name string, attrs []xml.Attr) (val bool, err error) {
|
||||||
// that same page
|
// that same page
|
||||||
//
|
//
|
||||||
// - No footer on the first page
|
// - No footer on the first page
|
||||||
func (f *File) SetHeaderFooter(sheet string, settings *HeaderFooterOptions) error {
|
func (f *File) SetHeaderFooter(sheet string, opts *HeaderFooterOptions) error {
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if settings == nil {
|
if opts == nil {
|
||||||
ws.HeaderFooter = nil
|
ws.HeaderFooter = nil
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
v := reflect.ValueOf(*settings)
|
v := reflect.ValueOf(*opts)
|
||||||
// Check 6 string type fields: OddHeader, OddFooter, EvenHeader, EvenFooter,
|
// Check 6 string type fields: OddHeader, OddFooter, EvenHeader, EvenFooter,
|
||||||
// FirstFooter, FirstHeader
|
// FirstFooter, FirstHeader
|
||||||
for i := 4; i < v.NumField()-1; i++ {
|
for i := 4; i < v.NumField()-1; i++ {
|
||||||
|
@ -1202,16 +1202,16 @@ func (f *File) SetHeaderFooter(sheet string, settings *HeaderFooterOptions) erro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws.HeaderFooter = &xlsxHeaderFooter{
|
ws.HeaderFooter = &xlsxHeaderFooter{
|
||||||
AlignWithMargins: settings.AlignWithMargins,
|
AlignWithMargins: opts.AlignWithMargins,
|
||||||
DifferentFirst: settings.DifferentFirst,
|
DifferentFirst: opts.DifferentFirst,
|
||||||
DifferentOddEven: settings.DifferentOddEven,
|
DifferentOddEven: opts.DifferentOddEven,
|
||||||
ScaleWithDoc: settings.ScaleWithDoc,
|
ScaleWithDoc: opts.ScaleWithDoc,
|
||||||
OddHeader: settings.OddHeader,
|
OddHeader: opts.OddHeader,
|
||||||
OddFooter: settings.OddFooter,
|
OddFooter: opts.OddFooter,
|
||||||
EvenHeader: settings.EvenHeader,
|
EvenHeader: opts.EvenHeader,
|
||||||
EvenFooter: settings.EvenFooter,
|
EvenFooter: opts.EvenFooter,
|
||||||
FirstFooter: settings.FirstFooter,
|
FirstFooter: opts.FirstFooter,
|
||||||
FirstHeader: settings.FirstHeader,
|
FirstHeader: opts.FirstHeader,
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
57
styles.go
57
styles.go
|
@ -1145,9 +1145,9 @@ func parseFormatStyleSet(style *Style) (*Style, error) {
|
||||||
//
|
//
|
||||||
// Index | Style | Index | Style
|
// Index | Style | Index | Style
|
||||||
// -------+-----------------+-------+-----------------
|
// -------+-----------------+-------+-----------------
|
||||||
// 0 | Horizontal | 3 | Diagonal down
|
// 0-2 | Horizontal | 9-11 | Diagonal down
|
||||||
// 1 | Vertical | 4 | From corner
|
// 3-5 | Vertical | 12-15 | From corner
|
||||||
// 2 | Diagonal Up | 5 | From center
|
// 6-8 | Diagonal Up | 16 | From center
|
||||||
//
|
//
|
||||||
// The following table shows the pattern styles used in 'Fill.Pattern' supported
|
// The following table shows the pattern styles used in 'Fill.Pattern' supported
|
||||||
// by excelize index number:
|
// by excelize index number:
|
||||||
|
@ -2459,41 +2459,38 @@ func newFills(style *Style, fg bool) *xlsxFill {
|
||||||
"gray125",
|
"gray125",
|
||||||
"gray0625",
|
"gray0625",
|
||||||
}
|
}
|
||||||
|
variants := []xlsxGradientFill{
|
||||||
variants := []float64{
|
{Degree: 90, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
90,
|
{Degree: 270, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
0,
|
{Degree: 90, Stop: []*xlsxGradientFillStop{{}, {Position: 0.5}, {Position: 1}}},
|
||||||
45,
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
135,
|
{Degree: 180, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 0.5}, {Position: 1}}},
|
||||||
|
{Degree: 45, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
|
{Degree: 255, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
|
{Degree: 45, Stop: []*xlsxGradientFillStop{{}, {Position: 0.5}, {Position: 1}}},
|
||||||
|
{Degree: 135, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
|
{Degree: 315, Stop: []*xlsxGradientFillStop{{}, {Position: 1}}},
|
||||||
|
{Degree: 135, Stop: []*xlsxGradientFillStop{{}, {Position: 0.5}, {Position: 1}}},
|
||||||
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 1}}, Type: "path"},
|
||||||
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 1}}, Type: "path", Left: 1, Right: 1},
|
||||||
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 1}}, Type: "path", Bottom: 1, Top: 1},
|
||||||
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 1}}, Type: "path", Bottom: 1, Left: 1, Right: 1, Top: 1},
|
||||||
|
{Stop: []*xlsxGradientFillStop{{}, {Position: 1}}, Type: "path", Bottom: 0.5, Left: 0.5, Right: 0.5, Top: 0.5},
|
||||||
}
|
}
|
||||||
|
|
||||||
var fill xlsxFill
|
var fill xlsxFill
|
||||||
switch style.Fill.Type {
|
switch style.Fill.Type {
|
||||||
case "gradient":
|
case "gradient":
|
||||||
if len(style.Fill.Color) != 2 {
|
if len(style.Fill.Color) != 2 || style.Fill.Shading < 0 || style.Fill.Shading > 16 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
var gradient xlsxGradientFill
|
gradient := variants[style.Fill.Shading]
|
||||||
switch style.Fill.Shading {
|
gradient.Stop[0].Color.RGB = getPaletteColor(style.Fill.Color[0])
|
||||||
case 0, 1, 2, 3:
|
gradient.Stop[1].Color.RGB = getPaletteColor(style.Fill.Color[1])
|
||||||
gradient.Degree = variants[style.Fill.Shading]
|
if len(gradient.Stop) == 3 {
|
||||||
case 4:
|
gradient.Stop[2].Color.RGB = getPaletteColor(style.Fill.Color[0])
|
||||||
gradient.Type = "path"
|
|
||||||
case 5:
|
|
||||||
gradient.Type = "path"
|
|
||||||
gradient.Bottom = 0.5
|
|
||||||
gradient.Left = 0.5
|
|
||||||
gradient.Right = 0.5
|
|
||||||
gradient.Top = 0.5
|
|
||||||
}
|
}
|
||||||
var stops []*xlsxGradientFillStop
|
|
||||||
for index, color := range style.Fill.Color {
|
|
||||||
var stop xlsxGradientFillStop
|
|
||||||
stop.Position = float64(index)
|
|
||||||
stop.Color.RGB = getPaletteColor(color)
|
|
||||||
stops = append(stops, &stop)
|
|
||||||
}
|
|
||||||
gradient.Stop = stops
|
|
||||||
fill.GradientFill = &gradient
|
fill.GradientFill = &gradient
|
||||||
case "pattern":
|
case "pattern":
|
||||||
if style.Fill.Pattern > 18 || style.Fill.Pattern < 0 {
|
if style.Fill.Pattern > 18 || style.Fill.Pattern < 0 {
|
||||||
|
|
|
@ -223,6 +223,13 @@ func TestUnsetConditionalFormat(t *testing.T) {
|
||||||
|
|
||||||
func TestNewStyle(t *testing.T) {
|
func TestNewStyle(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
|
for i := 0; i < 18; i++ {
|
||||||
|
_, err := f.NewStyle(&Style{
|
||||||
|
Fill: Fill{Type: "gradient", Color: []string{"#FFFFFF", "#4E71BE"}, Shading: i},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
f = NewFile()
|
||||||
styleID, err := f.NewStyle(&Style{Font: &Font{Bold: true, Italic: true, Family: "Times New Roman", Size: 36, Color: "#777777"}})
|
styleID, err := f.NewStyle(&Style{Font: &Font{Bold: true, Italic: true, Family: "Times New Roman", Size: 36, Color: "#777777"}})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
styles, err := f.stylesReader()
|
styles, err := f.stylesReader()
|
||||||
|
|
Loading…
Reference in New Issue