浏览代码

New feature: the function `SearchSheet` now support regular expression, relate pull request #316

xuri 7 年之前
父节点
当前提交
9a6f66a996
共有 3 个文件被更改,包括 30 次插入71 次删除
  1. 2 0
      excelize.go
  2. 4 13
      excelize_test.go
  3. 24 58
      sheet.go

+ 2 - 0
excelize.go

@@ -243,6 +243,8 @@ func (f *File) adjustRowDimensions(xlsx *xlsxWorksheet, rowIndex, offset int) {
 	}
 }
 
+// ajustSingleRowDimensions provides a function to ajust single row
+// dimensions.
 func (f *File) ajustSingleRowDimensions(r *xlsxRow, offset int) {
 	r.R += offset
 	for i, col := range r.C {

+ 4 - 13
excelize_test.go

@@ -1053,6 +1053,7 @@ func TestDuplicateRow(t *testing.T) {
 	xlsx.SetCellStr(sheet, b1, bnValue)
 
 	t.Run("FromSingleRow", func(t *testing.T) {
+		xlsx.DuplicateRow(sheet, -1)
 		xlsx.DuplicateRow(sheet, 1)
 		xlsx.DuplicateRow(sheet, 2)
 
@@ -1333,19 +1334,9 @@ func TestSearchSheet(t *testing.T) {
 	// Test search a not exists value.
 	t.Log(xlsx.SearchSheet("Sheet1", "X"))
 	t.Log(xlsx.SearchSheet("Sheet1", "A"))
-}
-
-func TestRegSearchSheet(t *testing.T) {
-	xlsx, err := OpenFile("./test/Book1.xlsx")
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	t.Log(xlsx.SearchSheet("Sheet1", "[0-9]"))
-	// Test search in a not exists worksheet.
-	t.Log(xlsx.SearchSheet("Sheet4", ""))
-	// Test search a not exists value.
-	t.Log(xlsx.SearchSheet("Sheet1", ""))
+	// Test search the coordinates where the numerical value in the range of
+	// "0-9" of Sheet1 is described by regular expression:
+	t.Log(xlsx.SearchSheet("Sheet1", "[0-9]", true))
 }
 
 func TestProtectSheet(t *testing.T) {

+ 24 - 58
sheet.go

@@ -658,66 +658,26 @@ func (f *File) GetSheetVisible(name string) bool {
 	return visible
 }
 
-// SearchSheet provides a function to get coordinates by given worksheet name
-// and cell value. This function only supports exact match of strings and
-// numbers, doesn't support the calculated result, formatted numbers and
-// conditional lookup currently. If it is a merged cell, it will return the
-// coordinates of the upper left corner of the merged area. For example,
-// search the coordinates of the value of "100" on Sheet1:
+// SearchSheet provides a function to get coordinates by given worksheet name,
+// cell value, and regular expression. The function doesn't support searching
+// on the calculated result, formatted numbers and conditional lookup
+// currently. If it is a merged cell, it will return the coordinates of the
+// upper left corner of the merged area.
+//
+// An example of search the coordinates of the value of "100" on Sheet1:
 //
 //    xlsx.SearchSheet("Sheet1", "100")
 //
-func (f *File) SearchSheet(sheet, value string) []string {
-	xlsx := f.workSheetReader(sheet)
-	result := []string{}
-	name, ok := f.sheetMap[trimSheetName(sheet)]
-	if !ok {
-		return result
-	}
-	if xlsx != nil {
-		output, _ := xml.Marshal(f.Sheet[name])
-		f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpaceBytes(output))
-	}
-	xml.NewDecoder(bytes.NewReader(f.readXML(name)))
-	d := f.sharedStringsReader()
-	var inElement string
-	var r xlsxRow
-	decoder := xml.NewDecoder(bytes.NewReader(f.readXML(name)))
-	for {
-		token, _ := decoder.Token()
-		if token == nil {
-			break
-		}
-		switch startElement := token.(type) {
-		case xml.StartElement:
-			inElement = startElement.Name.Local
-			if inElement == "row" {
-				r = xlsxRow{}
-				_ = decoder.DecodeElement(&r, &startElement)
-				for _, colCell := range r.C {
-					val, _ := colCell.getValueFrom(f, d)
-					if val != value {
-						continue
-					}
-					result = append(result, fmt.Sprintf("%s%d", strings.Map(letterOnlyMapF, colCell.R), r.R))
-				}
-			}
-		default:
-		}
-	}
-	return result
-}
-
-// RegSearchSheet provides the ability to retrieve coordinates
-// with the given worksheet name and regular expression
-// For a merged cell, get the coordinates
-// of the upper left corner of the merge area.
-// :example)
-// Search the coordinates where the numerical value in the range of "0-9" of Sheet 1 is described:
+// An example of search the coordinates where the numerical value in the range
+// of "0-9" of Sheet1 is described:
 //
-//    xlsx.RegSearchSheet("Sheet1", "[0-9]")
+//    xlsx.SearchSheet("Sheet1", "[0-9]", true)
 //
-func (f *File) RegSearchSheet(sheet, value string) []string {
+func (f *File) SearchSheet(sheet, value string, reg ...bool) []string {
+	var regSearch bool
+	for _, r := range reg {
+		regSearch = r
+	}
 	xlsx := f.workSheetReader(sheet)
 	result := []string{}
 	name, ok := f.sheetMap[trimSheetName(sheet)]
@@ -746,9 +706,15 @@ func (f *File) RegSearchSheet(sheet, value string) []string {
 				_ = decoder.DecodeElement(&r, &startElement)
 				for _, colCell := range r.C {
 					val, _ := colCell.getValueFrom(f, d)
-					regex := regexp.MustCompile(value)
-					if !regex.MatchString(val) {
-						continue
+					if regSearch {
+						regex := regexp.MustCompile(value)
+						if !regex.MatchString(val) {
+							continue
+						}
+					} else {
+						if val != value {
+							continue
+						}
 					}
 					result = append(result, fmt.Sprintf("%s%d", strings.Map(letterOnlyMapF, colCell.R), r.R))
 				}