summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2022-05-01 12:28:36 +0800
committerGitHub <noreply@github.com>2022-05-01 12:28:36 +0800
commit773d4afa32a55349a7b178c4c76d182f9ed0221f (patch)
treed176338fc1c550dab8201180f822dbf6dfad074d
parent856ee57c4019b4478da0f6cb3010ae636914a6be (diff)
This closes #1217, support update cell hyperlink
Ref #1129, make `SetRowStyle` overwrite style of the cells
-rw-r--r--cell.go24
-rw-r--r--excelize.go22
-rw-r--r--excelize_test.go16
-rw-r--r--rows.go5
-rw-r--r--rows_test.go15
5 files changed, 64 insertions, 18 deletions
diff --git a/cell.go b/cell.go
index 1d6ed84..70832ce 100644
--- a/cell.go
+++ b/cell.go
@@ -715,10 +715,17 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
}
var linkData xlsxHyperlink
-
+ idx := -1
if ws.Hyperlinks == nil {
ws.Hyperlinks = new(xlsxHyperlinks)
}
+ for i, hyperlink := range ws.Hyperlinks.Hyperlink {
+ if hyperlink.Ref == axis {
+ idx = i
+ linkData = hyperlink
+ break
+ }
+ }
if len(ws.Hyperlinks.Hyperlink) > TotalSheetHyperlinks {
return ErrTotalSheetHyperlinks
@@ -726,12 +733,12 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
switch linkType {
case "External":
+ sheetPath := f.sheetMap[trimSheetName(sheet)]
+ sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
+ rID := f.setRels(linkData.RID, sheetRels, SourceRelationshipHyperLink, link, linkType)
linkData = xlsxHyperlink{
Ref: axis,
}
- sheetPath := f.sheetMap[trimSheetName(sheet)]
- sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
- rID := f.addRels(sheetRels, SourceRelationshipHyperLink, link, linkType)
linkData.RID = "rId" + strconv.Itoa(rID)
f.addSheetNameSpace(sheet, SourceRelationship)
case "Location":
@@ -751,9 +758,12 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
linkData.Tooltip = *o.Tooltip
}
}
-
- ws.Hyperlinks.Hyperlink = append(ws.Hyperlinks.Hyperlink, linkData)
- return nil
+ if idx == -1 {
+ ws.Hyperlinks.Hyperlink = append(ws.Hyperlinks.Hyperlink, linkData)
+ return err
+ }
+ ws.Hyperlinks.Hyperlink[idx] = linkData
+ return err
}
// getCellRichText returns rich text of cell by given string item.
diff --git a/excelize.go b/excelize.go
index 9fe3d88..d78d2b1 100644
--- a/excelize.go
+++ b/excelize.go
@@ -327,6 +327,28 @@ func checkSheetR0(ws *xlsxWorksheet, sheetData *xlsxSheetData, r0 *xlsxRow) {
ws.SheetData = *sheetData
}
+// setRels provides a function to set relationships by given relationship ID,
+// XML path, relationship type, target and target mode.
+func (f *File) setRels(rID, relPath, relType, target, targetMode string) int {
+ rels := f.relsReader(relPath)
+ if rels == nil || rID == "" {
+ return f.addRels(relPath, relType, target, targetMode)
+ }
+ rels.Lock()
+ defer rels.Unlock()
+ var ID int
+ for i, rel := range rels.Relationships {
+ if rel.ID == rID {
+ rels.Relationships[i].Type = relType
+ rels.Relationships[i].Target = target
+ rels.Relationships[i].TargetMode = targetMode
+ ID, _ = strconv.Atoi(strings.TrimPrefix(rID, "rId"))
+ break
+ }
+ }
+ return ID
+}
+
// addRels provides a function to add relationships by given XML path,
// relationship type, target and target mode.
func (f *File) addRels(relPath, relType, target, targetMode string) int {
diff --git a/excelize_test.go b/excelize_test.go
index dc5dfcc..389573e 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -336,9 +336,7 @@ func TestAddDrawingVML(t *testing.T) {
func TestSetCellHyperLink(t *testing.T) {
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
- if err != nil {
- t.Log(err)
- }
+ assert.NoError(t, err)
// Test set cell hyperlink in a work sheet already have hyperlinks.
assert.NoError(t, f.SetCellHyperLink("Sheet1", "B19", "https://github.com/xuri/excelize", "External"))
// Test add first hyperlink in a work sheet.
@@ -346,8 +344,7 @@ func TestSetCellHyperLink(t *testing.T) {
// Test add Location hyperlink in a work sheet.
assert.NoError(t, f.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location"))
// Test add Location hyperlink with display & tooltip in a work sheet.
- display := "Display value"
- tooltip := "Hover text"
+ display, tooltip := "Display value", "Hover text"
assert.NoError(t, f.SetCellHyperLink("Sheet2", "D7", "Sheet1!D9", "Location", HyperlinkOpts{
Display: &display,
Tooltip: &tooltip,
@@ -376,6 +373,15 @@ func TestSetCellHyperLink(t *testing.T) {
ws.(*xlsxWorksheet).MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
err = f.SetCellHyperLink("Sheet1", "A1", "https://github.com/xuri/excelize", "External")
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
+
+ // Test update cell hyperlink
+ f = NewFile()
+ assert.NoError(t, f.SetCellHyperLink("Sheet1", "A1", "https://github.com", "External"))
+ assert.NoError(t, f.SetCellHyperLink("Sheet1", "A1", "https://github.com/xuri/excelize", "External"))
+ link, target, err := f.GetCellHyperLink("Sheet1", "A1")
+ assert.Equal(t, link, true)
+ assert.Equal(t, "https://github.com/xuri/excelize", target)
+ assert.NoError(t, err)
}
func TestGetCellHyperLink(t *testing.T) {
diff --git a/rows.go b/rows.go
index e0918bc..bcb8960 100644
--- a/rows.go
+++ b/rows.go
@@ -841,6 +841,11 @@ func (f *File) SetRowStyle(sheet string, start, end, styleID int) error {
for row := start - 1; row < end; row++ {
ws.SheetData.Row[row].S = styleID
ws.SheetData.Row[row].CustomFormat = true
+ for i := range ws.SheetData.Row[row].C {
+ if _, rowNum, err := CellNameToCoordinates(ws.SheetData.Row[row].C[i].R); err == nil && rowNum-1 == row {
+ ws.SheetData.Row[row].C[i].S = styleID
+ }
+ }
}
return nil
}
diff --git a/rows_test.go b/rows_test.go
index 22b038a..ae30838 100644
--- a/rows_test.go
+++ b/rows_test.go
@@ -915,16 +915,19 @@ func TestCheckRow(t *testing.T) {
func TestSetRowStyle(t *testing.T) {
f := NewFile()
- styleID, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":1}}`)
+ style1, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#63BE7B"],"pattern":1}}`)
assert.NoError(t, err)
- assert.EqualError(t, f.SetRowStyle("Sheet1", 10, -1, styleID), newInvalidRowNumberError(-1).Error())
- assert.EqualError(t, f.SetRowStyle("Sheet1", 1, TotalRows+1, styleID), ErrMaxRows.Error())
+ style2, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":1}}`)
+ assert.NoError(t, err)
+ assert.NoError(t, f.SetCellStyle("Sheet1", "B2", "B2", style1))
+ assert.EqualError(t, f.SetRowStyle("Sheet1", 5, -1, style2), newInvalidRowNumberError(-1).Error())
+ assert.EqualError(t, f.SetRowStyle("Sheet1", 1, TotalRows+1, style2), ErrMaxRows.Error())
assert.EqualError(t, f.SetRowStyle("Sheet1", 1, 1, -1), newInvalidStyleID(-1).Error())
- assert.EqualError(t, f.SetRowStyle("SheetN", 1, 1, styleID), "sheet SheetN is not exist")
- assert.NoError(t, f.SetRowStyle("Sheet1", 10, 1, styleID))
+ assert.EqualError(t, f.SetRowStyle("SheetN", 1, 1, style2), "sheet SheetN is not exist")
+ assert.NoError(t, f.SetRowStyle("Sheet1", 5, 1, style2))
cellStyleID, err := f.GetCellStyle("Sheet1", "B2")
assert.NoError(t, err)
- assert.Equal(t, styleID, cellStyleID)
+ assert.Equal(t, style2, cellStyleID)
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetRowStyle.xlsx")))
}