diff --git a/sheet.go b/sheet.go index 0d6f5d1203cdefc047a3d049f0d08ca13137c7e2..b0e29712ade327e6303e8bdd2d264ff747cc7504 100644 --- a/sheet.go +++ b/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 // of the spreadsheet. func (f *File) getSheetMap() map[string]string { - content := f.workbookReader() - rels := f.relsReader(f.getWorkbookRelsPath()) maps := map[string]string{} - for _, v := range content.Sheets.Sheet { - for _, rel := range rels.Relationships { + for _, v := range f.workbookReader().Sheets.Sheet { + for _, rel := range f.relsReader(f.getWorkbookRelsPath()).Relationships { 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 - pathInfo := strings.Split(rel.Target, "/") - pathInfoLen := len(pathInfo) - if pathInfoLen > 1 { - maps[v.Name] = fmt.Sprintf("xl/%s", strings.Join(pathInfo[pathInfoLen-2:], "/")) + // 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 + 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 } } } diff --git a/stream_test.go b/stream_test.go index 4f1812efd6dfb8261a9f4f12a78490a53261cacf..ec7bd08420d19970a6c91691abd7d2e34a4f4e45 100644 --- a/stream_test.go +++ b/stream_test.go @@ -76,7 +76,7 @@ func TestStreamWriter(t *testing.T) { file = NewFile() streamWriter, err = file.NewStreamWriter("Sheet1") assert.NoError(t, err) - for rowID := 10; rowID <= 51200; rowID++ { + for rowID := 10; rowID <= 25600; rowID++ { row := make([]interface{}, 50) for colID := 0; colID < 50; colID++ { row[colID] = rand.Intn(640000) diff --git a/table.go b/table.go index 8775929464af847181f9b874ecc07e9f7a4135e0..ba8de25c80ad95d4421a202ae0f9a640f0b7a30a 100644 --- a/table.go +++ b/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) } - filter.FilterColumn = &xlsxFilterColumn{ + filter.FilterColumn = append(filter.FilterColumn, &xlsxFilterColumn{ ColID: offset, - } + }) re := regexp.MustCompile(`"(?:[^"]|"")*"|\S+`) token := re.FindAllString(formatSet.Expression, -1) if len(token) != 3 && len(token) != 7 { @@ -372,14 +372,14 @@ func (f *File) writeAutoFilter(filter *xlsxAutoFilter, exp []int, tokens []strin // Single equality. var filters []*xlsxFilter 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 { // Double equality with "or" operator. filters := []*xlsxFilter{} for _, v := range tokens { filters = append(filters, &xlsxFilter{Val: v}) } - filter.FilterColumn.Filters = &xlsxFilters{Filter: filters} + filter.FilterColumn[0].Filters = &xlsxFilters{Filter: filters} } else { // Non default custom filter. 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 { f.writeCustomFilter(filter, exp[expRel[k]], v) 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], Val: val, } - if filter.FilterColumn.CustomFilters != nil { - filter.FilterColumn.CustomFilters.CustomFilter = append(filter.FilterColumn.CustomFilters.CustomFilter, &customFilter) + if filter.FilterColumn[0].CustomFilters != nil { + filter.FilterColumn[0].CustomFilters.CustomFilter = append(filter.FilterColumn[0].CustomFilters.CustomFilter, &customFilter) } else { customFilters := []*xlsxCustomFilter{} customFilters = append(customFilters, &customFilter) - filter.FilterColumn.CustomFilters = &xlsxCustomFilters{CustomFilter: customFilters} + filter.FilterColumn[0].CustomFilters = &xlsxCustomFilters{CustomFilter: customFilters} } } diff --git a/xmlTable.go b/xmlTable.go index 22d191e349efba964fb35a197f9d711f1958d1ef..c48720bd73630261fa90eb5c283d51532f2fd1b1 100644 --- a/xmlTable.go +++ b/xmlTable.go @@ -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 // the LICENSE file. // @@ -46,9 +46,9 @@ type xlsxTable struct { // applied column by column to a table of data in the worksheet. This collection // expresses AutoFilter settings. type xlsxAutoFilter struct { - XMLName xml.Name `xml:"autoFilter"` - Ref string `xml:"ref,attr"` - FilterColumn *xlsxFilterColumn `xml:"filterColumn"` + XMLName xml.Name `xml:"autoFilter"` + Ref string `xml:"ref,attr"` + FilterColumn []*xlsxFilterColumn `xml:"filterColumn"` } // xlsxFilterColumn directly maps the filterColumn element. The filterColumn