forked from p30928647/excelize
Breaking change: changed the third parameter for the `AddFilter`
- Support to add multiple filter columns - Remove the exported type `AutoFilterListOptions` - Support to specify if show header row of the table - Update unit tests and documents of the function
This commit is contained in:
parent
f707b2d2da
commit
dc3bf331d5
|
@ -252,7 +252,7 @@ func (f *File) adjustTable(ws *xlsxWorksheet, sheet string, dir adjustDirection,
|
||||||
if t.AutoFilter != nil {
|
if t.AutoFilter != nil {
|
||||||
t.AutoFilter.Ref = t.Ref
|
t.AutoFilter.Ref = t.Ref
|
||||||
}
|
}
|
||||||
_, _ = f.setTableHeader(sheet, x1, y1, x2)
|
_, _ = f.setTableHeader(sheet, true, x1, y1, x2)
|
||||||
table, _ := xml.Marshal(t)
|
table, _ := xml.Marshal(t)
|
||||||
f.saveFileList(tableXML, table)
|
f.saveFileList(tableXML, table)
|
||||||
}
|
}
|
||||||
|
|
|
@ -412,7 +412,7 @@ func TestInsertCols(t *testing.T) {
|
||||||
assert.NoError(t, f.SetCellHyperLink(sheet1, "A5", "https://github.com/xuri/excelize", "External"))
|
assert.NoError(t, f.SetCellHyperLink(sheet1, "A5", "https://github.com/xuri/excelize", "External"))
|
||||||
assert.NoError(t, f.MergeCell(sheet1, "A1", "C3"))
|
assert.NoError(t, f.MergeCell(sheet1, "A1", "C3"))
|
||||||
|
|
||||||
assert.NoError(t, f.AutoFilter(sheet1, "A2:B2", &AutoFilterOptions{Column: "B", Expression: "x != blanks"}))
|
assert.NoError(t, f.AutoFilter(sheet1, "A2:B2", []AutoFilterOptions{{Column: "B", Expression: "x != blanks"}}))
|
||||||
assert.NoError(t, f.InsertCols(sheet1, "A", 1))
|
assert.NoError(t, f.InsertCols(sheet1, "A", 1))
|
||||||
|
|
||||||
// Test insert column with illegal cell reference
|
// Test insert column with illegal cell reference
|
||||||
|
|
|
@ -320,7 +320,7 @@ func TestRemoveRow(t *testing.T) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = f.AutoFilter(sheet1, "A2:A2", &AutoFilterOptions{Column: "A", Expression: "x != blanks"})
|
err = f.AutoFilter(sheet1, "A2:A2", []AutoFilterOptions{{Column: "A", Expression: "x != blanks"}})
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
98
table.go
98
table.go
|
@ -131,7 +131,7 @@ func (f *File) addSheetTable(sheet string, rID int) error {
|
||||||
|
|
||||||
// setTableHeader provides a function to set cells value in header row for the
|
// setTableHeader provides a function to set cells value in header row for the
|
||||||
// table.
|
// table.
|
||||||
func (f *File) setTableHeader(sheet string, x1, y1, x2 int) ([]*xlsxTableColumn, error) {
|
func (f *File) setTableHeader(sheet string, showHeaderRow bool, x1, y1, x2 int) ([]*xlsxTableColumn, error) {
|
||||||
var (
|
var (
|
||||||
tableColumns []*xlsxTableColumn
|
tableColumns []*xlsxTableColumn
|
||||||
idx int
|
idx int
|
||||||
|
@ -144,11 +144,15 @@ func (f *File) setTableHeader(sheet string, x1, y1, x2 int) ([]*xlsxTableColumn,
|
||||||
}
|
}
|
||||||
name, _ := f.GetCellValue(sheet, cell)
|
name, _ := f.GetCellValue(sheet, cell)
|
||||||
if _, err := strconv.Atoi(name); err == nil {
|
if _, err := strconv.Atoi(name); err == nil {
|
||||||
_ = f.SetCellStr(sheet, cell, name)
|
if showHeaderRow {
|
||||||
|
_ = f.SetCellStr(sheet, cell, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = "Column" + strconv.Itoa(idx)
|
name = "Column" + strconv.Itoa(idx)
|
||||||
_ = f.SetCellStr(sheet, cell, name)
|
if showHeaderRow {
|
||||||
|
_ = f.SetCellStr(sheet, cell, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tableColumns = append(tableColumns, &xlsxTableColumn{
|
tableColumns = append(tableColumns, &xlsxTableColumn{
|
||||||
ID: idx,
|
ID: idx,
|
||||||
|
@ -188,13 +192,16 @@ func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, opts *Tab
|
||||||
if y1 == y2 {
|
if y1 == y2 {
|
||||||
y2++
|
y2++
|
||||||
}
|
}
|
||||||
|
hideHeaderRow := opts != nil && opts.ShowHeaderRow != nil && !*opts.ShowHeaderRow
|
||||||
|
if hideHeaderRow {
|
||||||
|
y1++
|
||||||
|
}
|
||||||
// Correct table range reference, such correct C1:B3 to B1:C3.
|
// Correct table range reference, such correct C1:B3 to B1:C3.
|
||||||
ref, err := f.coordinatesToRangeRef([]int{x1, y1, x2, y2})
|
ref, err := f.coordinatesToRangeRef([]int{x1, y1, x2, y2})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tableColumns, _ := f.setTableHeader(sheet, x1, y1, x2)
|
tableColumns, _ := f.setTableHeader(sheet, !hideHeaderRow, x1, y1, x2)
|
||||||
name := opts.Name
|
name := opts.Name
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = "Table" + strconv.Itoa(i)
|
name = "Table" + strconv.Itoa(i)
|
||||||
|
@ -220,6 +227,10 @@ func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, opts *Tab
|
||||||
ShowColumnStripes: opts.ShowColumnStripes,
|
ShowColumnStripes: opts.ShowColumnStripes,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if hideHeaderRow {
|
||||||
|
t.AutoFilter = nil
|
||||||
|
t.HeaderRowCount = intPtr(0)
|
||||||
|
}
|
||||||
table, _ := xml.Marshal(t)
|
table, _ := xml.Marshal(t)
|
||||||
f.saveFileList(tableXML, table)
|
f.saveFileList(tableXML, table)
|
||||||
return nil
|
return nil
|
||||||
|
@ -230,12 +241,12 @@ func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, opts *Tab
|
||||||
// way of filtering a 2D range of data based on some simple criteria. For
|
// way of filtering a 2D range of data based on some simple criteria. For
|
||||||
// example applying an auto filter to a cell range A1:D4 in the Sheet1:
|
// example applying an auto filter to a cell range A1:D4 in the Sheet1:
|
||||||
//
|
//
|
||||||
// err := f.AutoFilter("Sheet1", "A1:D4", nil)
|
// err := f.AutoFilter("Sheet1", "A1:D4", []excelize.AutoFilterOptions{})
|
||||||
//
|
//
|
||||||
// Filter data in an auto filter:
|
// Filter data in an auto filter:
|
||||||
//
|
//
|
||||||
// err := f.AutoFilter("Sheet1", "A1:D4", &excelize.AutoFilterOptions{
|
// err := f.AutoFilter("Sheet1", "A1:D4", []excelize.AutoFilterOptions{
|
||||||
// Column: "B", Expression: "x != blanks",
|
// {Column: "B", Expression: "x != blanks"},
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// Column defines the filter columns in an auto filter range based on simple
|
// Column defines the filter columns in an auto filter range based on simple
|
||||||
|
@ -296,7 +307,7 @@ func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, opts *Tab
|
||||||
// x < 2000
|
// x < 2000
|
||||||
// col < 2000
|
// col < 2000
|
||||||
// Price < 2000
|
// Price < 2000
|
||||||
func (f *File) AutoFilter(sheet, rangeRef string, opts *AutoFilterOptions) error {
|
func (f *File) AutoFilter(sheet, rangeRef string, opts []AutoFilterOptions) error {
|
||||||
coordinates, err := rangeRefToCoordinates(rangeRef)
|
coordinates, err := rangeRefToCoordinates(rangeRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -343,7 +354,7 @@ func (f *File) AutoFilter(sheet, rangeRef string, opts *AutoFilterOptions) error
|
||||||
|
|
||||||
// autoFilter provides a function to extract the tokens from the filter
|
// autoFilter provides a function to extract the tokens from the filter
|
||||||
// expression. The tokens are mainly non-whitespace groups.
|
// expression. The tokens are mainly non-whitespace groups.
|
||||||
func (f *File) autoFilter(sheet, ref string, columns, col int, opts *AutoFilterOptions) error {
|
func (f *File) autoFilter(sheet, ref string, columns, col int, opts []AutoFilterOptions) error {
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -356,66 +367,65 @@ func (f *File) autoFilter(sheet, ref string, columns, col int, opts *AutoFilterO
|
||||||
Ref: ref,
|
Ref: ref,
|
||||||
}
|
}
|
||||||
ws.AutoFilter = filter
|
ws.AutoFilter = filter
|
||||||
if opts == nil || opts.Column == "" || opts.Expression == "" {
|
for _, opt := range opts {
|
||||||
return nil
|
if opt.Column == "" || opt.Expression == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fsCol, err := ColumnNameToNumber(opt.Column)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
offset := fsCol - col
|
||||||
|
if offset < 0 || offset > columns {
|
||||||
|
return fmt.Errorf("incorrect index of column '%s'", opt.Column)
|
||||||
|
}
|
||||||
|
fc := &xlsxFilterColumn{ColID: offset}
|
||||||
|
re := regexp.MustCompile(`"(?:[^"]|"")*"|\S+`)
|
||||||
|
token := re.FindAllString(opt.Expression, -1)
|
||||||
|
if len(token) != 3 && len(token) != 7 {
|
||||||
|
return fmt.Errorf("incorrect number of tokens in criteria '%s'", opt.Expression)
|
||||||
|
}
|
||||||
|
expressions, tokens, err := f.parseFilterExpression(opt.Expression, token)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.writeAutoFilter(fc, expressions, tokens)
|
||||||
|
filter.FilterColumn = append(filter.FilterColumn, fc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fsCol, err := ColumnNameToNumber(opts.Column)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
offset := fsCol - col
|
|
||||||
if offset < 0 || offset > columns {
|
|
||||||
return fmt.Errorf("incorrect index of column '%s'", opts.Column)
|
|
||||||
}
|
|
||||||
|
|
||||||
filter.FilterColumn = append(filter.FilterColumn, &xlsxFilterColumn{
|
|
||||||
ColID: offset,
|
|
||||||
})
|
|
||||||
re := regexp.MustCompile(`"(?:[^"]|"")*"|\S+`)
|
|
||||||
token := re.FindAllString(opts.Expression, -1)
|
|
||||||
if len(token) != 3 && len(token) != 7 {
|
|
||||||
return fmt.Errorf("incorrect number of tokens in criteria '%s'", opts.Expression)
|
|
||||||
}
|
|
||||||
expressions, tokens, err := f.parseFilterExpression(opts.Expression, token)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.writeAutoFilter(filter, expressions, tokens)
|
|
||||||
ws.AutoFilter = filter
|
ws.AutoFilter = filter
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeAutoFilter provides a function to check for single or double custom
|
// writeAutoFilter provides a function to check for single or double custom
|
||||||
// filters as default filters and handle them accordingly.
|
// filters as default filters and handle them accordingly.
|
||||||
func (f *File) writeAutoFilter(filter *xlsxAutoFilter, exp []int, tokens []string) {
|
func (f *File) writeAutoFilter(fc *xlsxFilterColumn, exp []int, tokens []string) {
|
||||||
if len(exp) == 1 && exp[0] == 2 {
|
if len(exp) == 1 && exp[0] == 2 {
|
||||||
// Single equality.
|
// Single equality.
|
||||||
var filters []*xlsxFilter
|
var filters []*xlsxFilter
|
||||||
filters = append(filters, &xlsxFilter{Val: tokens[0]})
|
filters = append(filters, &xlsxFilter{Val: tokens[0]})
|
||||||
filter.FilterColumn[0].Filters = &xlsxFilters{Filter: filters}
|
fc.Filters = &xlsxFilters{Filter: filters}
|
||||||
} else if len(exp) == 3 && exp[0] == 2 && exp[1] == 1 && exp[2] == 2 {
|
} else if len(exp) == 3 && exp[0] == 2 && exp[1] == 1 && exp[2] == 2 {
|
||||||
// Double equality with "or" operator.
|
// Double equality with "or" operator.
|
||||||
var filters []*xlsxFilter
|
var filters []*xlsxFilter
|
||||||
for _, v := range tokens {
|
for _, v := range tokens {
|
||||||
filters = append(filters, &xlsxFilter{Val: v})
|
filters = append(filters, &xlsxFilter{Val: v})
|
||||||
}
|
}
|
||||||
filter.FilterColumn[0].Filters = &xlsxFilters{Filter: filters}
|
fc.Filters = &xlsxFilters{Filter: filters}
|
||||||
} else {
|
} else {
|
||||||
// Non default custom filter.
|
// Non default custom filter.
|
||||||
expRel := map[int]int{0: 0, 1: 2}
|
expRel := map[int]int{0: 0, 1: 2}
|
||||||
andRel := map[int]bool{0: true, 1: false}
|
andRel := map[int]bool{0: true, 1: false}
|
||||||
for k, v := range tokens {
|
for k, v := range tokens {
|
||||||
f.writeCustomFilter(filter, exp[expRel[k]], v)
|
f.writeCustomFilter(fc, exp[expRel[k]], v)
|
||||||
if k == 1 {
|
if k == 1 {
|
||||||
filter.FilterColumn[0].CustomFilters.And = andRel[exp[k]]
|
fc.CustomFilters.And = andRel[exp[k]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeCustomFilter provides a function to write the <customFilter> element.
|
// writeCustomFilter provides a function to write the <customFilter> element.
|
||||||
func (f *File) writeCustomFilter(filter *xlsxAutoFilter, operator int, val string) {
|
func (f *File) writeCustomFilter(fc *xlsxFilterColumn, operator int, val string) {
|
||||||
operators := map[int]string{
|
operators := map[int]string{
|
||||||
1: "lessThan",
|
1: "lessThan",
|
||||||
2: "equal",
|
2: "equal",
|
||||||
|
@ -429,12 +439,12 @@ func (f *File) writeCustomFilter(filter *xlsxAutoFilter, operator int, val strin
|
||||||
Operator: operators[operator],
|
Operator: operators[operator],
|
||||||
Val: val,
|
Val: val,
|
||||||
}
|
}
|
||||||
if filter.FilterColumn[0].CustomFilters != nil {
|
if fc.CustomFilters != nil {
|
||||||
filter.FilterColumn[0].CustomFilters.CustomFilter = append(filter.FilterColumn[0].CustomFilters.CustomFilter, &customFilter)
|
fc.CustomFilters.CustomFilter = append(fc.CustomFilters.CustomFilter, &customFilter)
|
||||||
} else {
|
} else {
|
||||||
var customFilters []*xlsxCustomFilter
|
var customFilters []*xlsxCustomFilter
|
||||||
customFilters = append(customFilters, &customFilter)
|
customFilters = append(customFilters, &customFilter)
|
||||||
filter.FilterColumn[0].CustomFilters = &xlsxCustomFilters{CustomFilter: customFilters}
|
fc.CustomFilters = &xlsxCustomFilters{CustomFilter: customFilters}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,14 @@ func TestAddTable(t *testing.T) {
|
||||||
assert.NoError(t, f.AddTable("Sheet2", "A2:B5", &TableOptions{
|
assert.NoError(t, f.AddTable("Sheet2", "A2:B5", &TableOptions{
|
||||||
Name: "table",
|
Name: "table",
|
||||||
StyleName: "TableStyleMedium2",
|
StyleName: "TableStyleMedium2",
|
||||||
|
ShowColumnStripes: true,
|
||||||
ShowFirstColumn: true,
|
ShowFirstColumn: true,
|
||||||
ShowLastColumn: true,
|
ShowLastColumn: true,
|
||||||
ShowRowStripes: boolPtr(true),
|
ShowRowStripes: boolPtr(true),
|
||||||
ShowColumnStripes: true,
|
}))
|
||||||
},
|
assert.NoError(t, f.AddTable("Sheet2", "D1:D11", &TableOptions{
|
||||||
))
|
ShowHeaderRow: boolPtr(false),
|
||||||
|
}))
|
||||||
assert.NoError(t, f.AddTable("Sheet2", "F1:F1", &TableOptions{StyleName: "TableStyleMedium8"}))
|
assert.NoError(t, f.AddTable("Sheet2", "F1:F1", &TableOptions{StyleName: "TableStyleMedium8"}))
|
||||||
|
|
||||||
// Test add table in not exist worksheet
|
// Test add table in not exist worksheet
|
||||||
|
@ -60,7 +62,7 @@ func TestAddTable(t *testing.T) {
|
||||||
|
|
||||||
func TestSetTableHeader(t *testing.T) {
|
func TestSetTableHeader(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
_, err := f.setTableHeader("Sheet1", 1, 0, 1)
|
_, err := f.setTableHeader("Sheet1", true, 1, 0, 1)
|
||||||
assert.EqualError(t, err, "invalid cell reference [1, 0]")
|
assert.EqualError(t, err, "invalid cell reference [1, 0]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,16 +70,16 @@ func TestAutoFilter(t *testing.T) {
|
||||||
outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")
|
outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")
|
||||||
f, err := prepareTestBook1()
|
f, err := prepareTestBook1()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for i, opts := range []*AutoFilterOptions{
|
for i, opts := range [][]AutoFilterOptions{
|
||||||
nil,
|
{},
|
||||||
{Column: "B", Expression: ""},
|
{{Column: "B", Expression: ""}},
|
||||||
{Column: "B", Expression: "x != blanks"},
|
{{Column: "B", Expression: "x != blanks"}},
|
||||||
{Column: "B", Expression: "x == blanks"},
|
{{Column: "B", Expression: "x == blanks"}},
|
||||||
{Column: "B", Expression: "x != nonblanks"},
|
{{Column: "B", Expression: "x != nonblanks"}},
|
||||||
{Column: "B", Expression: "x == nonblanks"},
|
{{Column: "B", Expression: "x == nonblanks"}},
|
||||||
{Column: "B", Expression: "x <= 1 and x >= 2"},
|
{{Column: "B", Expression: "x <= 1 and x >= 2"}},
|
||||||
{Column: "B", Expression: "x == 1 or x == 2"},
|
{{Column: "B", Expression: "x == 1 or x == 2"}},
|
||||||
{Column: "B", Expression: "x == 1 or x == 2*"},
|
{{Column: "B", Expression: "x == 1 or x == 2*"}},
|
||||||
} {
|
} {
|
||||||
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
|
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
|
||||||
assert.NoError(t, f.AutoFilter("Sheet1", "D4:B1", opts))
|
assert.NoError(t, f.AutoFilter("Sheet1", "D4:B1", opts))
|
||||||
|
@ -100,13 +102,13 @@ func TestAutoFilterError(t *testing.T) {
|
||||||
outFile := filepath.Join("test", "TestAutoFilterError%d.xlsx")
|
outFile := filepath.Join("test", "TestAutoFilterError%d.xlsx")
|
||||||
f, err := prepareTestBook1()
|
f, err := prepareTestBook1()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for i, opts := range []*AutoFilterOptions{
|
for i, opts := range [][]AutoFilterOptions{
|
||||||
{Column: "B", Expression: "x <= 1 and x >= blanks"},
|
{{Column: "B", Expression: "x <= 1 and x >= blanks"}},
|
||||||
{Column: "B", Expression: "x -- y or x == *2*"},
|
{{Column: "B", Expression: "x -- y or x == *2*"}},
|
||||||
{Column: "B", Expression: "x != y or x ? *2"},
|
{{Column: "B", Expression: "x != y or x ? *2"}},
|
||||||
{Column: "B", Expression: "x -- y o r x == *2"},
|
{{Column: "B", Expression: "x -- y o r x == *2"}},
|
||||||
{Column: "B", Expression: "x -- y"},
|
{{Column: "B", Expression: "x -- y"}},
|
||||||
{Column: "A", Expression: "x -- y"},
|
{{Column: "A", Expression: "x -- y"}},
|
||||||
} {
|
} {
|
||||||
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
|
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
|
||||||
if assert.Error(t, f.AutoFilter("Sheet2", "D4:B1", opts)) {
|
if assert.Error(t, f.AutoFilter("Sheet2", "D4:B1", opts)) {
|
||||||
|
@ -115,22 +117,22 @@ func TestAutoFilterError(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.EqualError(t, f.autoFilter("SheetN", "A1", 1, 1, &AutoFilterOptions{
|
assert.EqualError(t, f.autoFilter("SheetN", "A1", 1, 1, []AutoFilterOptions{{
|
||||||
Column: "A",
|
Column: "A",
|
||||||
Expression: "",
|
Expression: "",
|
||||||
}), "sheet SheetN does not exist")
|
}}), "sheet SheetN does not exist")
|
||||||
assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 1, &AutoFilterOptions{
|
assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 1, []AutoFilterOptions{{
|
||||||
Column: "-",
|
Column: "-",
|
||||||
Expression: "-",
|
Expression: "-",
|
||||||
}), newInvalidColumnNameError("-").Error())
|
}}), newInvalidColumnNameError("-").Error())
|
||||||
assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 100, &AutoFilterOptions{
|
assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 100, []AutoFilterOptions{{
|
||||||
Column: "A",
|
Column: "A",
|
||||||
Expression: "-",
|
Expression: "-",
|
||||||
}), `incorrect index of column 'A'`)
|
}}), `incorrect index of column 'A'`)
|
||||||
assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 1, &AutoFilterOptions{
|
assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 1, []AutoFilterOptions{{
|
||||||
Column: "A",
|
Column: "A",
|
||||||
Expression: "-",
|
Expression: "-",
|
||||||
}), `incorrect number of tokens in criteria '-'`)
|
}}), `incorrect number of tokens in criteria '-'`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseFilterTokens(t *testing.T) {
|
func TestParseFilterTokens(t *testing.T) {
|
||||||
|
|
12
xmlTable.go
12
xmlTable.go
|
@ -26,7 +26,7 @@ type xlsxTable struct {
|
||||||
DisplayName string `xml:"displayName,attr,omitempty"`
|
DisplayName string `xml:"displayName,attr,omitempty"`
|
||||||
HeaderRowBorderDxfID int `xml:"headerRowBorderDxfId,attr,omitempty"`
|
HeaderRowBorderDxfID int `xml:"headerRowBorderDxfId,attr,omitempty"`
|
||||||
HeaderRowCellStyle string `xml:"headerRowCellStyle,attr,omitempty"`
|
HeaderRowCellStyle string `xml:"headerRowCellStyle,attr,omitempty"`
|
||||||
HeaderRowCount int `xml:"headerRowCount,attr,omitempty"`
|
HeaderRowCount *int `xml:"headerRowCount,attr"`
|
||||||
HeaderRowDxfID int `xml:"headerRowDxfId,attr,omitempty"`
|
HeaderRowDxfID int `xml:"headerRowDxfId,attr,omitempty"`
|
||||||
ID int `xml:"id,attr"`
|
ID int `xml:"id,attr"`
|
||||||
InsertRow bool `xml:"insertRow,attr,omitempty"`
|
InsertRow bool `xml:"insertRow,attr,omitempty"`
|
||||||
|
@ -200,21 +200,15 @@ type xlsxTableStyleInfo struct {
|
||||||
type TableOptions struct {
|
type TableOptions struct {
|
||||||
Name string
|
Name string
|
||||||
StyleName string
|
StyleName string
|
||||||
|
ShowColumnStripes bool
|
||||||
ShowFirstColumn bool
|
ShowFirstColumn bool
|
||||||
|
ShowHeaderRow *bool
|
||||||
ShowLastColumn bool
|
ShowLastColumn bool
|
||||||
ShowRowStripes *bool
|
ShowRowStripes *bool
|
||||||
ShowColumnStripes bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// AutoFilterListOptions directly maps the auto filter list settings.
|
|
||||||
type AutoFilterListOptions struct {
|
|
||||||
Column string
|
|
||||||
Value []int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoFilterOptions directly maps the auto filter settings.
|
// AutoFilterOptions directly maps the auto filter settings.
|
||||||
type AutoFilterOptions struct {
|
type AutoFilterOptions struct {
|
||||||
Column string
|
Column string
|
||||||
Expression string
|
Expression string
|
||||||
FilterList []AutoFilterListOptions
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue