summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--excelize_test.go21
-rw-r--r--sheet.go80
-rw-r--r--sheet_test.go45
-rw-r--r--xmlWorkbook.go9
4 files changed, 135 insertions, 20 deletions
diff --git a/excelize_test.go b/excelize_test.go
index e4b2548..c7c3aec 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -182,6 +182,11 @@ func TestSaveAsWrongPath(t *testing.T) {
}
}
+func TestOpenReader(t *testing.T) {
+ _, err := OpenReader(strings.NewReader(""))
+ assert.EqualError(t, err, "zip: not a valid zip file")
+}
+
func TestBrokenFile(t *testing.T) {
// Test write file with broken file struct.
f := File{}
@@ -1033,22 +1038,6 @@ func TestHSL(t *testing.T) {
t.Log(RGBToHSL(250, 50, 100))
}
-func TestSearchSheet(t *testing.T) {
- f, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- // Test search in a not exists worksheet.
- t.Log(f.SearchSheet("Sheet4", ""))
- // Test search a not exists value.
- t.Log(f.SearchSheet("Sheet1", "X"))
- t.Log(f.SearchSheet("Sheet1", "A"))
- // Test search the coordinates where the numerical value in the range of
- // "0-9" of Sheet1 is described by regular expression:
- t.Log(f.SearchSheet("Sheet1", "[0-9]", true))
-}
-
func TestProtectSheet(t *testing.T) {
f := NewFile()
f.ProtectSheet("Sheet1", nil)
diff --git a/sheet.go b/sheet.go
index d3099fb..c0eba56 100644
--- a/sheet.go
+++ b/sheet.go
@@ -704,18 +704,14 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) {
var (
regSearch bool
result []string
- inElement string
- r xlsxRow
)
for _, r := range reg {
regSearch = r
}
-
xlsx, err := f.workSheetReader(sheet)
if err != nil {
return result, err
}
-
name, ok := f.sheetMap[trimSheetName(sheet)]
if !ok {
return result, nil
@@ -724,6 +720,17 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) {
output, _ := xml.Marshal(f.Sheet[name])
f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpaceBytes(output))
}
+ return f.searchSheet(name, value, regSearch)
+}
+
+// searchSheet provides a function to get coordinates by given worksheet name,
+// cell value, and regular expression.
+func (f *File) searchSheet(name, value string, regSearch bool) ([]string, error) {
+ var (
+ inElement string
+ result []string
+ r xlsxRow
+ )
xml.NewDecoder(bytes.NewReader(f.readXML(name)))
d := f.sharedStringsReader()
@@ -1213,6 +1220,71 @@ func (f *File) GetPageLayout(sheet string, opts ...PageLayoutOptionPtr) error {
return err
}
+// SetDefinedName provides a function to set the defined names of the workbook
+// or worksheet. If not specified scopr, the default scope is workbook.
+// For example:
+//
+// f.SetDefinedName(&excelize.DefinedName{
+// Name: "Amount",
+// RefersTo: "Sheet1!$A$2:$D$5",
+// Comment: "defined name comment",
+// Scope: "Sheet2",
+// })
+//
+func (f *File) SetDefinedName(definedName *DefinedName) error {
+ wb := f.workbookReader()
+ d := xlsxDefinedName{
+ Name: definedName.Name,
+ Comment: definedName.Comment,
+ Data: definedName.RefersTo,
+ }
+ if definedName.Scope != "" {
+ if sheetID := f.GetSheetIndex(definedName.Scope); sheetID != 0 {
+ sheetID--
+ d.LocalSheetID = &sheetID
+ }
+ }
+ if wb.DefinedNames != nil {
+ for _, dn := range wb.DefinedNames.DefinedName {
+ var scope string
+ if dn.LocalSheetID != nil {
+ scope = f.GetSheetName(*dn.LocalSheetID + 1)
+ }
+ if scope == definedName.Scope && dn.Name == definedName.Name {
+ return errors.New("the same name already exists on scope")
+ }
+ }
+ wb.DefinedNames.DefinedName = append(wb.DefinedNames.DefinedName, d)
+ return nil
+ }
+ wb.DefinedNames = &xlsxDefinedNames{
+ DefinedName: []xlsxDefinedName{d},
+ }
+ return nil
+}
+
+// GetDefinedName provides a function to get the defined names of the workbook
+// or worksheet.
+func (f *File) GetDefinedName() []DefinedName {
+ var definedNames []DefinedName
+ wb := f.workbookReader()
+ if wb.DefinedNames != nil {
+ for _, dn := range wb.DefinedNames.DefinedName {
+ definedName := DefinedName{
+ Name: dn.Name,
+ Comment: dn.Comment,
+ RefersTo: dn.Data,
+ Scope: "Workbook",
+ }
+ if dn.LocalSheetID != nil {
+ definedName.Scope = f.GetSheetName(*dn.LocalSheetID + 1)
+ }
+ definedNames = append(definedNames, definedName)
+ }
+ }
+ return definedNames
+}
+
// workSheetRelsReader provides a function to get the pointer to the structure
// after deserialization of xl/worksheets/_rels/sheet%d.xml.rels.
func (f *File) workSheetRelsReader(path string) *xlsxWorkbookRels {
diff --git a/sheet_test.go b/sheet_test.go
index beee10b..a7fd9e9 100644
--- a/sheet_test.go
+++ b/sheet_test.go
@@ -108,6 +108,29 @@ func TestPageLayoutOption(t *testing.T) {
}
}
+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.
@@ -142,3 +165,25 @@ func TestSetHeaderFooter(t *testing.T) {
}))
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")))
+}
diff --git a/xmlWorkbook.go b/xmlWorkbook.go
index 5384977..0118685 100644
--- a/xmlWorkbook.go
+++ b/xmlWorkbook.go
@@ -288,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
+}