This improves compatibility for worksheet relative XML path and multi rules auto filter

This commit is contained in:
xuri 2021-02-11 00:07:46 +08:00
parent 3783d1d01b
commit 3648335d7f
4 changed files with 22 additions and 22 deletions

View File

@ -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
} }
} }
} }

View File

@ -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)

View File

@ -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}
} }
} }

View File

@ -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