forked from p30928647/excelize
This improves compatibility for worksheet relative XML path and multi rules auto filter
This commit is contained in:
parent
3783d1d01b
commit
3648335d7f
18
sheet.go
18
sheet.go
|
@ -447,17 +447,17 @@ func (f *File) GetSheetList() (list []string) {
|
||||||
// getSheetMap provides a function to get worksheet name and XML file path map
|
// getSheetMap provides a function to get worksheet name and XML file path map
|
||||||
// of the spreadsheet.
|
// of the spreadsheet.
|
||||||
func (f *File) getSheetMap() map[string]string {
|
func (f *File) getSheetMap() map[string]string {
|
||||||
content := f.workbookReader()
|
|
||||||
rels := f.relsReader(f.getWorkbookRelsPath())
|
|
||||||
maps := map[string]string{}
|
maps := map[string]string{}
|
||||||
for _, v := range content.Sheets.Sheet {
|
for _, v := range f.workbookReader().Sheets.Sheet {
|
||||||
for _, rel := range rels.Relationships {
|
for _, rel := range f.relsReader(f.getWorkbookRelsPath()).Relationships {
|
||||||
if rel.ID == v.ID {
|
if rel.ID == v.ID {
|
||||||
// Construct a target XML as xl/worksheets/sheet%d by split path, compatible with different types of relative paths in workbook.xml.rels, for example: worksheets/sheet%d.xml and /xl/worksheets/sheet%d.xml
|
// Construct a target XML as xl/worksheets/sheet%d by split
|
||||||
pathInfo := strings.Split(rel.Target, "/")
|
// path, compatible with different types of relative paths in
|
||||||
pathInfoLen := len(pathInfo)
|
// workbook.xml.rels, for example: worksheets/sheet%d.xml
|
||||||
if pathInfoLen > 1 {
|
// and /xl/worksheets/sheet%d.xml
|
||||||
maps[v.Name] = fmt.Sprintf("xl/%s", strings.Join(pathInfo[pathInfoLen-2:], "/"))
|
path := filepath.ToSlash(strings.TrimPrefix(filepath.Clean(fmt.Sprintf("%s/%s", filepath.Dir(f.getWorkbookPath()), rel.Target)), "/"))
|
||||||
|
if _, ok := f.XLSX[path]; ok {
|
||||||
|
maps[v.Name] = path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ func TestStreamWriter(t *testing.T) {
|
||||||
file = NewFile()
|
file = NewFile()
|
||||||
streamWriter, err = file.NewStreamWriter("Sheet1")
|
streamWriter, err = file.NewStreamWriter("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for rowID := 10; rowID <= 51200; rowID++ {
|
for rowID := 10; rowID <= 25600; rowID++ {
|
||||||
row := make([]interface{}, 50)
|
row := make([]interface{}, 50)
|
||||||
for colID := 0; colID < 50; colID++ {
|
for colID := 0; colID < 50; colID++ {
|
||||||
row[colID] = rand.Intn(640000)
|
row[colID] = rand.Intn(640000)
|
||||||
|
|
16
table.go
16
table.go
|
@ -348,9 +348,9 @@ func (f *File) autoFilter(sheet, ref string, refRange, col int, formatSet *forma
|
||||||
return fmt.Errorf("incorrect index of column '%s'", formatSet.Column)
|
return fmt.Errorf("incorrect index of column '%s'", formatSet.Column)
|
||||||
}
|
}
|
||||||
|
|
||||||
filter.FilterColumn = &xlsxFilterColumn{
|
filter.FilterColumn = append(filter.FilterColumn, &xlsxFilterColumn{
|
||||||
ColID: offset,
|
ColID: offset,
|
||||||
}
|
})
|
||||||
re := regexp.MustCompile(`"(?:[^"]|"")*"|\S+`)
|
re := regexp.MustCompile(`"(?:[^"]|"")*"|\S+`)
|
||||||
token := re.FindAllString(formatSet.Expression, -1)
|
token := re.FindAllString(formatSet.Expression, -1)
|
||||||
if len(token) != 3 && len(token) != 7 {
|
if len(token) != 3 && len(token) != 7 {
|
||||||
|
@ -372,14 +372,14 @@ func (f *File) writeAutoFilter(filter *xlsxAutoFilter, exp []int, tokens []strin
|
||||||
// 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.Filters = &xlsxFilters{Filter: filters}
|
filter.FilterColumn[0].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.
|
||||||
filters := []*xlsxFilter{}
|
filters := []*xlsxFilter{}
|
||||||
for _, v := range tokens {
|
for _, v := range tokens {
|
||||||
filters = append(filters, &xlsxFilter{Val: v})
|
filters = append(filters, &xlsxFilter{Val: v})
|
||||||
}
|
}
|
||||||
filter.FilterColumn.Filters = &xlsxFilters{Filter: filters}
|
filter.FilterColumn[0].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}
|
||||||
|
@ -387,7 +387,7 @@ func (f *File) writeAutoFilter(filter *xlsxAutoFilter, exp []int, tokens []strin
|
||||||
for k, v := range tokens {
|
for k, v := range tokens {
|
||||||
f.writeCustomFilter(filter, exp[expRel[k]], v)
|
f.writeCustomFilter(filter, exp[expRel[k]], v)
|
||||||
if k == 1 {
|
if k == 1 {
|
||||||
filter.FilterColumn.CustomFilters.And = andRel[exp[k]]
|
filter.FilterColumn[0].CustomFilters.And = andRel[exp[k]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,12 +408,12 @@ func (f *File) writeCustomFilter(filter *xlsxAutoFilter, operator int, val strin
|
||||||
Operator: operators[operator],
|
Operator: operators[operator],
|
||||||
Val: val,
|
Val: val,
|
||||||
}
|
}
|
||||||
if filter.FilterColumn.CustomFilters != nil {
|
if filter.FilterColumn[0].CustomFilters != nil {
|
||||||
filter.FilterColumn.CustomFilters.CustomFilter = append(filter.FilterColumn.CustomFilters.CustomFilter, &customFilter)
|
filter.FilterColumn[0].CustomFilters.CustomFilter = append(filter.FilterColumn[0].CustomFilters.CustomFilter, &customFilter)
|
||||||
} else {
|
} else {
|
||||||
customFilters := []*xlsxCustomFilter{}
|
customFilters := []*xlsxCustomFilter{}
|
||||||
customFilters = append(customFilters, &customFilter)
|
customFilters = append(customFilters, &customFilter)
|
||||||
filter.FilterColumn.CustomFilters = &xlsxCustomFilters{CustomFilter: customFilters}
|
filter.FilterColumn[0].CustomFilters = &xlsxCustomFilters{CustomFilter: customFilters}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
|
// Copyright 2016 - 2021 The excelize Authors. All rights reserved. Use of
|
||||||
// this source code is governed by a BSD-style license that can be found in
|
// this source code is governed by a BSD-style license that can be found in
|
||||||
// the LICENSE file.
|
// the LICENSE file.
|
||||||
//
|
//
|
||||||
|
@ -46,9 +46,9 @@ type xlsxTable struct {
|
||||||
// applied column by column to a table of data in the worksheet. This collection
|
// applied column by column to a table of data in the worksheet. This collection
|
||||||
// expresses AutoFilter settings.
|
// expresses AutoFilter settings.
|
||||||
type xlsxAutoFilter struct {
|
type xlsxAutoFilter struct {
|
||||||
XMLName xml.Name `xml:"autoFilter"`
|
XMLName xml.Name `xml:"autoFilter"`
|
||||||
Ref string `xml:"ref,attr"`
|
Ref string `xml:"ref,attr"`
|
||||||
FilterColumn *xlsxFilterColumn `xml:"filterColumn"`
|
FilterColumn []*xlsxFilterColumn `xml:"filterColumn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// xlsxFilterColumn directly maps the filterColumn element. The filterColumn
|
// xlsxFilterColumn directly maps the filterColumn element. The filterColumn
|
||||||
|
|
Loading…
Reference in New Issue