Skip to content

Commit

Permalink
Update drawing objects on inserting/deleting maximum/minimum columns/…
Browse files Browse the repository at this point in the history
…rows
  • Loading branch information
xuri committed Nov 5, 2023
1 parent 6318a63 commit d416510
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 56 deletions.
110 changes: 62 additions & 48 deletions adjust.go
Original file line number Diff line number Diff line change
Expand Up @@ -765,60 +765,70 @@ func (f *File) adjustVolatileDeps(ws *xlsxWorksheet, sheet string, dir adjustDir
return nil
}

// adjustDrawings updates the two cell anchor pictures and charts object when
// inserting or deleting rows or columns.
func (a *xdrCellAnchor) adjustDrawings(dir adjustDirection, num, offset int) {
if a.From == nil || a.To == nil {
return
// adjustDrawings updates the starting anchor of the two cell anchor pictures
// and charts object when inserting or deleting rows or columns.
func (from *xlsxFrom) adjustDrawings(dir adjustDirection, num, offset int, editAs string) (bool, error) {
var ok bool
if dir == columns && from.Col+1 >= num && from.Col+offset >= 0 {
if from.Col+offset >= MaxColumns {
return false, ErrColumnNumber
}
from.Col += offset
ok = editAs == "oneCell"
}
if offset > 0 && a.EditAs != "absolute" {
var move bool
if dir == columns {
if a.From.Col+1 >= num {
a.From.Col += offset
move = a.EditAs == "oneCell"
}
if a.To.Col+1 >= num && (move || a.EditAs == "") {
a.To.Col += offset
}
return
if dir == rows && from.Row+1 >= num && from.Row+offset >= 0 {
if from.Row+offset >= TotalRows {
return false, ErrMaxRows
}
if a.From.Row+1 >= num {
a.From.Row += offset
move = a.EditAs == "oneCell"
from.Row += offset
ok = editAs == "oneCell"
}
return ok, nil
}

// adjustDrawings updates the ending anchor of the two cell anchor pictures
// and charts object when inserting or deleting rows or columns.
func (to *xlsxTo) adjustDrawings(dir adjustDirection, num, offset int, editAs string, ok bool) error {
if dir == columns && to.Col+1 >= num && to.Col+offset >= 0 && ok {
if to.Col+offset >= MaxColumns {
return ErrColumnNumber
}
if a.To.Row+1 >= num && (move || a.EditAs == "") {
a.To.Row += offset
to.Col += offset
}
if dir == rows && to.Row+1 >= num && to.Row+offset >= 0 && ok {
if to.Row+offset >= TotalRows {
return ErrMaxRows
}
to.Row += offset
}
return nil
}

// adjustDrawings updates the two cell anchor pictures and charts object when
// inserting or deleting rows or columns.
func (a *xdrCellAnchor) adjustDrawings(dir adjustDirection, num, offset int) error {
editAs := a.EditAs
if a.From == nil || a.To == nil || editAs == "absolute" {
return nil
}
ok, err := a.From.adjustDrawings(dir, num, offset, editAs)
if err != nil {
return err
}
return a.To.adjustDrawings(dir, num, offset, editAs, ok || editAs == "")
}

// adjustDrawings updates the existing two cell anchor pictures and charts
// object when inserting or deleting rows or columns.
func (a *xlsxCellAnchorPos) adjustDrawings(dir adjustDirection, num, offset int, editAs string) {
if a.From == nil || a.To == nil {
return
func (a *xlsxCellAnchorPos) adjustDrawings(dir adjustDirection, num, offset int, editAs string) error {
if a.From == nil || a.To == nil || editAs == "absolute" {
return nil
}
if offset > 0 && editAs != "absolute" {
var move bool
if dir == columns {
if a.From.Col+1 >= num {
a.From.Col += offset
move = editAs == "oneCell"
}
if a.To.Col+1 >= num && (move || editAs == "") {
a.To.Col += offset
}
return
}
if a.From.Row+1 >= num {
a.From.Row += offset
move = editAs == "oneCell"
}
if a.To.Row+1 >= num && (move || editAs == "") {
a.To.Row += offset
}
ok, err := a.From.adjustDrawings(dir, num, offset, editAs)
if err != nil {
return err
}
return a.To.adjustDrawings(dir, num, offset, editAs, ok || editAs == "")
}

// adjustDrawings updates the pictures and charts object when inserting or
Expand All @@ -836,10 +846,9 @@ func (f *File) adjustDrawings(ws *xlsxWorksheet, sheet string, dir adjustDirecti
if wsDr, _, err = f.drawingParser(drawingXML); err != nil {
return err
}
anchorCb := func(a *xdrCellAnchor) {
anchorCb := func(a *xdrCellAnchor) error {
if a.GraphicFrame == "" {
a.adjustDrawings(dir, num, offset)
return
return a.adjustDrawings(dir, num, offset)
}
deCellAnchor := decodeCellAnchor{}
deCellAnchorPos := decodeCellAnchorPos{}
Expand All @@ -858,12 +867,17 @@ func (f *File) adjustDrawings(ws *xlsxWorksheet, sheet string, dir adjustDirecti
Row: deCellAnchor.To.Row, RowOff: deCellAnchor.To.RowOff,
}
}
xlsxCellAnchorPos.adjustDrawings(dir, num, offset, a.EditAs)
if err = xlsxCellAnchorPos.adjustDrawings(dir, num, offset, a.EditAs); err != nil {
return err
}
cellAnchor, _ := xml.Marshal(xlsxCellAnchorPos)
a.GraphicFrame = strings.TrimSuffix(strings.TrimPrefix(string(cellAnchor), "<xlsxCellAnchorPos>"), "</xlsxCellAnchorPos>")
return err
}
for _, anchor := range wsDr.TwoCellAnchor {
anchorCb(anchor)
if err = anchorCb(anchor); err != nil {
return err
}
}
return nil
}
47 changes: 39 additions & 8 deletions adjust_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -953,9 +953,10 @@ func TestAdjustVolatileDeps(t *testing.T) {
func TestAdjustDrawings(t *testing.T) {
f := NewFile()
// Test add pictures to sheet with positioning
assert.NoError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), nil))
assert.NoError(t, f.AddPicture("Sheet1", "A10", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{Positioning: "oneCell"}))
assert.NoError(t, f.AddPicture("Sheet1", "A20", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{Positioning: "absolute"}))
assert.NoError(t, f.AddPicture("Sheet1", "B2", filepath.Join("test", "images", "excel.jpg"), nil))
assert.NoError(t, f.AddPicture("Sheet1", "B11", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{Positioning: "oneCell"}))
assert.NoError(t, f.AddPicture("Sheet1", "B21", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{Positioning: "absolute"}))

// Test adjust pictures on inserting columns and rows
assert.NoError(t, f.InsertCols("Sheet1", "A", 1))
assert.NoError(t, f.InsertRows("Sheet1", 1, 1))
Expand All @@ -964,10 +965,17 @@ func TestAdjustDrawings(t *testing.T) {
assert.NoError(t, f.InsertRows("Sheet1", 15, 1))
cells, err := f.GetPictureCells("Sheet1")
assert.NoError(t, err)
assert.Equal(t, []string{"B2", "B12", "A20"}, cells)
assert.Equal(t, []string{"D3", "D13", "B21"}, cells)
wb := filepath.Join("test", "TestAdjustDrawings.xlsx")
assert.NoError(t, f.SaveAs(wb))

// Test adjust pictures on deleting columns and rows
assert.NoError(t, f.RemoveCol("Sheet1", "A"))
assert.NoError(t, f.RemoveRow("Sheet1", 1))
cells, err = f.GetPictureCells("Sheet1")
assert.NoError(t, err)
assert.Equal(t, []string{"C2", "C12", "B21"}, cells)

// Test adjust existing pictures on inserting columns and rows
f, err = OpenFile(wb)
assert.NoError(t, err)
Expand All @@ -978,16 +986,39 @@ func TestAdjustDrawings(t *testing.T) {
assert.NoError(t, f.InsertRows("Sheet1", 16, 1))
cells, err = f.GetPictureCells("Sheet1")
assert.NoError(t, err)
assert.Equal(t, []string{"C3", "C14", "A20"}, cells)
assert.Equal(t, []string{"F4", "F15", "B21"}, cells)

// Test adjust pictures with unsupported charset
// Test adjust drawings with unsupported charset
f, err = OpenFile(wb)
assert.NoError(t, err)
f.Pkg.Store("xl/drawings/drawing1.xml", MacintoshCyrillicCharset)
assert.EqualError(t, f.InsertCols("Sheet1", "A", 1), "XML syntax error on line 1: invalid UTF-8")

errors := []error{ErrColumnNumber, ErrColumnNumber, ErrMaxRows, ErrMaxRows}
cells = []string{"XFD1", "XFB1"}
for i, cell := range cells {
f = NewFile()
assert.NoError(t, f.AddPicture("Sheet1", cell, filepath.Join("test", "images", "excel.jpg"), nil))
assert.Equal(t, errors[i], f.InsertCols("Sheet1", "A", 1))
assert.NoError(t, f.SaveAs(wb))
f, err = OpenFile(wb)
assert.NoError(t, err)
assert.Equal(t, errors[i], f.InsertCols("Sheet1", "A", 1))
}
errors = []error{ErrMaxRows, ErrMaxRows}
cells = []string{"A1048576", "A1048570"}
for i, cell := range cells {
f = NewFile()
assert.NoError(t, f.AddPicture("Sheet1", cell, filepath.Join("test", "images", "excel.jpg"), nil))
assert.Equal(t, errors[i], f.InsertRows("Sheet1", 1, 1))
assert.NoError(t, f.SaveAs(wb))
f, err = OpenFile(wb)
assert.NoError(t, err)
assert.Equal(t, errors[i], f.InsertRows("Sheet1", 1, 1))
}

a := xdrCellAnchor{}
a.adjustDrawings(columns, 0, 0)
assert.NoError(t, a.adjustDrawings(columns, 0, 0))
p := xlsxCellAnchorPos{}
p.adjustDrawings(columns, 0, 0, "")
assert.NoError(t, p.adjustDrawings(columns, 0, 0, ""))
}

0 comments on commit d416510

Please sign in to comment.