提交 725c1a0c 编写于 作者: V Veniamin Albaev

New feature: File.DuplicateRowTo() duplicate row to specified row position.

DuplicateRowTo() is similar to DuplicateRow() but copies specified row not just after specified source row
but to any other specified position below or above source row.

Also I made minor modifications of tests: using filepath.Join() instead of direct unix-way paths strings
to avoid possible tests fails on other OS.
上级 b0ed4c12
...@@ -10,13 +10,14 @@ ...@@ -10,13 +10,14 @@
package excelize package excelize
import ( import (
"path/filepath"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestDataValidation(t *testing.T) { func TestDataValidation(t *testing.T) {
const resultFile = "./test/TestDataValidation.xlsx" resultFile := filepath.Join("test", "TestDataValidation.xlsx")
xlsx := NewFile() xlsx := NewFile()
...@@ -50,7 +51,7 @@ func TestDataValidation(t *testing.T) { ...@@ -50,7 +51,7 @@ func TestDataValidation(t *testing.T) {
} }
func TestDataValidationError(t *testing.T) { func TestDataValidationError(t *testing.T) {
const resultFile = "./test/TestDataValidationError.xlsx" resultFile := filepath.Join("test", "TestDataValidationError.xlsx")
xlsx := NewFile() xlsx := NewFile()
xlsx.SetCellStr("Sheet1", "E1", "E1") xlsx.SetCellStr("Sheet1", "E1", "E1")
......
...@@ -238,18 +238,16 @@ func (f *File) adjustRowDimensions(xlsx *xlsxWorksheet, rowIndex, offset int) { ...@@ -238,18 +238,16 @@ func (f *File) adjustRowDimensions(xlsx *xlsxWorksheet, rowIndex, offset int) {
} }
for i, r := range xlsx.SheetData.Row { for i, r := range xlsx.SheetData.Row {
if r.R >= rowIndex { if r.R >= rowIndex {
f.ajustSingleRowDimensions(&xlsx.SheetData.Row[i], offset) f.ajustSingleRowDimensions(&xlsx.SheetData.Row[i], r.R+offset)
} }
} }
} }
// ajustSingleRowDimensions provides a function to ajust single row // ajustSingleRowDimensions provides a function to ajust single row dimensions.
// dimensions. func (f *File) ajustSingleRowDimensions(r *xlsxRow, row int) {
func (f *File) ajustSingleRowDimensions(r *xlsxRow, offset int) { r.R = row
r.R += offset
for i, col := range r.C { for i, col := range r.C {
row, _ := strconv.Atoi(strings.Map(intOnlyMapF, col.R)) r.C[i].R = string(strings.Map(letterOnlyMapF, col.R)) + strconv.Itoa(r.R)
r.C[i].R = string(strings.Map(letterOnlyMapF, col.R)) + strconv.Itoa(row+offset)
} }
} }
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
_ "image/png" _ "image/png"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
...@@ -18,7 +19,7 @@ import ( ...@@ -18,7 +19,7 @@ import (
func TestOpenFile(t *testing.T) { func TestOpenFile(t *testing.T) {
// Test update a XLSX file. // Test update a XLSX file.
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -126,16 +127,16 @@ func TestOpenFile(t *testing.T) { ...@@ -126,16 +127,16 @@ func TestOpenFile(t *testing.T) {
for i := 1; i <= 300; i++ { for i := 1; i <= 300; i++ {
xlsx.SetCellStr("Sheet3", "c"+strconv.Itoa(i), strconv.Itoa(i)) xlsx.SetCellStr("Sheet3", "c"+strconv.Itoa(i), strconv.Itoa(i))
} }
assert.NoError(t, xlsx.SaveAs("./test/TestOpenFile.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestOpenFile.xlsx")))
} }
func TestSaveFile(t *testing.T) { func TestSaveFile(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
assert.NoError(t, xlsx.SaveAs("./test/TestSaveFile.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSaveFile.xlsx")))
xlsx, err = OpenFile("./test/TestSaveFile.xlsx") xlsx, err = OpenFile(filepath.Join("test", "TestSaveFile.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -143,7 +144,7 @@ func TestSaveFile(t *testing.T) { ...@@ -143,7 +144,7 @@ func TestSaveFile(t *testing.T) {
} }
func TestSaveAsWrongPath(t *testing.T) { func TestSaveAsWrongPath(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if assert.NoError(t, err) { if assert.NoError(t, err) {
// Test write file to not exist directory. // Test write file to not exist directory.
err = xlsx.SaveAs("") err = xlsx.SaveAs("")
...@@ -154,26 +155,26 @@ func TestSaveAsWrongPath(t *testing.T) { ...@@ -154,26 +155,26 @@ func TestSaveAsWrongPath(t *testing.T) {
} }
func TestAddPicture(t *testing.T) { func TestAddPicture(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// Test add picture to worksheet with offset and location hyperlink. // Test add picture to worksheet with offset and location hyperlink.
err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", err = xlsx.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
`{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`) `{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// Test add picture to worksheet with offset, external hyperlink and positioning. // Test add picture to worksheet with offset, external hyperlink and positioning.
err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", err = xlsx.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
`{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`) `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
file, err := ioutil.ReadFile("./test/images/excel.jpg") file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.jpg"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -183,24 +184,24 @@ func TestAddPicture(t *testing.T) { ...@@ -183,24 +184,24 @@ func TestAddPicture(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Test write file to given path. // Test write file to given path.
err = xlsx.SaveAs("./test/TestAddPicture.xlsx") err = xlsx.SaveAs(filepath.Join("test", "TestAddPicture.xlsx"))
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestAddPictureErrors(t *testing.T) { func TestAddPictureErrors(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// Test add picture to worksheet with invalid file path. // Test add picture to worksheet with invalid file path.
err = xlsx.AddPicture("Sheet1", "G21", "./test/not_exists_dir/not_exists.icon", "") err = xlsx.AddPicture("Sheet1", "G21", filepath.Join("test", "not_exists_dir", "not_exists.icon"), "")
if assert.Error(t, err) { if assert.Error(t, err) {
assert.True(t, os.IsNotExist(err), "Expected os.IsNotExist(err) == true") assert.True(t, os.IsNotExist(err), "Expected os.IsNotExist(err) == true")
} }
// Test add picture to worksheet with unsupport file type. // Test add picture to worksheet with unsupport file type.
err = xlsx.AddPicture("Sheet1", "G21", "./test/Book1.xlsx", "") err = xlsx.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), "")
assert.EqualError(t, err, "unsupported image extension") assert.EqualError(t, err, "unsupported image extension")
err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1)) err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1))
...@@ -221,12 +222,12 @@ func TestBrokenFile(t *testing.T) { ...@@ -221,12 +222,12 @@ func TestBrokenFile(t *testing.T) {
t.Run("SaveAsEmptyStruct", func(t *testing.T) { t.Run("SaveAsEmptyStruct", func(t *testing.T) {
// Test write file with broken file struct with given path. // Test write file with broken file struct with given path.
assert.NoError(t, xlsx.SaveAs("./test/TestBrokenFile.SaveAsEmptyStruct.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestBrokenFile.SaveAsEmptyStruct.xlsx")))
}) })
t.Run("OpenBadWorkbook", func(t *testing.T) { t.Run("OpenBadWorkbook", func(t *testing.T) {
// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml. // Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
f3, err := OpenFile("./test/BadWorkbook.xlsx") f3, err := OpenFile(filepath.Join("test", "BadWorkbook.xlsx"))
f3.GetActiveSheetIndex() f3.GetActiveSheetIndex()
f3.SetActiveSheet(2) f3.SetActiveSheet(2)
assert.NoError(t, err) assert.NoError(t, err)
...@@ -234,7 +235,7 @@ func TestBrokenFile(t *testing.T) { ...@@ -234,7 +235,7 @@ func TestBrokenFile(t *testing.T) {
t.Run("OpenNotExistsFile", func(t *testing.T) { t.Run("OpenNotExistsFile", func(t *testing.T) {
// Test open a XLSX file with given illegal path. // Test open a XLSX file with given illegal path.
_, err := OpenFile("./test/NotExistsFile.xlsx") _, err := OpenFile(filepath.Join("test", "NotExistsFile.xlsx"))
if assert.Error(t, err) { if assert.Error(t, err) {
assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true") assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true")
} }
...@@ -252,24 +253,25 @@ func TestNewFile(t *testing.T) { ...@@ -252,24 +253,25 @@ func TestNewFile(t *testing.T) {
xlsx.SetActiveSheet(0) xlsx.SetActiveSheet(0)
// Test add picture to sheet with scaling and positioning. // Test add picture to sheet with scaling and positioning.
err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`) err := xlsx.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
`{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// Test add picture to worksheet without formatset. // Test add picture to worksheet without formatset.
err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "") err = xlsx.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), "")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
// Test add picture to worksheet with invalid formatset. // Test add picture to worksheet with invalid formatset.
err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", `{`) err = xlsx.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), `{`)
if !assert.Error(t, err) { if !assert.Error(t, err) {
t.FailNow() t.FailNow()
} }
assert.NoError(t, xlsx.SaveAs("./test/TestNewFile.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestNewFile.xlsx")))
} }
func TestColWidth(t *testing.T) { func TestColWidth(t *testing.T) {
...@@ -278,7 +280,7 @@ func TestColWidth(t *testing.T) { ...@@ -278,7 +280,7 @@ func TestColWidth(t *testing.T) {
xlsx.SetColWidth("Sheet1", "A", "B", 12) xlsx.SetColWidth("Sheet1", "A", "B", 12)
xlsx.GetColWidth("Sheet1", "A") xlsx.GetColWidth("Sheet1", "A")
xlsx.GetColWidth("Sheet1", "C") xlsx.GetColWidth("Sheet1", "C")
err := xlsx.SaveAs("./test/TestColWidth.xlsx") err := xlsx.SaveAs(filepath.Join("test", "TestColWidth.xlsx"))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
...@@ -291,7 +293,7 @@ func TestRowHeight(t *testing.T) { ...@@ -291,7 +293,7 @@ func TestRowHeight(t *testing.T) {
xlsx.SetRowHeight("Sheet1", 4, 90) xlsx.SetRowHeight("Sheet1", 4, 90)
t.Log(xlsx.GetRowHeight("Sheet1", 1)) t.Log(xlsx.GetRowHeight("Sheet1", 1))
t.Log(xlsx.GetRowHeight("Sheet1", 0)) t.Log(xlsx.GetRowHeight("Sheet1", 0))
err := xlsx.SaveAs("./test/TestRowHeight.xlsx") err := xlsx.SaveAs(filepath.Join("test", "TestRowHeight.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -299,7 +301,7 @@ func TestRowHeight(t *testing.T) { ...@@ -299,7 +301,7 @@ func TestRowHeight(t *testing.T) {
} }
func TestSetCellHyperLink(t *testing.T) { func TestSetCellHyperLink(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
...@@ -311,11 +313,11 @@ func TestSetCellHyperLink(t *testing.T) { ...@@ -311,11 +313,11 @@ func TestSetCellHyperLink(t *testing.T) {
xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location") xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location")
xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", "") xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", "")
xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location") xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location")
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellHyperLink.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellHyperLink.xlsx")))
} }
func TestGetCellHyperLink(t *testing.T) { func TestGetCellHyperLink(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -331,7 +333,7 @@ func TestGetCellHyperLink(t *testing.T) { ...@@ -331,7 +333,7 @@ func TestGetCellHyperLink(t *testing.T) {
} }
func TestSetCellFormula(t *testing.T) { func TestSetCellFormula(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -341,45 +343,45 @@ func TestSetCellFormula(t *testing.T) { ...@@ -341,45 +343,45 @@ func TestSetCellFormula(t *testing.T) {
// Test set cell formula with illegal rows number. // Test set cell formula with illegal rows number.
xlsx.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)") xlsx.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)")
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellFormula.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellFormula.xlsx")))
} }
func TestSetSheetBackground(t *testing.T) { func TestSetSheetBackground(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg") err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "images", "background.jpg"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg") err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "images", "background.jpg"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
assert.NoError(t, xlsx.SaveAs("./test/TestSetSheetBackground.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetSheetBackground.xlsx")))
} }
func TestSetSheetBackgroundErrors(t *testing.T) { func TestSetSheetBackgroundErrors(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
err = xlsx.SetSheetBackground("Sheet2", "./test/not_exists/not_exists.png") err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "not_exists", "not_exists.png"))
if assert.Error(t, err) { if assert.Error(t, err) {
assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true") assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true")
} }
err = xlsx.SetSheetBackground("Sheet2", "./test/Book1.xlsx") err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "Book1.xlsx"))
assert.EqualError(t, err, "unsupported image extension") assert.EqualError(t, err, "unsupported image extension")
} }
func TestMergeCell(t *testing.T) { func TestMergeCell(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -401,7 +403,7 @@ func TestMergeCell(t *testing.T) { ...@@ -401,7 +403,7 @@ func TestMergeCell(t *testing.T) {
xlsx.GetCellValue("Sheet2", "A6") // Merged cell ref is single coordinate. xlsx.GetCellValue("Sheet2", "A6") // Merged cell ref is single coordinate.
xlsx.GetCellFormula("Sheet1", "G12") xlsx.GetCellFormula("Sheet1", "G12")
assert.NoError(t, xlsx.SaveAs("./test/TestMergeCell.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestMergeCell.xlsx")))
} }
func TestGetMergeCells(t *testing.T) { func TestGetMergeCells(t *testing.T) {
...@@ -432,7 +434,7 @@ func TestGetMergeCells(t *testing.T) { ...@@ -432,7 +434,7 @@ func TestGetMergeCells(t *testing.T) {
}, },
} }
xlsx, err := OpenFile("./test/MergeCell.xlsx") xlsx, err := OpenFile(filepath.Join("test", "MergeCell.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -476,7 +478,7 @@ func TestSetCellStyleAlignment(t *testing.T) { ...@@ -476,7 +478,7 @@ func TestSetCellStyleAlignment(t *testing.T) {
// Test get cell style with given illegal rows number. // Test get cell style with given illegal rows number.
xlsx.GetCellStyle("Sheet1", "A") xlsx.GetCellStyle("Sheet1", "A")
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleAlignment.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleAlignment.xlsx")))
} }
func TestSetCellStyleBorder(t *testing.T) { func TestSetCellStyleBorder(t *testing.T) {
...@@ -514,7 +516,7 @@ func TestSetCellStyleBorder(t *testing.T) { ...@@ -514,7 +516,7 @@ func TestSetCellStyleBorder(t *testing.T) {
xlsx.SetCellStyle("Sheet1", "O22", "O22", style) xlsx.SetCellStyle("Sheet1", "O22", "O22", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleBorder.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleBorder.xlsx")))
} }
func TestSetCellStyleBorderErrors(t *testing.T) { func TestSetCellStyleBorderErrors(t *testing.T) {
...@@ -571,7 +573,7 @@ func TestSetCellStyleNumberFormat(t *testing.T) { ...@@ -571,7 +573,7 @@ func TestSetCellStyleNumberFormat(t *testing.T) {
} }
xlsx.SetCellStyle("Sheet2", "L33", "L33", style) xlsx.SetCellStyle("Sheet2", "L33", "L33", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleNumberFormat.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleNumberFormat.xlsx")))
} }
func TestSetCellStyleCurrencyNumberFormat(t *testing.T) { func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
...@@ -597,7 +599,7 @@ func TestSetCellStyleCurrencyNumberFormat(t *testing.T) { ...@@ -597,7 +599,7 @@ func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
xlsx.SetCellStyle("Sheet1", "A2", "A2", style) xlsx.SetCellStyle("Sheet1", "A2", "A2", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleCurrencyNumberFormat.TestBook3.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleCurrencyNumberFormat.TestBook3.xlsx")))
}) })
t.Run("TestBook4", func(t *testing.T) { t.Run("TestBook4", func(t *testing.T) {
...@@ -632,7 +634,7 @@ func TestSetCellStyleCurrencyNumberFormat(t *testing.T) { ...@@ -632,7 +634,7 @@ func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
} }
xlsx.SetCellStyle("Sheet1", "A2", "A2", style) xlsx.SetCellStyle("Sheet1", "A2", "A2", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleCurrencyNumberFormat.TestBook4.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleCurrencyNumberFormat.TestBook4.xlsx")))
}) })
} }
...@@ -651,7 +653,7 @@ func TestSetCellStyleCustomNumberFormat(t *testing.T) { ...@@ -651,7 +653,7 @@ func TestSetCellStyleCustomNumberFormat(t *testing.T) {
} }
xlsx.SetCellStyle("Sheet1", "A2", "A2", style) xlsx.SetCellStyle("Sheet1", "A2", "A2", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleCustomNumberFormat.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleCustomNumberFormat.xlsx")))
} }
func TestSetCellStyleFill(t *testing.T) { func TestSetCellStyleFill(t *testing.T) {
...@@ -686,7 +688,7 @@ func TestSetCellStyleFill(t *testing.T) { ...@@ -686,7 +688,7 @@ func TestSetCellStyleFill(t *testing.T) {
} }
xlsx.SetCellStyle("Sheet1", "O23", "O23", style) xlsx.SetCellStyle("Sheet1", "O23", "O23", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleFill.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleFill.xlsx")))
} }
func TestSetCellStyleFont(t *testing.T) { func TestSetCellStyleFont(t *testing.T) {
...@@ -731,7 +733,7 @@ func TestSetCellStyleFont(t *testing.T) { ...@@ -731,7 +733,7 @@ func TestSetCellStyleFont(t *testing.T) {
xlsx.SetCellStyle("Sheet2", "A5", "A5", style) xlsx.SetCellStyle("Sheet2", "A5", "A5", style)
assert.NoError(t, xlsx.SaveAs("./test/TestSetCellStyleFont.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleFont.xlsx")))
} }
func TestSetCellStyleProtection(t *testing.T) { func TestSetCellStyleProtection(t *testing.T) {
...@@ -747,7 +749,7 @@ func TestSetCellStyleProtection(t *testing.T) { ...@@ -747,7 +749,7 @@ func TestSetCellStyleProtection(t *testing.T) {
} }
xlsx.SetCellStyle("Sheet2", "A6", "A6", style) xlsx.SetCellStyle("Sheet2", "A6", "A6", style)
err = xlsx.SaveAs("./test/TestSetCellStyleProtection.xlsx") err = xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleProtection.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -761,7 +763,7 @@ func TestSetDeleteSheet(t *testing.T) { ...@@ -761,7 +763,7 @@ func TestSetDeleteSheet(t *testing.T) {
} }
xlsx.DeleteSheet("XLSXSheet3") xlsx.DeleteSheet("XLSXSheet3")
assert.NoError(t, xlsx.SaveAs("./test/TestSetDeleteSheet.TestBook3.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook3.xlsx")))
}) })
t.Run("TestBook4", func(t *testing.T) { t.Run("TestBook4", func(t *testing.T) {
...@@ -772,7 +774,7 @@ func TestSetDeleteSheet(t *testing.T) { ...@@ -772,7 +774,7 @@ func TestSetDeleteSheet(t *testing.T) {
xlsx.DeleteSheet("Sheet1") xlsx.DeleteSheet("Sheet1")
xlsx.AddComment("Sheet1", "A1", "") xlsx.AddComment("Sheet1", "A1", "")
xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`) xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
assert.NoError(t, xlsx.SaveAs("./test/TestSetDeleteSheet.TestBook4.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook4.xlsx")))
}) })
} }
...@@ -818,7 +820,7 @@ func TestSheetVisibility(t *testing.T) { ...@@ -818,7 +820,7 @@ func TestSheetVisibility(t *testing.T) {
xlsx.SetSheetVisible("Sheet1", true) xlsx.SetSheetVisible("Sheet1", true)
xlsx.GetSheetVisible("Sheet1") xlsx.GetSheetVisible("Sheet1")
assert.NoError(t, xlsx.SaveAs("./test/TestSheetVisibility.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSheetVisibility.xlsx")))
} }
func TestRowVisibility(t *testing.T) { func TestRowVisibility(t *testing.T) {
...@@ -831,7 +833,7 @@ func TestRowVisibility(t *testing.T) { ...@@ -831,7 +833,7 @@ func TestRowVisibility(t *testing.T) {
xlsx.SetRowVisible("Sheet3", 2, true) xlsx.SetRowVisible("Sheet3", 2, true)
xlsx.GetRowVisible("Sheet3", 2) xlsx.GetRowVisible("Sheet3", 2)
assert.NoError(t, xlsx.SaveAs("./test/TestRowVisibility.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestRowVisibility.xlsx")))
} }
func TestColumnVisibility(t *testing.T) { func TestColumnVisibility(t *testing.T) {
...@@ -845,7 +847,7 @@ func TestColumnVisibility(t *testing.T) { ...@@ -845,7 +847,7 @@ func TestColumnVisibility(t *testing.T) {
xlsx.SetColVisible("Sheet1", "F", true) xlsx.SetColVisible("Sheet1", "F", true)
xlsx.GetColVisible("Sheet1", "F") xlsx.GetColVisible("Sheet1", "F")
xlsx.SetColVisible("Sheet3", "E", false) xlsx.SetColVisible("Sheet3", "E", false)
assert.NoError(t, xlsx.SaveAs("./test/TestColumnVisibility.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestColumnVisibility.xlsx")))
}) })
t.Run("TestBook3", func(t *testing.T) { t.Run("TestBook3", func(t *testing.T) {
...@@ -872,7 +874,7 @@ func TestCopySheet(t *testing.T) { ...@@ -872,7 +874,7 @@ func TestCopySheet(t *testing.T) {
xlsx.SetCellValue("Sheet4", "F1", "Hello") xlsx.SetCellValue("Sheet4", "F1", "Hello")
assert.NotEqual(t, "Hello", xlsx.GetCellValue("Sheet1", "F1")) assert.NotEqual(t, "Hello", xlsx.GetCellValue("Sheet1", "F1"))
assert.NoError(t, xlsx.SaveAs("./test/TestCopySheet.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestCopySheet.xlsx")))
} }
func TestCopySheetError(t *testing.T) { func TestCopySheetError(t *testing.T) {
...@@ -886,7 +888,7 @@ func TestCopySheetError(t *testing.T) { ...@@ -886,7 +888,7 @@ func TestCopySheetError(t *testing.T) {
t.FailNow() t.FailNow()
} }
assert.NoError(t, xlsx.SaveAs("./test/TestCopySheetError.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestCopySheetError.xlsx")))
} }
func TestAddTable(t *testing.T) { func TestAddTable(t *testing.T) {
...@@ -910,7 +912,7 @@ func TestAddTable(t *testing.T) { ...@@ -910,7 +912,7 @@ func TestAddTable(t *testing.T) {
t.FailNow() t.FailNow()
} }
assert.NoError(t, xlsx.SaveAs("./test/TestAddTable.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddTable.xlsx")))
} }
func TestAddShape(t *testing.T) { func TestAddShape(t *testing.T) {
...@@ -925,7 +927,7 @@ func TestAddShape(t *testing.T) { ...@@ -925,7 +927,7 @@ func TestAddShape(t *testing.T) {
xlsx.AddShape("Sheet3", "H1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}], "height": 90}`) xlsx.AddShape("Sheet3", "H1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}], "height": 90}`)
xlsx.AddShape("Sheet3", "H1", "") xlsx.AddShape("Sheet3", "H1", "")
assert.NoError(t, xlsx.SaveAs("./test/TestAddShape.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddShape.xlsx")))
} }
func TestAddComments(t *testing.T) { func TestAddComments(t *testing.T) {
...@@ -938,12 +940,14 @@ func TestAddComments(t *testing.T) { ...@@ -938,12 +940,14 @@ func TestAddComments(t *testing.T) {
xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`) xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`) xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
if assert.NoError(t, xlsx.SaveAs("./test/TestAddComments.xlsx")) { if assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
assert.Len(t, xlsx.GetComments(), 2) assert.Len(t, xlsx.GetComments(), 2)
} }
} }
func TestAutoFilter(t *testing.T) { func TestAutoFilter(t *testing.T) {
outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")
xlsx, err := prepareTestBook1() xlsx, err := prepareTestBook1()
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
...@@ -964,7 +968,7 @@ func TestAutoFilter(t *testing.T) { ...@@ -964,7 +968,7 @@ func TestAutoFilter(t *testing.T) {
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
err = xlsx.AutoFilter("Sheet3", "D4", "B1", format) err = xlsx.AutoFilter("Sheet3", "D4", "B1", format)
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.NoError(t, xlsx.SaveAs(fmt.Sprintf("./test/TestAutoFilter%d.xlsx", i+1))) assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, i+1)))
} }
}) })
} }
...@@ -972,6 +976,8 @@ func TestAutoFilter(t *testing.T) { ...@@ -972,6 +976,8 @@ func TestAutoFilter(t *testing.T) {
} }
func TestAutoFilterError(t *testing.T) { func TestAutoFilterError(t *testing.T) {
outFile := filepath.Join("test", "TestAutoFilterError%d.xlsx")
xlsx, err := prepareTestBook1() xlsx, err := prepareTestBook1()
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
...@@ -989,14 +995,14 @@ func TestAutoFilterError(t *testing.T) { ...@@ -989,14 +995,14 @@ func TestAutoFilterError(t *testing.T) {
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
err = xlsx.AutoFilter("Sheet3", "D4", "B1", format) err = xlsx.AutoFilter("Sheet3", "D4", "B1", format)
if assert.Error(t, err) { if assert.Error(t, err) {
assert.NoError(t, xlsx.SaveAs(fmt.Sprintf("./test/TestAutoFilterError%d.xlsx", i+1))) assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, i+1)))
} }
}) })
} }
} }
func TestAddChart(t *testing.T) { func TestAddChart(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1037,7 +1043,7 @@ func TestAddChart(t *testing.T) { ...@@ -1037,7 +1043,7 @@ func TestAddChart(t *testing.T) {
xlsx.AddChart("Sheet2", "AF32", `{"type":"area3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet2", "AF32", `{"type":"area3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
xlsx.AddChart("Sheet2", "AN32", `{"type":"area3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D 100% Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet2", "AN32", `{"type":"area3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D 100% Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
assert.NoError(t, xlsx.SaveAs("./test/TestAddChart.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddChart.xlsx")))
} }
func TestInsertCol(t *testing.T) { func TestInsertCol(t *testing.T) {
...@@ -1057,7 +1063,7 @@ func TestInsertCol(t *testing.T) { ...@@ -1057,7 +1063,7 @@ func TestInsertCol(t *testing.T) {
xlsx.InsertCol("Sheet1", "A") xlsx.InsertCol("Sheet1", "A")
assert.NoError(t, xlsx.SaveAs("./test/TestInsertCol.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestInsertCol.xlsx")))
} }
func TestRemoveCol(t *testing.T) { func TestRemoveCol(t *testing.T) {
...@@ -1075,7 +1081,7 @@ func TestRemoveCol(t *testing.T) { ...@@ -1075,7 +1081,7 @@ func TestRemoveCol(t *testing.T) {
xlsx.RemoveCol("Sheet1", "A") xlsx.RemoveCol("Sheet1", "A")
xlsx.RemoveCol("Sheet1", "A") xlsx.RemoveCol("Sheet1", "A")
assert.NoError(t, xlsx.SaveAs("./test/TestRemoveCol.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestRemoveCol.xlsx")))
} }
func TestInsertRow(t *testing.T) { func TestInsertRow(t *testing.T) {
...@@ -1090,84 +1096,321 @@ func TestInsertRow(t *testing.T) { ...@@ -1090,84 +1096,321 @@ func TestInsertRow(t *testing.T) {
xlsx.InsertRow("Sheet1", -1) xlsx.InsertRow("Sheet1", -1)
xlsx.InsertRow("Sheet1", 4) xlsx.InsertRow("Sheet1", 4)
assert.NoError(t, xlsx.SaveAs("./test/TestInsertRow.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestInsertRow.xlsx")))
} }
func TestDuplicateRow(t *testing.T) { // Testing internal sructure state after insert operations.
const ( // It is important for insert workflow to be constant to avoid side effect with functions related to internal structure.
file = "./test/TestDuplicateRow" + func TestInsertRowInEmptyFile(t *testing.T) {
".%s.xlsx"
sheet = "Sheet1"
a1 = "A1"
b1 = "B1"
a2 = "A2"
b2 = "B2"
a3 = "A3"
b3 = "B3"
a4 = "A4"
b4 = "B4"
a1Value = "A1 value"
a2Value = "A2 value"
a3Value = "A3 value"
bnValue = "Bn value"
)
xlsx := NewFile() xlsx := NewFile()
xlsx.SetCellStr(sheet, a1, a1Value) sheet1 := xlsx.GetSheetName(1)
xlsx.SetCellStr(sheet, b1, bnValue) r := xlsx.workSheetReader(sheet1)
xlsx.InsertRow(sheet1, 0)
assert.Len(t, r.SheetData.Row, 0)
xlsx.InsertRow(sheet1, 1)
assert.Len(t, r.SheetData.Row, 0)
xlsx.InsertRow(sheet1, 99)
assert.Len(t, r.SheetData.Row, 0)
assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestInsertRowInEmptyFile.xlsx")))
}
func TestDuplicateRow(t *testing.T) {
const sheet = "Sheet1"
outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
cells := map[string]string{
"A1": "A1 Value",
"A2": "A2 Value",
"A3": "A3 Value",
"B1": "B1 Value",
"B2": "B2 Value",
"B3": "B3 Value",
}
newFileWithDefaults := func() *File {
f := NewFile()
for cell, val := range cells {
f.SetCellStr(sheet, cell, val)
}
return f
}
t.Run("FromSingleRow", func(t *testing.T) { t.Run("FromSingleRow", func(t *testing.T) {
xlsx := NewFile()
xlsx.SetCellStr(sheet, "A1", cells["A1"])
xlsx.SetCellStr(sheet, "B1", cells["B1"])
xlsx.DuplicateRow(sheet, 1) xlsx.DuplicateRow(sheet, 1)
xlsx.DuplicateRow(sheet, 2) if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.FromSingleRow_1"))) {
t.FailNow()
}
expect := map[string]string{
"A1": cells["A1"], "B1": cells["B1"],
"A2": cells["A1"], "B2": cells["B1"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
}
if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "TestDuplicateRow.FromSingleRow"))) { xlsx.DuplicateRow(sheet, 2)
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a1)) if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.FromSingleRow_2"))) {
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a2)) t.FailNow()
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a3)) }
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b1)) expect = map[string]string{
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2)) "A1": cells["A1"], "B1": cells["B1"],
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b3)) "A2": cells["A1"], "B2": cells["B1"],
"A3": cells["A1"], "B3": cells["B1"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
} }
}) })
t.Run("UpdateDuplicatedRows", func(t *testing.T) { t.Run("UpdateDuplicatedRows", func(t *testing.T) {
xlsx.SetCellStr(sheet, a2, a2Value) xlsx := NewFile()
xlsx.SetCellStr(sheet, a3, a3Value) xlsx.SetCellStr(sheet, "A1", cells["A1"])
xlsx.SetCellStr(sheet, "B1", cells["B1"])
if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "TestDuplicateRow.UpdateDuplicatedRows"))) { xlsx.DuplicateRow(sheet, 1)
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a1))
assert.Equal(t, a2Value, xlsx.GetCellValue(sheet, a2)) xlsx.SetCellStr(sheet, "A2", cells["A2"])
assert.Equal(t, a3Value, xlsx.GetCellValue(sheet, a3)) xlsx.SetCellStr(sheet, "B2", cells["B2"])
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b1))
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2)) if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.UpdateDuplicatedRows"))) {
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b3)) t.FailNow()
}
expect := map[string]string{
"A1": cells["A1"], "B1": cells["B1"],
"A2": cells["A2"], "B2": cells["B2"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
} }
}) })
t.Run("FromFirstOfMultipleRows", func(t *testing.T) { t.Run("FirstOfMultipleRows", func(t *testing.T) {
xlsx := newFileWithDefaults()
xlsx.DuplicateRow(sheet, 1) xlsx.DuplicateRow(sheet, 1)
if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "TestDuplicateRow.FromFirstOfMultipleRows"))) { if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.FirstOfMultipleRows"))) {
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a1)) t.FailNow()
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a2)) }
assert.Equal(t, a2Value, xlsx.GetCellValue(sheet, a3)) expect := map[string]string{
assert.Equal(t, a3Value, xlsx.GetCellValue(sheet, a4)) "A1": cells["A1"], "B1": cells["B1"],
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b1)) "A2": cells["A1"], "B2": cells["B1"],
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2)) "A3": cells["A2"], "B3": cells["B2"],
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b3)) "A4": cells["A3"], "B4": cells["B3"],
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b4)) }
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
} }
}) })
t.Run("ZeroAndNegativeRowNum", func(t *testing.T) { t.Run("ZeroWithNoRows", func(t *testing.T) {
xlsx.DuplicateRow(sheet, -1) xlsx := NewFile()
xlsx.DuplicateRow(sheet, 0) xlsx.DuplicateRow(sheet, 0)
if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "TestDuplicateRow.ZeroAndNegativeRowNum"))) {
assert.Equal(t, "", xlsx.GetCellValue(sheet, a1)) if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.ZeroWithNoRows"))) {
assert.Equal(t, "", xlsx.GetCellValue(sheet, b1)) t.FailNow()
assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a2)) }
assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2)) assert.Equal(t, "", xlsx.GetCellValue(sheet, "A1"))
assert.Equal(t, "", xlsx.GetCellValue(sheet, "B1"))
assert.Equal(t, "", xlsx.GetCellValue(sheet, "A2"))
assert.Equal(t, "", xlsx.GetCellValue(sheet, "B2"))
expect := map[string]string{
"A1": "", "B1": "",
"A2": "", "B2": "",
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
}
})
t.Run("MiddleRowOfEmptyFile", func(t *testing.T) {
xlsx := NewFile()
xlsx.DuplicateRow(sheet, 99)
if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.MiddleRowOfEmptyFile"))) {
t.FailNow()
}
expect := map[string]string{
"A98": "",
"A99": "",
"A100": "",
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
} }
}) })
t.Run("WithLargeOffsetToMiddleOfData", func(t *testing.T) {
xlsx := newFileWithDefaults()
xlsx.DuplicateRowTo(sheet, 1, 3)
if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.WithLargeOffsetToMiddleOfData"))) {
t.FailNow()
}
expect := map[string]string{
"A1": cells["A1"], "B1": cells["B1"],
"A2": cells["A2"], "B2": cells["B2"],
"A3": cells["A1"], "B3": cells["B1"],
"A4": cells["A3"], "B4": cells["B3"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
}
})
t.Run("WithLargeOffsetToEmptyRows", func(t *testing.T) {
xlsx := newFileWithDefaults()
xlsx.DuplicateRowTo(sheet, 1, 7)
if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.WithLargeOffsetToEmptyRows"))) {
t.FailNow()
}
expect := map[string]string{
"A1": cells["A1"], "B1": cells["B1"],
"A2": cells["A2"], "B2": cells["B2"],
"A3": cells["A3"], "B3": cells["B3"],
"A7": cells["A1"], "B7": cells["B1"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
}
})
t.Run("InsertBefore", func(t *testing.T) {
xlsx := newFileWithDefaults()
xlsx.DuplicateRowTo(sheet, 2, 1)
if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.InsertBefore"))) {
t.FailNow()
}
expect := map[string]string{
"A1": cells["A2"], "B1": cells["B2"],
"A2": cells["A1"], "B2": cells["B1"],
"A3": cells["A2"], "B3": cells["B2"],
"A4": cells["A3"], "B4": cells["B3"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell), cell) {
t.FailNow()
}
}
})
t.Run("InsertBeforeWithLargeOffset", func(t *testing.T) {
xlsx := newFileWithDefaults()
xlsx.DuplicateRowTo(sheet, 3, 1)
if !assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.InsertBeforeWithLargeOffset"))) {
t.FailNow()
}
expect := map[string]string{
"A1": cells["A3"], "B1": cells["B3"],
"A2": cells["A1"], "B2": cells["B1"],
"A3": cells["A2"], "B3": cells["B2"],
"A4": cells["A3"], "B4": cells["B3"],
}
for cell, val := range expect {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, cell)) {
t.FailNow()
}
}
})
}
func TestDuplicateRowInvalidRownum(t *testing.T) {
const sheet = "Sheet1"
outFile := filepath.Join("test", "TestDuplicateRowInvalidRownum.%s.xlsx")
cells := map[string]string{
"A1": "A1 Value",
"A2": "A2 Value",
"A3": "A3 Value",
"B1": "B1 Value",
"B2": "B2 Value",
"B3": "B3 Value",
}
testRows := []int{-2, -1}
testRowPairs := []struct {
row1 int
row2 int
}{
{-1, -1},
{-1, 0},
{-1, 1},
{0, -1},
{0, 0},
{0, 1},
{1, -1},
{1, 1},
{1, 0},
}
for i, row := range testRows {
name := fmt.Sprintf("TestRow_%d", i+1)
t.Run(name, func(t *testing.T) {
xlsx := NewFile()
for col, val := range cells {
xlsx.SetCellStr(sheet, col, val)
}
xlsx.DuplicateRow(sheet, row)
for col, val := range cells {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, col)) {
t.FailNow()
}
}
assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, name)))
})
}
for i, pair := range testRowPairs {
name := fmt.Sprintf("TestRowPair_%d", i+1)
t.Run(name, func(t *testing.T) {
xlsx := NewFile()
for col, val := range cells {
xlsx.SetCellStr(sheet, col, val)
}
xlsx.DuplicateRowTo(sheet, pair.row1, pair.row2)
for col, val := range cells {
if !assert.Equal(t, val, xlsx.GetCellValue(sheet, col)) {
t.FailNow()
}
}
assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, name)))
})
}
} }
func TestSetPane(t *testing.T) { func TestSetPane(t *testing.T) {
...@@ -1181,7 +1424,7 @@ func TestSetPane(t *testing.T) { ...@@ -1181,7 +1424,7 @@ func TestSetPane(t *testing.T) {
xlsx.SetPanes("Panes 4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`) xlsx.SetPanes("Panes 4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`)
xlsx.SetPanes("Panes 4", "") xlsx.SetPanes("Panes 4", "")
assert.NoError(t, xlsx.SaveAs("./test/TestSetPane.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
} }
func TestRemoveRow(t *testing.T) { func TestRemoveRow(t *testing.T) {
...@@ -1208,7 +1451,7 @@ func TestRemoveRow(t *testing.T) { ...@@ -1208,7 +1451,7 @@ func TestRemoveRow(t *testing.T) {
xlsx.RemoveRow("Sheet1", 1) xlsx.RemoveRow("Sheet1", 1)
xlsx.RemoveRow("Sheet1", 0) xlsx.RemoveRow("Sheet1", 0)
assert.NoError(t, xlsx.SaveAs("./test/TestRemoveRow.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestRemoveRow.xlsx")))
} }
func TestConditionalFormat(t *testing.T) { func TestConditionalFormat(t *testing.T) {
...@@ -1265,7 +1508,7 @@ func TestConditionalFormat(t *testing.T) { ...@@ -1265,7 +1508,7 @@ func TestConditionalFormat(t *testing.T) {
// Test set invalid format set in conditional format // Test set invalid format set in conditional format
xlsx.SetConditionalFormat("Sheet1", "L1:L10", "") xlsx.SetConditionalFormat("Sheet1", "L1:L10", "")
err = xlsx.SaveAs("./test/TestConditionalFormat.xlsx") err = xlsx.SaveAs(filepath.Join("test", "TestConditionalFormat.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1276,7 +1519,7 @@ func TestConditionalFormat(t *testing.T) { ...@@ -1276,7 +1519,7 @@ func TestConditionalFormat(t *testing.T) {
xlsx.SetConditionalFormat("Sheet1", "K1:K10", `[{"type":"data_bar", "criteria":"", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`) xlsx.SetConditionalFormat("Sheet1", "K1:K10", `[{"type":"data_bar", "criteria":"", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
// Set conditional format with file without dxfs element shold not return error. // Set conditional format with file without dxfs element shold not return error.
xlsx, err = OpenFile("./test/Book1.xlsx") xlsx, err = OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1308,7 +1551,7 @@ func TestTitleToNumber(t *testing.T) { ...@@ -1308,7 +1551,7 @@ func TestTitleToNumber(t *testing.T) {
} }
func TestSharedStrings(t *testing.T) { func TestSharedStrings(t *testing.T) {
xlsx, err := OpenFile("./test/SharedStrings.xlsx") xlsx, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1316,7 +1559,7 @@ func TestSharedStrings(t *testing.T) { ...@@ -1316,7 +1559,7 @@ func TestSharedStrings(t *testing.T) {
} }
func TestSetSheetRow(t *testing.T) { func TestSetSheetRow(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1326,11 +1569,11 @@ func TestSetSheetRow(t *testing.T) { ...@@ -1326,11 +1569,11 @@ func TestSetSheetRow(t *testing.T) {
xlsx.SetSheetRow("Sheet1", "B27", []interface{}{}) xlsx.SetSheetRow("Sheet1", "B27", []interface{}{})
xlsx.SetSheetRow("Sheet1", "B27", &xlsx) xlsx.SetSheetRow("Sheet1", "B27", &xlsx)
assert.NoError(t, xlsx.SaveAs("./test/TestSetSheetRow.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetSheetRow.xlsx")))
} }
func TestRows(t *testing.T) { func TestRows(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1365,7 +1608,7 @@ func TestRows(t *testing.T) { ...@@ -1365,7 +1608,7 @@ func TestRows(t *testing.T) {
} }
func TestRowsError(t *testing.T) { func TestRowsError(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1383,12 +1626,12 @@ func TestOutlineLevel(t *testing.T) { ...@@ -1383,12 +1626,12 @@ func TestOutlineLevel(t *testing.T) {
xlsx.SetColOutlineLevel("Sheet2", "B", 2) xlsx.SetColOutlineLevel("Sheet2", "B", 2)
xlsx.SetRowOutlineLevel("Sheet1", 2, 1) xlsx.SetRowOutlineLevel("Sheet1", 2, 1)
xlsx.GetRowOutlineLevel("Sheet1", 2) xlsx.GetRowOutlineLevel("Sheet1", 2)
err := xlsx.SaveAs("./test/TestOutlineLevel.xlsx") err := xlsx.SaveAs(filepath.Join("test", "TestOutlineLevel.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
xlsx, err = OpenFile("./test/Book1.xlsx") xlsx, err = OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1422,7 +1665,7 @@ func TestHSL(t *testing.T) { ...@@ -1422,7 +1665,7 @@ func TestHSL(t *testing.T) {
} }
func TestSearchSheet(t *testing.T) { func TestSearchSheet(t *testing.T) {
xlsx, err := OpenFile("./test/SharedStrings.xlsx") xlsx, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
...@@ -1445,17 +1688,17 @@ func TestProtectSheet(t *testing.T) { ...@@ -1445,17 +1688,17 @@ func TestProtectSheet(t *testing.T) {
EditScenarios: false, EditScenarios: false,
}) })
assert.NoError(t, xlsx.SaveAs("./test/TestProtectSheet.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestProtectSheet.xlsx")))
} }
func TestUnprotectSheet(t *testing.T) { func TestUnprotectSheet(t *testing.T) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
xlsx.UnprotectSheet("Sheet1") xlsx.UnprotectSheet("Sheet1")
assert.NoError(t, xlsx.SaveAs("./test/TestUnprotectSheet.xlsx")) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestUnprotectSheet.xlsx")))
} }
func trimSliceSpace(s []string) []string { func trimSliceSpace(s []string) []string {
...@@ -1470,25 +1713,25 @@ func trimSliceSpace(s []string) []string { ...@@ -1470,25 +1713,25 @@ func trimSliceSpace(s []string) []string {
} }
func prepareTestBook1() (*File, error) { func prepareTestBook1() (*File, error) {
xlsx, err := OpenFile("./test/Book1.xlsx") xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", err = xlsx.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
`{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`) `{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Test add picture to worksheet with offset, external hyperlink and positioning. // Test add picture to worksheet with offset, external hyperlink and positioning.
err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", err = xlsx.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.png"),
`{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`) `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
if err != nil { if err != nil {
return nil, err return nil, err
} }
file, err := ioutil.ReadFile("./test/images/excel.jpg") file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.jpg"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -1510,12 +1753,13 @@ func prepareTestBook3() (*File, error) { ...@@ -1510,12 +1753,13 @@ func prepareTestBook3() (*File, error) {
xlsx.SetCellStr("Sheet1", "B20", "42") xlsx.SetCellStr("Sheet1", "B20", "42")
xlsx.SetActiveSheet(0) xlsx.SetActiveSheet(0)
err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`) err := xlsx.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
`{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "") err = xlsx.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), "")
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -3,6 +3,5 @@ module github.com/360EntSecGroup-Skylar/excelize ...@@ -3,6 +3,5 @@ module github.com/360EntSecGroup-Skylar/excelize
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.3.0
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb
) )
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb h1:cRItZejS4Ok67vfCdrbGIaqk86wmtQNOjVD7jSyS2aw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
...@@ -376,38 +376,55 @@ func (f *File) InsertRow(sheet string, row int) { ...@@ -376,38 +376,55 @@ func (f *File) InsertRow(sheet string, row int) {
// xlsx.DuplicateRow("Sheet1", 2) // xlsx.DuplicateRow("Sheet1", 2)
// //
func (f *File) DuplicateRow(sheet string, row int) { func (f *File) DuplicateRow(sheet string, row int) {
if row < 0 { f.DuplicateRowTo(sheet, row, row+1)
}
// DuplicateRowTo inserts a copy of specified row at specified row position
// movig down exists rows aftet target position
//
// xlsx.DuplicateRowTo("Sheet1", 2, 7)
//
func (f *File) DuplicateRowTo(sheet string, row, row2 int) {
if row <= 0 || row2 <= 0 || row == row2 {
return return
} }
row2 := row + 1
f.adjustHelper(sheet, -1, row2, 1)
xlsx := f.workSheetReader(sheet) ws := f.workSheetReader(sheet)
idx := -1
idx2 := -1
for i, r := range xlsx.SheetData.Row { var ok bool
var rowCopy xlsxRow
for i, r := range ws.SheetData.Row {
if r.R == row { if r.R == row {
idx = i rowCopy = ws.SheetData.Row[i]
} else if r.R == row2 { ok = true
idx2 = i
}
if idx != -1 && idx2 != -1 {
break break
} }
} }
if !ok {
return
}
if idx == -1 || (idx2 == -1 && len(xlsx.SheetData.Row) >= row2) { f.adjustHelper(sheet, -1, row2, 1)
idx2 := -1
for i, r := range ws.SheetData.Row {
if r.R == row2 {
idx2 = i
break
}
}
if idx2 == -1 && len(ws.SheetData.Row) >= row2 {
return return
} }
rowData := xlsx.SheetData.Row[idx]
cols := make([]xlsxC, 0, len(rowData.C)) rowCopy.C = append(make([]xlsxC, 0, len(rowCopy.C)), rowCopy.C...)
rowData.C = append(cols, rowData.C...) f.ajustSingleRowDimensions(&rowCopy, row2)
f.ajustSingleRowDimensions(&rowData, 1)
if idx2 != -1 { if idx2 != -1 {
xlsx.SheetData.Row[idx2] = rowData ws.SheetData.Row[idx2] = rowCopy
} else { } else {
xlsx.SheetData.Row = append(xlsx.SheetData.Row, rowData) ws.SheetData.Row = append(ws.SheetData.Row, rowCopy)
} }
} }
...@@ -446,7 +463,7 @@ func checkRow(xlsx *xlsxWorksheet) { ...@@ -446,7 +463,7 @@ func checkRow(xlsx *xlsxWorksheet) {
if lenCol < endCol { if lenCol < endCol {
oldRow := xlsx.SheetData.Row[k].C oldRow := xlsx.SheetData.Row[k].C
xlsx.SheetData.Row[k].C = xlsx.SheetData.Row[k].C[:0] xlsx.SheetData.Row[k].C = xlsx.SheetData.Row[k].C[:0]
tmp := []xlsxC{} var tmp []xlsxC
for i := 0; i < endCol; i++ { for i := 0; i < endCol; i++ {
buffer.WriteString(ToAlphaString(i)) buffer.WriteString(ToAlphaString(i))
buffer.WriteString(strconv.Itoa(endRow)) buffer.WriteString(strconv.Itoa(endRow))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册