542 changes: 416 additions & 126 deletions sheet.go

Large diffs are not rendered by default.

162 changes: 146 additions & 16 deletions sheet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,68 @@ package excelize_test

import (
"fmt"
"path/filepath"
"strings"
"testing"

"github.com/360EntSecGroup-Skylar/excelize/v2"

"github.com/mohae/deepcopy"
"github.com/stretchr/testify/assert"
)

func ExampleFile_SetPageLayout() {
xl := excelize.NewFile()
f := excelize.NewFile()

if err := xl.SetPageLayout(
if err := f.SetPageLayout(
"Sheet1",
excelize.PageLayoutOrientation(excelize.OrientationLandscape),
); err != nil {
panic(err)
}
if err := xl.SetPageLayout(
if err := f.SetPageLayout(
"Sheet1",
excelize.PageLayoutPaperSize(10),
excelize.FitToHeight(2),
excelize.FitToWidth(2),
); err != nil {
panic(err)
}
// Output:
}

func ExampleFile_GetPageLayout() {
xl := excelize.NewFile()
f := excelize.NewFile()
var (
orientation excelize.PageLayoutOrientation
paperSize excelize.PageLayoutPaperSize
fitToHeight excelize.FitToHeight
fitToWidth excelize.FitToWidth
)
if err := xl.GetPageLayout("Sheet1", &orientation); err != nil {
if err := f.GetPageLayout("Sheet1", &orientation); err != nil {
panic(err)
}
if err := f.GetPageLayout("Sheet1", &paperSize); err != nil {
panic(err)
}
if err := f.GetPageLayout("Sheet1", &fitToHeight); err != nil {
panic(err)
}
if err := xl.GetPageLayout("Sheet1", &paperSize); err != nil {

if err := f.GetPageLayout("Sheet1", &fitToWidth); err != nil {
panic(err)
}
fmt.Println("Defaults:")
fmt.Printf("- orientation: %q\n", orientation)
fmt.Printf("- paper size: %d\n", paperSize)
fmt.Printf("- fit to height: %d\n", fitToHeight)
fmt.Printf("- fit to width: %d\n", fitToWidth)
// Output:
// Defaults:
// - orientation: "portrait"
// - paper size: 1
// - fit to height: 1
// - fit to width: 1
}

func TestPageLayoutOption(t *testing.T) {
Expand All @@ -57,6 +75,8 @@ func TestPageLayoutOption(t *testing.T) {
}{
{new(excelize.PageLayoutOrientation), excelize.PageLayoutOrientation(excelize.OrientationLandscape)},
{new(excelize.PageLayoutPaperSize), excelize.PageLayoutPaperSize(10)},
{new(excelize.FitToHeight), excelize.FitToHeight(2)},
{new(excelize.FitToWidth), excelize.FitToWidth(2)},
}

for i, test := range testData {
Expand All @@ -69,26 +89,26 @@ func TestPageLayoutOption(t *testing.T) {
val1 := deepcopy.Copy(def).(excelize.PageLayoutOptionPtr)
val2 := deepcopy.Copy(def).(excelize.PageLayoutOptionPtr)

xl := excelize.NewFile()
f := excelize.NewFile()
// Get the default value
assert.NoError(t, xl.GetPageLayout(sheet, def), opt)
assert.NoError(t, f.GetPageLayout(sheet, def), opt)
// Get again and check
assert.NoError(t, xl.GetPageLayout(sheet, val1), opt)
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
if !assert.Equal(t, val1, def, opt) {
t.FailNow()
}
// Set the same value
assert.NoError(t, xl.SetPageLayout(sheet, val1), opt)
assert.NoError(t, f.SetPageLayout(sheet, val1), opt)
// Get again and check
assert.NoError(t, xl.GetPageLayout(sheet, val1), opt)
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) {
t.FailNow()
}
// Set a different value
assert.NoError(t, xl.SetPageLayout(sheet, test.nonDefault), opt)
assert.NoError(t, xl.GetPageLayout(sheet, val1), opt)
assert.NoError(t, f.SetPageLayout(sheet, test.nonDefault), opt)
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
// Get again and compare
assert.NoError(t, xl.GetPageLayout(sheet, val2), opt)
assert.NoError(t, f.GetPageLayout(sheet, val2), opt)
if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) {
t.FailNow()
}
Expand All @@ -97,15 +117,38 @@ func TestPageLayoutOption(t *testing.T) {
t.FailNow()
}
// Restore the default value
assert.NoError(t, xl.SetPageLayout(sheet, def), opt)
assert.NoError(t, xl.GetPageLayout(sheet, val1), opt)
assert.NoError(t, f.SetPageLayout(sheet, def), opt)
assert.NoError(t, f.GetPageLayout(sheet, val1), opt)
if !assert.Equal(t, def, val1) {
t.FailNow()
}
})
}
}

func TestSearchSheet(t *testing.T) {
f, err := excelize.OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
if !assert.NoError(t, err) {
t.FailNow()
}
// Test search in a not exists worksheet.
_, err = f.SearchSheet("Sheet4", "")
assert.EqualError(t, err, "sheet Sheet4 is not exist")
var expected []string
// Test search a not exists value.
result, err := f.SearchSheet("Sheet1", "X")
assert.NoError(t, err)
assert.EqualValues(t, expected, result)
result, err = f.SearchSheet("Sheet1", "A")
assert.NoError(t, err)
assert.EqualValues(t, []string{"A1"}, result)
// Test search the coordinates where the numerical value in the range of
// "0-9" of Sheet1 is described by regular expression:
result, err = f.SearchSheet("Sheet1", "[0-9]", true)
assert.NoError(t, err)
assert.EqualValues(t, expected, result)
}

func TestSetPageLayout(t *testing.T) {
f := excelize.NewFile()
// Test set page layout on not exists worksheet.
Expand All @@ -117,3 +160,90 @@ func TestGetPageLayout(t *testing.T) {
// Test get page layout on not exists worksheet.
assert.EqualError(t, f.GetPageLayout("SheetN"), "sheet SheetN is not exist")
}

func TestSetHeaderFooter(t *testing.T) {
f := excelize.NewFile()
f.SetCellStr("Sheet1", "A1", "Test SetHeaderFooter")
// Test set header and footer on not exists worksheet.
assert.EqualError(t, f.SetHeaderFooter("SheetN", nil), "sheet SheetN is not exist")
// Test set header and footer with illegal setting.
assert.EqualError(t, f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{
OddHeader: strings.Repeat("c", 256),
}), "field OddHeader must be less than 255 characters")

assert.NoError(t, f.SetHeaderFooter("Sheet1", nil))
assert.NoError(t, f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{
DifferentFirst: true,
DifferentOddEven: true,
OddHeader: "&R&P",
OddFooter: "&C&F",
EvenHeader: "&L&P",
EvenFooter: "&L&D&R&T",
FirstHeader: `&CCenter &"-,Bold"Bold&"-,Regular"HeaderU+000A&D`,
}))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetHeaderFooter.xlsx")))
}

func TestDefinedName(t *testing.T) {
f := excelize.NewFile()
assert.NoError(t, f.SetDefinedName(&excelize.DefinedName{
Name: "Amount",
RefersTo: "Sheet1!$A$2:$D$5",
Comment: "defined name comment",
Scope: "Sheet1",
}))
assert.NoError(t, f.SetDefinedName(&excelize.DefinedName{
Name: "Amount",
RefersTo: "Sheet1!$A$2:$D$5",
Comment: "defined name comment",
}))
assert.EqualError(t, f.SetDefinedName(&excelize.DefinedName{
Name: "Amount",
RefersTo: "Sheet1!$A$2:$D$5",
Comment: "defined name comment",
}), "the same name already exists on scope")
assert.Exactly(t, "Sheet1!$A$2:$D$5", f.GetDefinedName()[1].RefersTo)
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestDefinedName.xlsx")))
}

func TestGroupSheets(t *testing.T) {
f := excelize.NewFile()
sheets := []string{"Sheet2", "Sheet3"}
for _, sheet := range sheets {
f.NewSheet(sheet)
}
assert.EqualError(t, f.GroupSheets([]string{"Sheet1", "SheetN"}), "sheet SheetN is not exist")
assert.EqualError(t, f.GroupSheets([]string{"Sheet2", "Sheet3"}), "group worksheet must contain an active worksheet")
assert.NoError(t, f.GroupSheets([]string{"Sheet1", "Sheet2"}))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestGroupSheets.xlsx")))
}

func TestUngroupSheets(t *testing.T) {
f := excelize.NewFile()
sheets := []string{"Sheet2", "Sheet3", "Sheet4", "Sheet5"}
for _, sheet := range sheets {
f.NewSheet(sheet)
}
assert.NoError(t, f.UngroupSheets())
}

func TestGetSheetName(t *testing.T) {
f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx"))
assert.Equal(t, "Sheet1", f.GetSheetName(1))
assert.Equal(t, "Sheet2", f.GetSheetName(2))
assert.Equal(t, "", f.GetSheetName(0))
assert.Equal(t, "", f.GetSheetName(3))
}

func TestGetSheetMap(t *testing.T) {
expectedMap := map[int]string{
1: "Sheet1",
2: "Sheet2",
}
f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx"))
sheetMap := f.GetSheetMap()
for idx, name := range sheetMap {
assert.Equal(t, expectedMap[idx], name)
}
assert.Equal(t, len(sheetMap), 2)
}
2 changes: 1 addition & 1 deletion sheetpr.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down
77 changes: 59 additions & 18 deletions sheetview.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,64 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "fmt"

// SheetViewOption is an option of a view of a worksheet. See SetSheetViewOptions().
// SheetViewOption is an option of a view of a worksheet. See
// SetSheetViewOptions().
type SheetViewOption interface {
setSheetViewOption(view *xlsxSheetView)
}

// SheetViewOptionPtr is a writable SheetViewOption. See GetSheetViewOptions().
// SheetViewOptionPtr is a writable SheetViewOption. See
// GetSheetViewOptions().
type SheetViewOptionPtr interface {
SheetViewOption
getSheetViewOption(view *xlsxSheetView)
}

type (
// DefaultGridColor is a SheetViewOption.
// DefaultGridColor is a SheetViewOption. It specifies a flag indicating that
// the consuming application should use the default grid lines color (system
// dependent). Overrides any color specified in colorId.
DefaultGridColor bool
// RightToLeft is a SheetViewOption.
// RightToLeft is a SheetViewOption. It specifies a flag indicating whether
// the sheet is in 'right to left' display mode. When in this mode, Column A
// is on the far right, Column B ;is one column left of Column A, and so on.
// Also, information in cells is displayed in the Right to Left format.
RightToLeft bool
// ShowFormulas is a SheetViewOption.
// ShowFormulas is a SheetViewOption. It specifies a flag indicating whether
// this sheet should display formulas.
ShowFormulas bool
// ShowGridLines is a SheetViewOption.
// ShowGridLines is a SheetViewOption. It specifies a flag indicating whether
// this sheet should display gridlines.
ShowGridLines bool
// ShowRowColHeaders is a SheetViewOption.
// ShowRowColHeaders is a SheetViewOption. It specifies a flag indicating
// whether the sheet should display row and column headings.
ShowRowColHeaders bool
// ZoomScale is a SheetViewOption.
// ZoomScale is a SheetViewOption. It specifies a window zoom magnification
// for current view representing percent values. This attribute is restricted
// to values ranging from 10 to 400. Horizontal & Vertical scale together.
ZoomScale float64
// TopLeftCell is a SheetViewOption.
// TopLeftCell is a SheetViewOption. It specifies a location of the top left
// visible cell Location of the top left visible cell in the bottom right
// pane (when in Left-to-Right mode).
TopLeftCell string
// ShowZeros is a SheetViewOption. It specifies a flag indicating
// whether to "show a zero in cells that have zero value".
// When using a formula to reference another cell which is empty, the referenced value becomes 0
// when the flag is true. (Default setting is true.)
ShowZeros bool

/* TODO
// ShowWhiteSpace is a SheetViewOption.
// ShowWhiteSpace is a SheetViewOption. It specifies a flag indicating
// whether page layout view shall display margins. False means do not display
// left, right, top (header), and bottom (footer) margins (even when there is
// data in the header or footer).
ShowWhiteSpace bool
// ShowZeros is a SheetViewOption.
ShowZeros bool
// WindowProtection is a SheetViewOption.
WindowProtection bool
*/
Expand Down Expand Up @@ -89,6 +110,14 @@ func (o *ShowGridLines) getSheetViewOption(view *xlsxSheetView) {
*o = ShowGridLines(defaultTrue(view.ShowGridLines)) // Excel default: true
}

func (o ShowZeros) setSheetViewOption(view *xlsxSheetView) {
view.ShowZeros = boolPtr(bool(o))
}

func (o *ShowZeros) getSheetViewOption(view *xlsxSheetView) {
*o = ShowZeros(defaultTrue(view.ShowZeros)) // Excel default: true
}

func (o ShowRowColHeaders) setSheetViewOption(view *xlsxSheetView) {
view.ShowRowColHeaders = boolPtr(bool(o))
}
Expand All @@ -98,7 +127,7 @@ func (o *ShowRowColHeaders) getSheetViewOption(view *xlsxSheetView) {
}

func (o ZoomScale) setSheetViewOption(view *xlsxSheetView) {
//This attribute is restricted to values ranging from 10 to 400.
// This attribute is restricted to values ranging from 10 to 400.
if float64(o) >= 10 && float64(o) <= 400 {
view.ZoomScale = float64(o)
}
Expand Down Expand Up @@ -126,17 +155,23 @@ func (f *File) getSheetView(sheetName string, viewIndex int) (*xlsxSheetView, er
return &(xlsx.SheetViews.SheetView[viewIndex]), err
}

// SetSheetViewOptions sets sheet view options.
// The viewIndex may be negative and if so is counted backward (-1 is the last view).
// SetSheetViewOptions sets sheet view options. The viewIndex may be negative
// and if so is counted backward (-1 is the last view).
//
// Available options:
//
// DefaultGridColor(bool)
// RightToLeft(bool)
// ShowFormulas(bool)
// ShowGridLines(bool)
// ShowRowColHeaders(bool)
// ZoomScale(float64)
// TopLeftCell(string)
//
// Example:
//
// err = f.SetSheetViewOptions("Sheet1", -1, ShowGridLines(false))
//
func (f *File) SetSheetViewOptions(name string, viewIndex int, opts ...SheetViewOption) error {
view, err := f.getSheetView(name, viewIndex)
if err != nil {
Expand All @@ -149,18 +184,24 @@ func (f *File) SetSheetViewOptions(name string, viewIndex int, opts ...SheetView
return nil
}

// GetSheetViewOptions gets the value of sheet view options.
// The viewIndex may be negative and if so is counted backward (-1 is the last view).
// GetSheetViewOptions gets the value of sheet view options. The viewIndex may
// be negative and if so is counted backward (-1 is the last view).
//
// Available options:
//
// DefaultGridColor(bool)
// RightToLeft(bool)
// ShowFormulas(bool)
// ShowGridLines(bool)
// ShowRowColHeaders(bool)
// ZoomScale(float64)
// TopLeftCell(string)
//
// Example:
//
// var showGridLines excelize.ShowGridLines
// err = f.GetSheetViewOptions("Sheet1", -1, &showGridLines)
//
func (f *File) GetSheetViewOptions(name string, viewIndex int, opts ...SheetViewOptionPtr) error {
view, err := f.getSheetView(name, viewIndex)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions sheetview_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func ExampleFile_GetSheetViewOptions() {
rightToLeft excelize.RightToLeft
showFormulas excelize.ShowFormulas
showGridLines excelize.ShowGridLines
showZeros excelize.ShowZeros
showRowColHeaders excelize.ShowRowColHeaders
zoomScale excelize.ZoomScale
topLeftCell excelize.TopLeftCell
Expand All @@ -105,6 +106,7 @@ func ExampleFile_GetSheetViewOptions() {
&rightToLeft,
&showFormulas,
&showGridLines,
&showZeros,
&showRowColHeaders,
&zoomScale,
&topLeftCell,
Expand All @@ -117,6 +119,7 @@ func ExampleFile_GetSheetViewOptions() {
fmt.Println("- rightToLeft:", rightToLeft)
fmt.Println("- showFormulas:", showFormulas)
fmt.Println("- showGridLines:", showGridLines)
fmt.Println("- showZeros:", showZeros)
fmt.Println("- showRowColHeaders:", showRowColHeaders)
fmt.Println("- zoomScale:", zoomScale)
fmt.Println("- topLeftCell:", `"`+topLeftCell+`"`)
Expand All @@ -137,8 +140,17 @@ func ExampleFile_GetSheetViewOptions() {
panic(err)
}

if err := f.SetSheetViewOptions(sheet, 0, excelize.ShowZeros(false)); err != nil {
panic(err)
}

if err := f.GetSheetViewOptions(sheet, 0, &showZeros); err != nil {
panic(err)
}

fmt.Println("After change:")
fmt.Println("- showGridLines:", showGridLines)
fmt.Println("- showZeros:", showZeros)
fmt.Println("- topLeftCell:", topLeftCell)

// Output:
Expand All @@ -147,11 +159,13 @@ func ExampleFile_GetSheetViewOptions() {
// - rightToLeft: false
// - showFormulas: false
// - showGridLines: true
// - showZeros: true
// - showRowColHeaders: true
// - zoomScale: 0
// - topLeftCell: ""
// After change:
// - showGridLines: false
// - showZeros: false
// - topLeftCell: B2
}

Expand Down
503 changes: 503 additions & 0 deletions sparkline.go

Large diffs are not rendered by default.

297 changes: 297 additions & 0 deletions sparkline_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
package excelize

import (
"fmt"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestAddSparkline(t *testing.T) {
f := prepareSparklineDataset()

// Set the columns widths to make the output clearer
style, err := f.NewStyle(`{"font":{"bold":true}}`)
assert.NoError(t, err)
assert.NoError(t, f.SetCellStyle("Sheet1", "A1", "B1", style))
assert.NoError(t, f.SetSheetViewOptions("Sheet1", 0, ZoomScale(150)))

f.SetColWidth("Sheet1", "A", "A", 14)
f.SetColWidth("Sheet1", "B", "B", 50)
// Headings
f.SetCellValue("Sheet1", "A1", "Sparkline")
f.SetCellValue("Sheet1", "B1", "Description")

f.SetCellValue("Sheet1", "B2", `A default "line" sparkline.`)
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A2"},
Range: []string{"Sheet3!A1:J1"},
}))

f.SetCellValue("Sheet1", "B3", `A default "column" sparkline.`)
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A3"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
}))

f.SetCellValue("Sheet1", "B4", `A default "win/loss" sparkline.`)
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A4"},
Range: []string{"Sheet3!A3:J3"},
Type: "win_loss",
}))

f.SetCellValue("Sheet1", "B6", "Line with markers.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A6"},
Range: []string{"Sheet3!A1:J1"},
Markers: true,
}))

f.SetCellValue("Sheet1", "B7", "Line with high and low points.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A7"},
Range: []string{"Sheet3!A1:J1"},
High: true,
Low: true,
}))

f.SetCellValue("Sheet1", "B8", "Line with first and last point markers.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A8"},
Range: []string{"Sheet3!A1:J1"},
First: true,
Last: true,
}))

f.SetCellValue("Sheet1", "B9", "Line with negative point markers.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A9"},
Range: []string{"Sheet3!A1:J1"},
Negative: true,
}))

f.SetCellValue("Sheet1", "B10", "Line with axis.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A10"},
Range: []string{"Sheet3!A1:J1"},
Axis: true,
}))

f.SetCellValue("Sheet1", "B12", "Column with default style (1).")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A12"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
}))

f.SetCellValue("Sheet1", "B13", "Column with style 2.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A13"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
Style: 2,
}))

f.SetCellValue("Sheet1", "B14", "Column with style 3.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A14"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
Style: 3,
}))

f.SetCellValue("Sheet1", "B15", "Column with style 4.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A15"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
Style: 4,
}))

f.SetCellValue("Sheet1", "B16", "Column with style 5.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A16"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
Style: 5,
}))

f.SetCellValue("Sheet1", "B17", "Column with style 6.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A17"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
Style: 6,
}))

f.SetCellValue("Sheet1", "B18", "Column with a user defined color.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A18"},
Range: []string{"Sheet3!A2:J2"},
Type: "column",
SeriesColor: "#E965E0",
}))

f.SetCellValue("Sheet1", "B20", "A win/loss sparkline.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A20"},
Range: []string{"Sheet3!A3:J3"},
Type: "win_loss",
}))

f.SetCellValue("Sheet1", "B21", "A win/loss sparkline with negative points highlighted.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A21"},
Range: []string{"Sheet3!A3:J3"},
Type: "win_loss",
Negative: true,
}))

f.SetCellValue("Sheet1", "B23", "A left to right column (the default).")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A23"},
Range: []string{"Sheet3!A4:J4"},
Type: "column",
Style: 20,
}))

f.SetCellValue("Sheet1", "B24", "A right to left column.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A24"},
Range: []string{"Sheet3!A4:J4"},
Type: "column",
Style: 20,
Reverse: true,
}))

f.SetCellValue("Sheet1", "B25", "Sparkline and text in one cell.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A25"},
Range: []string{"Sheet3!A4:J4"},
Type: "column",
Style: 20,
}))
f.SetCellValue("Sheet1", "A25", "Growth")

f.SetCellValue("Sheet1", "B27", "A grouped sparkline. Changes are applied to all three.")
assert.NoError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A27", "A28", "A29"},
Range: []string{"Sheet3!A5:J5", "Sheet3!A6:J6", "Sheet3!A7:J7"},
Markers: true,
}))

// Sheet2 sections
assert.NoError(t, f.AddSparkline("Sheet2", &SparklineOption{
Location: []string{"F3"},
Range: []string{"Sheet2!A3:E3"},
Type: "win_loss",
Negative: true,
}))

assert.NoError(t, f.AddSparkline("Sheet2", &SparklineOption{
Location: []string{"F1"},
Range: []string{"Sheet2!A1:E1"},
Markers: true,
}))

assert.NoError(t, f.AddSparkline("Sheet2", &SparklineOption{
Location: []string{"F2"},
Range: []string{"Sheet2!A2:E2"},
Type: "column",
Style: 12,
}))

assert.NoError(t, f.AddSparkline("Sheet2", &SparklineOption{
Location: []string{"F3"},
Range: []string{"Sheet2!A3:E3"},
Type: "win_loss",
Negative: true,
}))

// Save xlsx file by the given path.
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddSparkline.xlsx")))

// Test error exceptions
assert.EqualError(t, f.AddSparkline("SheetN", &SparklineOption{
Location: []string{"F3"},
Range: []string{"Sheet2!A3:E3"},
}), "sheet SheetN is not exist")

assert.EqualError(t, f.AddSparkline("Sheet1", nil), "parameter is required")

assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Range: []string{"Sheet2!A3:E3"},
}), `parameter 'Location' is required`)

assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"F3"},
}), `parameter 'Range' is required`)

assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"F2", "F3"},
Range: []string{"Sheet2!A3:E3"},
}), `must have the same number of 'Location' and 'Range' parameters`)

assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"F3"},
Range: []string{"Sheet2!A3:E3"},
Type: "unknown_type",
}), `parameter 'Type' must be 'line', 'column' or 'win_loss'`)

assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"F3"},
Range: []string{"Sheet2!A3:E3"},
Style: -1,
}), `parameter 'Style' must betweent 0-35`)

assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"F3"},
Range: []string{"Sheet2!A3:E3"},
Style: -1,
}), `parameter 'Style' must betweent 0-35`)

f.Sheet["xl/worksheets/sheet1.xml"].ExtLst.Ext = `<extLst>
<ext x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" uri="{05C60535-1F16-4fd2-B633-F4F36F0B64E0}">
<x14:sparklineGroups
xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main">
<x14:sparklineGroup>
</x14:sparklines>
</x14:sparklineGroup>
</x14:sparklineGroups>
</ext>
</extLst>`
assert.EqualError(t, f.AddSparkline("Sheet1", &SparklineOption{
Location: []string{"A2"},
Range: []string{"Sheet3!A1:J1"},
}), "XML syntax error on line 6: element <sparklineGroup> closed by </sparklines>")
}

func prepareSparklineDataset() *File {
f := NewFile()
sheet2 := [][]int{
{-2, 2, 3, -1, 0},
{30, 20, 33, 20, 15},
{1, -1, -1, 1, -1},
}
sheet3 := [][]int{
{-2, 2, 3, -1, 0, -2, 3, 2, 1, 0},
{30, 20, 33, 20, 15, 5, 5, 15, 10, 15},
{1, 1, -1, -1, 1, -1, 1, 1, 1, -1},
{5, 6, 7, 10, 15, 20, 30, 50, 70, 100},
{-2, 2, 3, -1, 0, -2, 3, 2, 1, 0},
{3, -1, 0, -2, 3, 2, 1, 0, 2, 1},
{0, -2, 3, 2, 1, 0, 1, 2, 3, 1},
}
f.NewSheet("Sheet2")
f.NewSheet("Sheet3")
for row, data := range sheet2 {
f.SetSheetRow("Sheet2", fmt.Sprintf("A%d", row+1), &data)
}
for row, data := range sheet3 {
f.SetSheetRow("Sheet3", fmt.Sprintf("A%d", row+1), &data)
}
return f
}
65 changes: 46 additions & 19 deletions styles.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down Expand Up @@ -852,7 +852,7 @@ func formatToInt(i int, v string) string {
if err != nil {
return v
}
return fmt.Sprintf("%d", int(f))
return fmt.Sprintf("%d", int64(f))
}

// formatToFloat provides a function to convert original string to float
Expand Down Expand Up @@ -1010,7 +1010,7 @@ func (f *File) stylesReader() *xlsxStyleSheet {
func (f *File) styleSheetWriter() {
if f.Styles != nil {
output, _ := xml.Marshal(f.Styles)
f.saveFileList("xl/styles.xml", replaceWorkSheetsRelationshipsNameSpaceBytes(output))
f.saveFileList("xl/styles.xml", replaceStyleRelationshipsNameSpaceBytes(output))
}
}

Expand Down Expand Up @@ -1895,11 +1895,8 @@ func (f *File) NewStyle(style string) (int, error) {
numFmtID := setNumFmt(s, fs)

if fs.Font != nil {
font, _ := xml.Marshal(setFont(fs))
s.Fonts.Count++
s.Fonts.Font = append(s.Fonts.Font, &xlsxFont{
Font: string(font[6 : len(font)-7]),
})
s.Fonts.Font = append(s.Fonts.Font, f.setFont(fs))
fontID = s.Fonts.Count - 1
}

Expand Down Expand Up @@ -1935,7 +1932,7 @@ func (f *File) NewConditionalStyle(style string) (int, error) {
Border: setBorders(fs),
}
if fs.Font != nil {
dxf.Font = setFont(fs)
dxf.Font = f.setFont(fs)
}
dxfStr, _ := xml.Marshal(dxf)
if s.Dxfs == nil {
Expand All @@ -1948,33 +1945,63 @@ func (f *File) NewConditionalStyle(style string) (int, error) {
return s.Dxfs.Count - 1, nil
}

// GetDefaultFont provides the default font name currently set in the workbook
// Documents generated by excelize start with Calibri.
func (f *File) GetDefaultFont() string {
font := f.readDefaultFont()
return font.Name.Val
}

// SetDefaultFont changes the default font in the workbook.
func (f *File) SetDefaultFont(fontName string) {
font := f.readDefaultFont()
font.Name.Val = fontName
s := f.stylesReader()
s.Fonts.Font[0] = font
custom := true
s.CellStyles.CellStyle[0].CustomBuiltIn = &custom
}

// readDefaultFont provides an unmarshalled font value.
func (f *File) readDefaultFont() *xlsxFont {
s := f.stylesReader()
return s.Fonts.Font[0]
}

// setFont provides a function to add font style by given cell format
// settings.
func setFont(formatStyle *formatStyle) *font {
func (f *File) setFont(formatStyle *formatStyle) *xlsxFont {
fontUnderlineType := map[string]string{"single": "single", "double": "double"}
if formatStyle.Font.Size < 1 {
formatStyle.Font.Size = 11
}
if formatStyle.Font.Color == "" {
formatStyle.Font.Color = "#000000"
}
f := font{
B: formatStyle.Font.Bold,
I: formatStyle.Font.Italic,
Sz: &attrValInt{Val: formatStyle.Font.Size},
fnt := xlsxFont{
Sz: &attrValFloat{Val: formatStyle.Font.Size},
Color: &xlsxColor{RGB: getPaletteColor(formatStyle.Font.Color)},
Name: &attrValString{Val: formatStyle.Font.Family},
Family: &attrValInt{Val: 2},
}
if f.Name.Val == "" {
f.Name.Val = "Calibri"
f.Scheme = &attrValString{Val: "minor"}
if formatStyle.Font.Bold {
fnt.B = &formatStyle.Font.Bold
}
if formatStyle.Font.Italic {
fnt.I = &formatStyle.Font.Italic
}
if fnt.Name.Val == "" {
fnt.Name.Val = f.GetDefaultFont()
}
if formatStyle.Font.Strike {
strike := true
fnt.Strike = &strike
}
val, ok := fontUnderlineType[formatStyle.Font.Underline]
if ok {
f.U = &attrValString{Val: val}
fnt.U = &attrValString{Val: val}
}
return &f
return &fnt
}

// setNumFmt provides a function to check if number format code in the range
Expand Down Expand Up @@ -2328,7 +2355,7 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
//
// Set font style for cell H9 on Sheet1:
//
// style, err := f.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777"}}`)
// style, err := f.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777"}}`)
// if err != nil {
// fmt.Println(err)
// }
Expand Down
30 changes: 29 additions & 1 deletion styles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestStyleFill(t *testing.T) {
xl := NewFile()
styleID, err := xl.NewStyle(testCase.format)
if err != nil {
t.Fatalf("%v", err)
t.Fatal(err)
}

styles := xl.stylesReader()
Expand Down Expand Up @@ -165,3 +165,31 @@ func TestSetConditionalFormat(t *testing.T) {
assert.EqualValues(t, testCase.rules, cf[0].CfRule, testCase.label)
}
}

func TestNewStyle(t *testing.T) {
f := NewFile()
styleID, err := f.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777"}}`)
if err != nil {
t.Fatal(err)
}
styles := f.stylesReader()
fontID := styles.CellXfs.Xf[styleID].FontID
font := styles.Fonts.Font[fontID]
assert.Contains(t, font.Name.Val, "Times New Roman", "Stored font should contain font name")
assert.Equal(t, 2, styles.CellXfs.Count, "Should have 2 styles")
}

func TestGetDefaultFont(t *testing.T) {
f := NewFile()
s := f.GetDefaultFont()
assert.Equal(t, s, "Calibri", "Default font should be Calibri")
}

func TestSetDefaultFont(t *testing.T) {
f := NewFile()
f.SetDefaultFont("Ariel")
styles := f.stylesReader()
s := f.GetDefaultFont()
assert.Equal(t, s, "Ariel", "Default font should change to Ariel")
assert.Equal(t, *styles.CellStyles.CellStyle[0].CustomBuiltIn, true)
}
23 changes: 10 additions & 13 deletions table.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down Expand Up @@ -77,7 +77,9 @@ func (f *File) AddTable(sheet, hcell, vcell, format string) error {
sheetRelationshipsTableXML := "../tables/table" + strconv.Itoa(tableID) + ".xml"
tableXML := strings.Replace(sheetRelationshipsTableXML, "..", "xl", -1)
// Add first table for given sheet.
rID := f.addSheetRelationships(sheet, SourceRelationshipTable, sheetRelationshipsTableXML, "")
sheetPath, _ := f.sheetMap[trimSheetName(sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipTable, sheetRelationshipsTableXML, "")
f.addSheetTable(sheet, rID)
err = f.addTable(sheet, tableXML, hcol, hrow, vcol, vrow, tableID, formatSet)
if err != nil {
Expand Down Expand Up @@ -115,29 +117,24 @@ func (f *File) addSheetTable(sheet string, rID int) {

// addTable provides a function to add table by given worksheet name,
// coordinate area and format set.
func (f *File) addTable(sheet, tableXML string, hcol, hrow, vcol, vrow, i int, formatSet *formatTable) error {
func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, formatSet *formatTable) error {
// Correct the minimum number of rows, the table at least two lines.
if hrow == vrow {
vrow++
if y1 == y2 {
y2++
}

// Correct table reference coordinate area, such correct C1:B3 to B1:C3.
hcell, err := CoordinatesToCellName(hcol, hrow)
ref, err := f.coordinatesToAreaRef([]int{x1, y1, x2, y2})
if err != nil {
return err
}
vcell, err := CoordinatesToCellName(vcol, vrow)
if err != nil {
return err
}
ref := hcell + ":" + vcell

var tableColumn []*xlsxTableColumn

idx := 0
for i := hcol; i <= vcol; i++ {
for i := x1; i <= x2; i++ {
idx++
cell, err := CoordinatesToCellName(i, hrow)
cell, err := CoordinatesToCellName(i, y1)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.
//
// This file contains default templates for XML files we don't yet populated
// based on content.
Expand All @@ -27,7 +27,7 @@ const templateContentTypes = `<Types xmlns="http://schemas.openxmlformats.org/pa

const templateWorkbook = `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"><fileVersion appName="xl" lastEdited="6" lowestEdited="6" rupBuild="14420" /><workbookPr filterPrivacy="1" defaultThemeVersion="164011" /><bookViews><workbookView xWindow="0" yWindow="0" windowWidth="14805" windowHeight="8010" /></bookViews><sheets><sheet name="Sheet1" sheetId="1" r:id="rId1" /></sheets><calcPr calcId="122211" /></workbook>`

const templateStyles = `<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main"><fonts count="1" x14ac:knownFonts="1"><font><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/></cellXfs><cellStyles count="1"><cellStyle name="常规" xfId="0" builtinId="0"/></cellStyles><dxfs count="0"/><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/></styleSheet>`
const templateStyles = `<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main"><fonts count="1" x14ac:knownFonts="1"><font><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles><dxfs count="0"/><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/></styleSheet>`

const templateSheet = `<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/><sheetData/><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/></worksheet>`

Expand Down
Binary file modified test/BadWorkbook.xlsx
Binary file not shown.
Binary file modified test/Book1.xlsx
Binary file not shown.
Binary file modified test/CalcChain.xlsx
Binary file not shown.
Binary file modified test/MergeCell.xlsx
Binary file not shown.
Binary file added test/OverflowNumericCell.xlsx
Binary file not shown.
Binary file modified test/SharedStrings.xlsx
Binary file not shown.
Binary file added test/images/excel.tif
Binary file not shown.
Binary file added test/vbaProject.bin
Binary file not shown.
2 changes: 1 addition & 1 deletion vmlDrawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down
61 changes: 61 additions & 0 deletions xmlApp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "encoding/xml"

// xlsxProperties specifies to an OOXML document properties such as the
// template used, the number of pages and words, and the application name and
// version.
type xlsxProperties struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties Properties"`
Template string
Manager string
Company string
Pages int
Words int
Characters int
PresentationFormat string
Lines int
Paragraphs int
Slides int
Notes int
TotalTime int
HiddenSlides int
MMClips int
ScaleCrop bool
HeadingPairs *xlsxVectorVariant
TitlesOfParts *xlsxVectorLpstr
LinksUpToDate bool
CharactersWithSpaces int
SharedDoc bool
HyperlinkBase string
HLinks *xlsxVectorVariant
HyperlinksChanged bool
DigSig *xlsxDigSig
Application string
AppVersion string
DocSecurity int
}

// xlsxVectorVariant specifies the set of hyperlinks that were in this
// document when last saved.
type xlsxVectorVariant struct {
Content string `xml:",innerxml"`
}

type xlsxVectorLpstr struct {
Content string `xml:",innerxml"`
}

// xlsxDigSig contains the signature of a digitally signed document.
type xlsxDigSig struct {
Content string `xml:",innerxml"`
}
57 changes: 56 additions & 1 deletion xmlCalcChain.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand All @@ -18,6 +18,61 @@ type xlsxCalcChain struct {
}

// xlsxCalcChainC directly maps the c element.
//
// Attributes | Attributes
// --------------------------+----------------------------------------------------------
// a (Array) | A Boolean flag indicating whether the cell's formula
// | is an array formula. True if this cell's formula is
// | an array formula, false otherwise. If there is a
// | conflict between this attribute and the t attribute
// | of the f element (§18.3.1.40), the t attribute takes
// | precedence. The possible values for this attribute
// | are defined by the W3C XML Schema boolean datatype.
// |
// i (Sheet Id) | A sheet Id of a sheet the cell belongs to. If this is
// | omitted, it is assumed to be the same as the i value
// | of the previous cell.The possible values for this
// | attribute are defined by the W3C XML Schema int datatype.
// |
// l (New Dependency Level) | A Boolean flag indicating that the cell's formula
// | starts a new dependency level. True if the formula
// | starts a new dependency level, false otherwise.
// | Starting a new dependency level means that all
// | concurrent calculations, and child calculations, shall
// | be completed - and the cells have new values - before
// | the calc chain can continue. In other words, this
// | dependency level might depend on levels that came before
// | it, and any later dependency levels might depend on
// | this level; but not later dependency levels can have
// | any calculations started until this dependency level
// | completes.The possible values for this attribute are
// | defined by the W3C XML Schema boolean datatype.
// |
// r (Cell Reference) | An A-1 style reference to a cell.The possible values
// | for this attribute are defined by the ST_CellRef
// | simple type (§18.18.7).
// |
// s (Child Chain) | A Boolean flag indicating whether the cell's formula
// | is on a child chain. True if this cell is part of a
// | child chain, false otherwise. If this is omitted, it
// | is assumed to be the same as the s value of the
// | previous cell .A child chain is a list of calculations
// | that occur which depend on the parent to the chain.
// | There shall not be cross dependencies between child
// | chains. Child chains are not the same as dependency
// | levels - a child chain and its parent are all on the
// | same dependency level. Child chains are series of
// | calculations that can be independently farmed out to
// | other threads or processors.The possible values for
// | this attribute are defined by the W3C XML Schema
// | boolean datatype.
// |
// t (New Thread) | A Boolean flag indicating whether the cell's formula
// | starts a new thread. True if the cell's formula starts
// | a new thread, false otherwise.The possible values for
// | this attribute are defined by the W3C XML Schema
// | boolean datatype.
//
type xlsxCalcChainC struct {
R string `xml:"r,attr"`
I int `xml:"i,attr"`
Expand Down
350 changes: 184 additions & 166 deletions xmlChart.go

Large diffs are not rendered by default.

17 changes: 15 additions & 2 deletions xmlComments.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down Expand Up @@ -54,7 +54,20 @@ type xlsxComment struct {
// spreadsheet application implementation detail. A recommended guideline is
// 32767 chars.
type xlsxText struct {
R []xlsxR `xml:"r"`
T *string `xml:"t"`
R []xlsxR `xml:"r"`
RPh *xlsxPhoneticRun `xml:"rPh"`
PhoneticPr *xlsxPhoneticPr `xml:"phoneticPr"`
}

// xlsxPhoneticRun element represents a run of text which displays a phonetic
// hint for this String Item (si). Phonetic hints are used to give information
// about the pronunciation of an East Asian language. The hints are displayed
// as text within the spreadsheet cells across the top portion of the cell.
type xlsxPhoneticRun struct {
Sb uint32 `xml:"sb,attr"`
Eb uint32 `xml:"eb,attr"`
T string `xml:"t,attr"`
}

// formatComment directly maps the format settings of the comment.
Expand Down
2 changes: 1 addition & 1 deletion xmlContentTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down
89 changes: 89 additions & 0 deletions xmlCore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "encoding/xml"

// DocProperties directly maps the document core properties.
type DocProperties struct {
Category string
ContentStatus string
Created string
Creator string
Description string
Identifier string
Keywords string
LastModifiedBy string
Modified string
Revision string
Subject string
Title string
Language string
Version string
}

// decodeCoreProperties directly maps the root element for a part of this
// content type shall coreProperties. In order to solve the problem that the
// label structure is changed after serialization and deserialization, two
// different structures are defined. decodeCoreProperties just for
// deserialization.
type decodeCoreProperties struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/metadata/core-properties coreProperties"`
Title string `xml:"http://purl.org/dc/elements/1.1/ title,omitempty"`
Subject string `xml:"http://purl.org/dc/elements/1.1/ subject,omitempty"`
Creator string `xml:"http://purl.org/dc/elements/1.1/ creator"`
Keywords string `xml:"keywords,omitempty"`
Description string `xml:"http://purl.org/dc/elements/1.1/ description,omitempty"`
LastModifiedBy string `xml:"lastModifiedBy"`
Language string `xml:"http://purl.org/dc/elements/1.1/ language,omitempty"`
Identifier string `xml:"http://purl.org/dc/elements/1.1/ identifier,omitempty"`
Revision string `xml:"revision,omitempty"`
Created struct {
Text string `xml:",chardata"`
Type string `xml:"http://www.w3.org/2001/XMLSchema-instance type,attr"`
} `xml:"http://purl.org/dc/terms/ created"`
Modified struct {
Text string `xml:",chardata"`
Type string `xml:"http://www.w3.org/2001/XMLSchema-instance type,attr"`
} `xml:"http://purl.org/dc/terms/ modified"`
ContentStatus string `xml:"contentStatus,omitempty"`
Category string `xml:"category,omitempty"`
Version string `xml:"version,omitempty"`
}

// xlsxCoreProperties directly maps the root element for a part of this
// content type shall coreProperties.
type xlsxCoreProperties struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/metadata/core-properties coreProperties"`
Dc string `xml:"xmlns:dc,attr"`
Dcterms string `xml:"xmlns:dcterms,attr"`
Dcmitype string `xml:"xmlns:dcmitype,attr"`
XSI string `xml:"xmlns:xsi,attr"`
Title string `xml:"dc:title,omitempty"`
Subject string `xml:"dc:subject,omitempty"`
Creator string `xml:"dc:creator"`
Keywords string `xml:"keywords,omitempty"`
Description string `xml:"dc:description,omitempty"`
LastModifiedBy string `xml:"lastModifiedBy"`
Language string `xml:"dc:language,omitempty"`
Identifier string `xml:"dc:identifier,omitempty"`
Revision string `xml:"revision,omitempty"`
Created struct {
Text string `xml:",chardata"`
Type string `xml:"xsi:type,attr"`
} `xml:"dcterms:created"`
Modified struct {
Text string `xml:",chardata"`
Type string `xml:"xsi:type,attr"`
} `xml:"dcterms:modified"`
ContentStatus string `xml:"contentStatus,omitempty"`
Category string `xml:"category,omitempty"`
Version string `xml:"version,omitempty"`
}
113 changes: 75 additions & 38 deletions xmlDecodeDrawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,61 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "encoding/xml"

// decodeCellAnchor directly maps the oneCellAnchor (One Cell Anchor Shape Size)
// and twoCellAnchor (Two Cell Anchor Shape Size). This element specifies a two
// cell anchor placeholder for a group, a shape, or a drawing element. It moves
// with cells and its extents are in EMU units.
// decodeCellAnchor directly maps the oneCellAnchor (One Cell Anchor Shape
// Size) and twoCellAnchor (Two Cell Anchor Shape Size). This element
// specifies a two cell anchor placeholder for a group, a shape, or a drawing
// element. It moves with cells and its extents are in EMU units.
type decodeCellAnchor struct {
EditAs string `xml:"editAs,attr,omitempty"`
Content string `xml:",innerxml"`
EditAs string `xml:"editAs,attr,omitempty"`
From *decodeFrom `xml:"from"`
To *decodeTo `xml:"to"`
Sp *decodeSp `xml:"sp"`
ClientData *decodeClientData `xml:"clientData"`
Content string `xml:",innerxml"`
}

// xdrSp (Shape) directly maps the sp element. This element specifies the
// existence of a single shape. A shape can either be a preset or a custom
// geometry, defined using the SpreadsheetDrawingML framework. In addition to
// a geometry each shape can have both visual and non-visual properties
// attached. Text and corresponding styling information can also be attached
// to a shape. This shape is specified along with all other shapes within
// either the shape tree or group shape elements.
type decodeSp struct {
NvSpPr *decodeNvSpPr `xml:"nvSpPr"`
SpPr *decodeSpPr `xml:"spPr"`
}

// decodeSp (Non-Visual Properties for a Shape) directly maps the nvSpPr
// element. This element specifies all non-visual properties for a shape. This
// element is a container for the non-visual identification properties, shape
// properties and application properties that are to be associated with a
// shape. This allows for additional information that does not affect the
// appearance of the shape to be stored.
type decodeNvSpPr struct {
CNvPr *decodeCNvPr `xml:"cNvPr"`
ExtLst *decodeExt `xml:"extLst"`
CNvSpPr *decodeCNvSpPr `xml:"cNvSpPr"`
}

// decodeCNvSpPr (Connection Non-Visual Shape Properties) directly maps the
// cNvSpPr element. This element specifies the set of non-visual properties
// for a connection shape. These properties specify all data about the
// connection shape which do not affect its display within a spreadsheet.
type decodeCNvSpPr struct {
TxBox bool `xml:"txBox,attr"`
}

// decodeWsDr directly maps the root element for a part of this content type
// shall wsDr. In order to solve the problem that the label structure is changed
// after serialization and deserialization, two different structures are
// defined. decodeWsDr just for deserialization.
// shall wsDr. In order to solve the problem that the label structure is
// changed after serialization and deserialization, two different structures
// are defined. decodeWsDr just for deserialization.
type decodeWsDr struct {
A string `xml:"xmlns a,attr"`
Xdr string `xml:"xmlns xdr,attr"`
Expand All @@ -34,9 +70,9 @@ type decodeWsDr struct {
}

// decodeTwoCellAnchor directly maps the oneCellAnchor (One Cell Anchor Shape
// Size) and twoCellAnchor (Two Cell Anchor Shape Size). This element specifies
// a two cell anchor placeholder for a group, a shape, or a drawing element. It
// moves with cells and its extents are in EMU units.
// Size) and twoCellAnchor (Two Cell Anchor Shape Size). This element
// specifies a two cell anchor placeholder for a group, a shape, or a drawing
// element. It moves with cells and its extents are in EMU units.
type decodeTwoCellAnchor struct {
From *decodeFrom `xml:"from"`
To *decodeTo `xml:"to"`
Expand All @@ -46,7 +82,8 @@ type decodeTwoCellAnchor struct {

// decodeCNvPr directly maps the cNvPr (Non-Visual Drawing Properties). This
// element specifies non-visual canvas properties. This allows for additional
// information that does not affect the appearance of the picture to be stored.
// information that does not affect the appearance of the picture to be
// stored.
type decodeCNvPr struct {
ID int `xml:"id,attr"`
Name string `xml:"name,attr"`
Expand All @@ -55,8 +92,8 @@ type decodeCNvPr struct {
}

// decodePicLocks directly maps the picLocks (Picture Locks). This element
// specifies all locking properties for a graphic frame. These properties inform
// the generating application about specific properties that have been
// specifies all locking properties for a graphic frame. These properties
// inform the generating application about specific properties that have been
// previously locked and thus should not be changed.
type decodePicLocks struct {
NoAdjustHandles bool `xml:"noAdjustHandles,attr,omitempty"`
Expand All @@ -82,9 +119,9 @@ type decodeBlip struct {
R string `xml:"r,attr"`
}

// decodeStretch directly maps the stretch element. This element specifies that
// a BLIP should be stretched to fill the target rectangle. The other option is
// a tile where a BLIP is tiled to fill the available area.
// decodeStretch directly maps the stretch element. This element specifies
// that a BLIP should be stretched to fill the target rectangle. The other
// option is a tile where a BLIP is tiled to fill the available area.
type decodeStretch struct {
FillRect string `xml:"fillRect"`
}
Expand Down Expand Up @@ -128,12 +165,12 @@ type decodeCNvPicPr struct {
PicLocks decodePicLocks `xml:"picLocks"`
}

// directly maps the nvPicPr (Non-Visual Properties for a Picture). This element
// specifies all non-visual properties for a picture. This element is a
// container for the non-visual identification properties, shape properties and
// application properties that are to be associated with a picture. This allows
// for additional information that does not affect the appearance of the picture
// to be stored.
// directly maps the nvPicPr (Non-Visual Properties for a Picture). This
// element specifies all non-visual properties for a picture. This element is
// a container for the non-visual identification properties, shape properties
// and application properties that are to be associated with a picture. This
// allows for additional information that does not affect the appearance of
// the picture to be stored.
type decodeNvPicPr struct {
CNvPr decodeCNvPr `xml:"cNvPr"`
CNvPicPr decodeCNvPicPr `xml:"cNvPicPr"`
Expand All @@ -148,20 +185,20 @@ type decodeBlipFill struct {
Stretch decodeStretch `xml:"stretch"`
}

// decodeSpPr directly maps the spPr (Shape Properties). This element specifies
// the visual shape properties that can be applied to a picture. These are the
// same properties that are allowed to describe the visual properties of a shape
// but are used here to describe the visual appearance of a picture within a
// document.
// decodeSpPr directly maps the spPr (Shape Properties). This element
// specifies the visual shape properties that can be applied to a picture.
// These are the same properties that are allowed to describe the visual
// properties of a shape but are used here to describe the visual appearance
// of a picture within a document.
type decodeSpPr struct {
Xfrm decodeXfrm `xml:"a:xfrm"`
PrstGeom decodePrstGeom `xml:"a:prstGeom"`
Xfrm decodeXfrm `xml:"xfrm"`
PrstGeom decodePrstGeom `xml:"prstGeom"`
}

// decodePic elements encompass the definition of pictures within the DrawingML
// framework. While pictures are in many ways very similar to shapes they have
// specific properties that are unique in order to optimize for picture-
// specific scenarios.
// decodePic elements encompass the definition of pictures within the
// DrawingML framework. While pictures are in many ways very similar to shapes
// they have specific properties that are unique in order to optimize for
// picture- specific scenarios.
type decodePic struct {
NvPicPr decodeNvPicPr `xml:"nvPicPr"`
BlipFill decodeBlipFill `xml:"blipFill"`
Expand All @@ -184,8 +221,8 @@ type decodeTo struct {
RowOff int `xml:"rowOff"`
}

// decodeClientData directly maps the clientData element. An empty element which
// specifies (via attributes) certain properties related to printing and
// decodeClientData directly maps the clientData element. An empty element
// which specifies (via attributes) certain properties related to printing and
// selection of the drawing object. The fLocksWithSheet attribute (either true
// or false) determines whether to disable selection when the sheet is
// protected, and fPrintsWithSheet attribute (either true or false) determines
Expand Down
77 changes: 52 additions & 25 deletions xmlDrawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,67 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "encoding/xml"

// Source relationship and namespace.
const (
SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
SourceRelationshipComments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
SourceRelationshipTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"
SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
SourceRelationshipChart201506 = "http://schemas.microsoft.com/office/drawing/2015/06/chart"
SourceRelationshipChart20070802 = "http://schemas.microsoft.com/office/drawing/2007/8/2/chart"
SourceRelationshipChart2014 = "http://schemas.microsoft.com/office/drawing/2014/chart"
SourceRelationshipCompatibility = "http://schemas.openxmlformats.org/markup-compatibility/2006"
NameSpaceDrawingML = "http://schemas.openxmlformats.org/drawingml/2006/main"
NameSpaceDrawingMLChart = "http://schemas.openxmlformats.org/drawingml/2006/chart"
NameSpaceDrawingMLSpreadSheet = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
NameSpaceSpreadSheet = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
StrictSourceRelationship = "http://purl.oclc.org/ooxml/officeDocument/relationships"
StrictSourceRelationshipChart = "http://purl.oclc.org/ooxml/officeDocument/relationships/chart"
StrictSourceRelationshipComments = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments"
StrictSourceRelationshipImage = "http://purl.oclc.org/ooxml/officeDocument/relationships/image"
StrictNameSpaceSpreadSheet = "http://purl.oclc.org/ooxml/spreadsheetml/main"
SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
SourceRelationshipComments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
SourceRelationshipTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"
SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
SourceRelationshipPivotTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"
SourceRelationshipPivotCache = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition"
SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
SourceRelationshipChart201506 = "http://schemas.microsoft.com/office/drawing/2015/06/chart"
SourceRelationshipChart20070802 = "http://schemas.microsoft.com/office/drawing/2007/8/2/chart"
SourceRelationshipChart2014 = "http://schemas.microsoft.com/office/drawing/2014/chart"
SourceRelationshipCompatibility = "http://schemas.openxmlformats.org/markup-compatibility/2006"
NameSpaceDrawingML = "http://schemas.openxmlformats.org/drawingml/2006/main"
NameSpaceDrawingMLChart = "http://schemas.openxmlformats.org/drawingml/2006/chart"
NameSpaceDrawingMLSpreadSheet = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
NameSpaceSpreadSheet = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
NameSpaceSpreadSheetX14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
NameSpaceSpreadSheetX15 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"
NameSpaceSpreadSheetExcel2006Main = "http://schemas.microsoft.com/office/excel/2006/main"
NameSpaceMacExcel2008Main = "http://schemas.microsoft.com/office/mac/excel/2008/main"
NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
NameSpaceXMLSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance"
StrictSourceRelationship = "http://purl.oclc.org/ooxml/officeDocument/relationships"
StrictSourceRelationshipChart = "http://purl.oclc.org/ooxml/officeDocument/relationships/chart"
StrictSourceRelationshipComments = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments"
StrictSourceRelationshipImage = "http://purl.oclc.org/ooxml/officeDocument/relationships/image"
StrictNameSpaceSpreadSheet = "http://purl.oclc.org/ooxml/spreadsheetml/main"
NameSpaceDublinCore = "http://purl.org/dc/elements/1.1/"
NameSpaceDublinCoreTerms = "http://purl.org/dc/terms/"
NameSpaceDublinCoreMetadataIntiative = "http://purl.org/dc/dcmitype/"
// The extLst child element ([ISO/IEC29500-1:2016] section 18.2.10) of the
// worksheet element ([ISO/IEC29500-1:2016] section 18.3.1.99) is extended by
// the addition of new child ext elements ([ISO/IEC29500-1:2016] section
// 18.2.7)
ExtURIConditionalFormattings = "{78C0D931-6437-407D-A8EE-F0AAD7539E65}"
ExtURIDataValidations = "{CCE6A557-97BC-4B89-ADB6-D9C93CAAB3DF}"
ExtURISparklineGroups = "{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"
ExtURISlicerListX14 = "{A8765BA9-456A-4DAB-B4F3-ACF838C121DE}"
ExtURISlicerCachesListX14 = "{BBE1A952-AA13-448e-AADC-164F8A28A991}"
ExtURISlicerListX15 = "{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}"
ExtURIProtectedRanges = "{FC87AEE6-9EDD-4A0A-B7FB-166176984837}"
ExtURIIgnoredErrors = "{01252117-D84E-4E92-8308-4BE1C098FCBB}"
ExtURIWebExtensions = "{F7C9EE02-42E1-4005-9D12-6889AFFD525C}"
ExtURITimelineRefs = "{7E03D99C-DC04-49d9-9315-930204A7B6E9}"
ExtURIDrawingBlip = "{28A0092B-C50C-407E-A947-70E740481C1C}"
ExtURIMacExcelMX = "{64002731-A6B0-56B0-2670-7721B7C09600}"
)

var supportImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png"}
var supportImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png", ".tif": ".tiff", ".tiff": ".tiff"}

// xlsxCNvPr directly maps the cNvPr (Non-Visual Drawing Properties). This
// element specifies non-visual canvas properties. This allows for additional
Expand Down
218 changes: 218 additions & 0 deletions xmlPivotCache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package excelize

import "encoding/xml"

// xlsxPivotCacheDefinition represents the pivotCacheDefinition part. This part
// defines each field in the source data, including the name, the string
// resources of the instance data (for shared items), and information about
// the type of data that appears in the field.
type xlsxPivotCacheDefinition struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main pivotCacheDefinition"`
RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
Invalid bool `xml:"invalid,attr,omitempty"`
SaveData bool `xml:"saveData,attr"`
RefreshOnLoad bool `xml:"refreshOnLoad,attr,omitempty"`
OptimizeMemory bool `xml:"optimizeMemory,attr,omitempty"`
EnableRefresh bool `xml:"enableRefresh,attr,omitempty"`
RefreshedBy string `xml:"refreshedBy,attr,omitempty"`
RefreshedDate float64 `xml:"refreshedDate,attr,omitempty"`
RefreshedDateIso float64 `xml:"refreshedDateIso,attr,omitempty"`
BackgroundQuery bool `xml:"backgroundQuery,attr"`
MissingItemsLimit int `xml:"missingItemsLimit,attr,omitempty"`
CreatedVersion int `xml:"createdVersion,attr,omitempty"`
RefreshedVersion int `xml:"refreshedVersion,attr,omitempty"`
MinRefreshableVersion int `xml:"minRefreshableVersion,attr,omitempty"`
RecordCount int `xml:"recordCount,attr,omitempty"`
UpgradeOnRefresh bool `xml:"upgradeOnRefresh,attr,omitempty"`
TupleCacheAttr bool `xml:"tupleCache,attr,omitempty"`
SupportSubquery bool `xml:"supportSubquery,attr,omitempty"`
SupportAdvancedDrill bool `xml:"supportAdvancedDrill,attr,omitempty"`
CacheSource *xlsxCacheSource `xml:"cacheSource"`
CacheFields *xlsxCacheFields `xml:"cacheFields"`
CacheHierarchies *xlsxCacheHierarchies `xml:"cacheHierarchies"`
Kpis *xlsxKpis `xml:"kpis"`
TupleCache *xlsxTupleCache `xml:"tupleCache"`
CalculatedItems *xlsxCalculatedItems `xml:"calculatedItems"`
CalculatedMembers *xlsxCalculatedMembers `xml:"calculatedMembers"`
Dimensions *xlsxDimensions `xml:"dimensions"`
MeasureGroups *xlsxMeasureGroups `xml:"measureGroups"`
Maps *xlsxMaps `xml:"maps"`
ExtLst *xlsxExtLst `xml:"extLst"`
}

// xlsxCacheSource represents the description of data source whose data is
// stored in the pivot cache. The data source refers to the underlying rows or
// database records that provide the data for a PivotTable. You can create a
// PivotTable report from a SpreadsheetML table, an external database
// (including OLAP cubes), multiple SpreadsheetML worksheets, or another
// PivotTable.
type xlsxCacheSource struct {
Type string `xml:"type,attr"`
ConnectionId int `xml:"connectionId,attr,omitempty"`
WorksheetSource *xlsxWorksheetSource `xml:"worksheetSource"`
Consolidation *xlsxConsolidation `xml:"consolidation"`
ExtLst *xlsxExtLst `xml:"extLst"`
}

// xlsxWorksheetSource represents the location of the source of the data that
// is stored in the cache.
type xlsxWorksheetSource struct {
RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
Ref string `xml:"ref,attr,omitempty"`
Name string `xml:"name,attr,omitempty"`
Sheet string `xml:"sheet,attr,omitempty"`
}

// xlsxConsolidation represents the description of the PivotCache source using
// multiple consolidation ranges. This element is used when the source of the
// PivotTable is a collection of ranges in the workbook. The ranges are
// specified in the rangeSets collection. The logic for how the application
// consolidates the data in the ranges is application- defined.
type xlsxConsolidation struct {
}

// xlsxCacheFields represents the collection of field definitions in the
// source data.
type xlsxCacheFields struct {
Count int `xml:"count,attr"`
CacheField []*xlsxCacheField `xml:"cacheField"`
}

// xlsxCacheField represent a single field in the PivotCache. This definition
// contains information about the field, such as its source, data type, and
// location within a level or hierarchy. The sharedItems element stores
// additional information about the data in this field. If there are no shared
// items, then values are stored directly in the pivotCacheRecords part.
type xlsxCacheField struct {
Name string `xml:"name,attr"`
Caption string `xml:"caption,attr,omitempty"`
PropertyName string `xml:"propertyName,attr,omitempty"`
ServerField bool `xml:"serverField,attr,omitempty"`
UniqueList bool `xml:"uniqueList,attr,omitempty"`
NumFmtId int `xml:"numFmtId,attr"`
Formula string `xml:"formula,attr,omitempty"`
SQLType int `xml:"sqlType,attr,omitempty"`
Hierarchy int `xml:"hierarchy,attr,omitempty"`
Level int `xml:"level,attr,omitempty"`
DatabaseField bool `xml:"databaseField,attr,omitempty"`
MappingCount int `xml:"mappingCount,attr,omitempty"`
MemberPropertyField bool `xml:"memberPropertyField,attr,omitempty"`
SharedItems *xlsxSharedItems `xml:"sharedItems"`
FieldGroup *xlsxFieldGroup `xml:"fieldGroup"`
MpMap *xlsxX `xml:"mpMap"`
ExtLst *xlsxExtLst `xml:"extLst"`
}

// xlsxSharedItems represents the collection of unique items for a field in
// the PivotCacheDefinition. The sharedItems complex type stores data type and
// formatting information about the data in a field. Items in the
// PivotCacheDefinition can be shared in order to reduce the redundancy of
// those values that are referenced in multiple places across all the
// PivotTable parts.
type xlsxSharedItems struct {
ContainsSemiMixedTypes bool `xml:"containsSemiMixedTypes,attr,omitempty"`
ContainsNonDate bool `xml:"containsNonDate,attr,omitempty"`
ContainsDate bool `xml:"containsDate,attr,omitempty"`
ContainsString bool `xml:"containsString,attr,omitempty"`
ContainsBlank bool `xml:"containsBlank,attr,omitempty"`
ContainsMixedTypes bool `xml:"containsMixedTypes,attr,omitempty"`
ContainsNumber bool `xml:"containsNumber,attr,omitempty"`
ContainsInteger bool `xml:"containsInteger,attr,omitempty"`
MinValue float64 `xml:"minValue,attr,omitempty"`
MaxValue float64 `xml:"maxValue,attr,omitempty"`
MinDate string `xml:"minDate,attr,omitempty"`
MaxDate string `xml:"maxDate,attr,omitempty"`
Count int `xml:"count,attr"`
LongText bool `xml:"longText,attr,omitempty"`
M *xlsxMissing `xml:"m"`
N *xlsxNumber `xml:"n"`
B *xlsxBoolean `xml:"b"`
E *xlsxError `xml:"e"`
S *xlsxString `xml:"s"`
D *xlsxDateTime `xml:"d"`
}

// xlsxMissing represents a value that was not specified.
type xlsxMissing struct {
}

// xlsxNumber represents a numeric value in the PivotTable.
type xlsxNumber struct {
V float64 `xml:"v,attr"`
U bool `xml:"u,attr,omitempty"`
F bool `xml:"f,attr,omitempty"`
C string `xml:"c,attr,omitempty"`
Cp int `xml:"cp,attr,omitempty"`
In int `xml:"in,attr,omitempty"`
Bc string `xml:"bc,attr,omitempty"`
Fc string `xml:"fc,attr,omitempty"`
I bool `xml:"i,attr,omitempty"`
Un bool `xml:"un,attr,omitempty"`
St bool `xml:"st,attr,omitempty"`
B bool `xml:"b,attr,omitempty"`
Tpls *xlsxTuples `xml:"tpls"`
X *attrValInt `xml:"x"`
}

// xlsxTuples represents members for the OLAP sheet data entry, also known as
// a tuple.
type xlsxTuples struct {
}

// xlsxBoolean represents a boolean value for an item in the PivotTable.
type xlsxBoolean struct {
}

// xlsxError represents an error value. The use of this item indicates that an
// error value is present in the PivotTable source. The error is recorded in
// the value attribute.
type xlsxError struct {
}

// xlsxString represents a character value in a PivotTable.
type xlsxString struct {
}

// xlsxDateTime represents a date-time value in the PivotTable.
type xlsxDateTime struct {
}

// xlsxFieldGroup represents the collection of properties for a field group.
type xlsxFieldGroup struct {
}

// xlsxCacheHierarchies represents the collection of OLAP hierarchies in the
// PivotCache.
type xlsxCacheHierarchies struct {
}

// xlsxKpis represents the collection of Key Performance Indicators (KPIs)
// defined on the OLAP server and stored in the PivotCache.
type xlsxKpis struct {
}

// xlsxTupleCache represents the cache of OLAP sheet data members, or tuples.
type xlsxTupleCache struct {
}

// xlsxCalculatedItems represents the collection of calculated items.
type xlsxCalculatedItems struct {
}

// xlsxCalculatedMembers represents the collection of calculated members in an
// OLAP PivotTable.
type xlsxCalculatedMembers struct {
}

// xlsxDimensions represents the collection of PivotTable OLAP dimensions.
type xlsxDimensions struct {
}

// xlsxMeasureGroups represents the collection of PivotTable OLAP measure
// groups.
type xlsxMeasureGroups struct {
}

// xlsxMaps represents the PivotTable OLAP measure group - Dimension maps.
type xlsxMaps struct {
}
294 changes: 294 additions & 0 deletions xmlPivotTable.go

Large diffs are not rendered by default.

18 changes: 16 additions & 2 deletions xmlSharedStrings.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "encoding/xml"
import (
"encoding/xml"
"strings"
)

// xlsxSST directly maps the sst element from the namespace
// http://schemas.openxmlformats.org/spreadsheetml/2006/main. String values may
Expand All @@ -33,6 +36,17 @@ type xlsxSI struct {
R []xlsxR `xml:"r"`
}

func (x xlsxSI) String() string {
if len(x.R) > 0 {
var rows strings.Builder
for _, s := range x.R {
rows.WriteString(s.T)
}
return rows.String()
}
return x.T
}

// xlsxR directly maps the r element from the namespace
// http://schemas.openxmlformats.org/spreadsheetml/2006/main - currently I have
// not checked this for completeness - it does as much as I need.
Expand Down
50 changes: 23 additions & 27 deletions xmlStyles.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down Expand Up @@ -82,30 +82,25 @@ type xlsxFonts struct {
Font []*xlsxFont `xml:"font"`
}

// font directly maps the font element.
type font struct {
// xlsxFont directly maps the font element. This element defines the
// properties for one of the fonts used in this workbook.
type xlsxFont struct {
B *bool `xml:"b,omitempty"`
I *bool `xml:"i,omitempty"`
Strike *bool `xml:"strike,omitempty"`
Outline *bool `xml:"outline,omitempty"`
Shadow *bool `xml:"shadow,omitempty"`
Condense *bool `xml:"condense,omitempty"`
Extend *bool `xml:"extend,omitempty"`
U *attrValString `xml:"u"`
Sz *attrValFloat `xml:"sz"`
Color *xlsxColor `xml:"color"`
Name *attrValString `xml:"name"`
Charset *attrValInt `xml:"charset"`
Family *attrValInt `xml:"family"`
B bool `xml:"b,omitempty"`
I bool `xml:"i,omitempty"`
Strike bool `xml:"strike,omitempty"`
Outline bool `xml:"outline,omitempty"`
Shadow bool `xml:"shadow,omitempty"`
Condense bool `xml:"condense,omitempty"`
Extend bool `xml:"extend,omitempty"`
Color *xlsxColor `xml:"color"`
Sz *attrValInt `xml:"sz"`
U *attrValString `xml:"u"`
Charset *attrValInt `xml:"charset"`
Scheme *attrValString `xml:"scheme"`
}

// xlsxFont directly maps the font element. This element defines the properties
// for one of the fonts used in this workbook.
type xlsxFont struct {
Font string `xml:",innerxml"`
}

// xlsxFills directly maps the fills element. This element defines the cell
// fills portion of the Styles part, consisting of a sequence of fill records. A
// cell fill consists of a background color, foreground color, and pattern to be
Expand Down Expand Up @@ -262,7 +257,7 @@ type xlsxDxf struct {

// dxf directly maps the dxf element.
type dxf struct {
Font *font `xml:"font"`
Font *xlsxFont `xml:"font"`
NumFmt *xlsxNumFmt `xml:"numFmt"`
Fill *xlsxFill `xml:"fill"`
Alignment *xlsxAlignment `xml:"alignment"`
Expand Down Expand Up @@ -320,12 +315,13 @@ type xlsxStyleColors struct {

// formatFont directly maps the styles settings of the fonts.
type formatFont struct {
Bold bool `json:"bold"`
Italic bool `json:"italic"`
Underline string `json:"underline"`
Family string `json:"family"`
Size int `json:"size"`
Color string `json:"color"`
Bold bool `json:"bold"`
Italic bool `json:"italic"`
Underline string `json:"underline"`
Family string `json:"family"`
Size float64 `json:"size"`
Strike bool `json:"strike"`
Color string `json:"color"`
}

// formatStyle directly maps the styles settings of the cells.
Expand Down
2 changes: 1 addition & 1 deletion xmlTable.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down
2 changes: 1 addition & 1 deletion xmlTheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

Expand Down
30 changes: 19 additions & 11 deletions xmlWorkbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.8 or later.
// charts of XLSX. This library needs Go version 1.10 or later.

package excelize

import "encoding/xml"

// xmlxWorkbookRels contains xmlxWorkbookRelations which maps sheet id and sheet XML.
type xlsxWorkbookRels struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
Relationships []xlsxWorkbookRelation `xml:"Relationship"`
// xlsxRelationships describe references from parts to other internal resources in the package or to external resources.
type xlsxRelationships struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
Relationships []xlsxRelationship `xml:"Relationship"`
}

// xmlxWorkbookRelation maps sheet id and xl/worksheets/_rels/sheet%d.xml.rels
type xlsxWorkbookRelation struct {
// xlsxRelationship contains relations which maps id and XML.
type xlsxRelationship struct {
ID string `xml:"Id,attr"`
Target string `xml:",attr"`
Type string `xml:",attr"`
Expand Down Expand Up @@ -146,9 +146,8 @@ type xlsxSheets struct {
Sheet []xlsxSheet `xml:"sheet"`
}

// xlsxSheet directly maps the sheet element from the namespace
// http://schemas.openxmlformats.org/spreadsheetml/2006/main - currently I have
// not checked it for completeness - it does as much as I need.
// xlsxSheet defines a sheet in this workbook. Sheet data is stored in a
// separate part.
type xlsxSheet struct {
Name string `xml:"name,attr,omitempty"`
SheetID int `xml:"sheetId,attr,omitempty"`
Expand Down Expand Up @@ -176,7 +175,7 @@ type xlsxPivotCaches struct {

// xlsxPivotCache directly maps the pivotCache element.
type xlsxPivotCache struct {
CacheID int `xml:"cacheId,attr,omitempty"`
CacheID int `xml:"cacheId,attr"`
RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
}

Expand Down Expand Up @@ -289,3 +288,12 @@ type xlsxCustomWorkbookView struct {
XWindow *int `xml:"xWindow,attr"`
YWindow *int `xml:"yWindow,attr"`
}

// DefinedName directly maps the name for a cell or cell range on a
// worksheet.
type DefinedName struct {
Name string
Comment string
RefersTo string
Scope string
}
292 changes: 233 additions & 59 deletions xmlWorksheet.go

Large diffs are not rendered by default.