This closes #1217, support update cell hyperlink

Ref #1129, make `SetRowStyle` overwrite style of the cells
This commit is contained in:
xuri 2022-05-01 12:28:36 +08:00 committed by GitHub
parent 856ee57c40
commit 773d4afa32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 18 deletions

24
cell.go
View File

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

View File

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

View File

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

View File

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

View File

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