提交 576bfffb 编写于 作者: xurime's avatar xurime

This closes #752, fix incorrectly merged cells on duplicate row, and new...

This closes #752, fix incorrectly merged cells on duplicate row, and new formula function: LOWER, PROPER, UPPER
上级 77978ac6
...@@ -97,7 +97,7 @@ func main() { ...@@ -97,7 +97,7 @@ func main() {
### Add chart to spreadsheet file ### Add chart to spreadsheet file
With Excelize chart generation and management is as easy as a few lines of code. You can build charts based off data in your worksheet or generate charts without any data in your worksheet at all. With Excelize chart generation and management is as easy as a few lines of code. You can build charts based on data in your worksheet or generate charts without any data in your worksheet at all.
<p align="center"><img width="650" src="./test/images/chart.png" alt="Excelize"></p> <p align="center"><img width="650" src="./test/images/chart.png" alt="Excelize"></p>
...@@ -111,8 +111,10 @@ import ( ...@@ -111,8 +111,10 @@ import (
) )
func main() { func main() {
categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"} categories := map[string]string{
values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} "A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
values := map[string]int{
"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8}
f := excelize.NewFile() f := excelize.NewFile()
for k, v := range categories { for k, v := range categories {
f.SetCellValue("Sheet1", k, v) f.SetCellValue("Sheet1", k, v)
...@@ -120,7 +122,29 @@ func main() { ...@@ -120,7 +122,29 @@ func main() {
for k, v := range values { for k, v := range values {
f.SetCellValue("Sheet1", k, v) f.SetCellValue("Sheet1", k, v)
} }
if err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`); err != nil { if err := f.AddChart("Sheet1", "E1", `{
"type": "col3DClustered",
"series": [
{
"name": "Sheet1!$A$2",
"categories": "Sheet1!$B$1:$D$1",
"values": "Sheet1!$B$2:$D$2"
},
{
"name": "Sheet1!$A$3",
"categories": "Sheet1!$B$1:$D$1",
"values": "Sheet1!$B$3:$D$3"
},
{
"name": "Sheet1!$A$4",
"categories": "Sheet1!$B$1:$D$1",
"values": "Sheet1!$B$4:$D$4"
}],
"title":
{
"name": "Fruit 3D Clustered Column Chart"
}
}`); err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
...@@ -156,11 +180,18 @@ func main() { ...@@ -156,11 +180,18 @@ func main() {
fmt.Println(err) fmt.Println(err)
} }
// Insert a picture to worksheet with scaling. // Insert a picture to worksheet with scaling.
if err := f.AddPicture("Sheet1", "D2", "image.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`); err != nil { if err := f.AddPicture("Sheet1", "D2", "image.jpg",
`{"x_scale": 0.5, "y_scale": 0.5}`); err != nil {
fmt.Println(err) fmt.Println(err)
} }
// Insert a picture offset in the cell with printing support. // Insert a picture offset in the cell with printing support.
if err := f.AddPicture("Sheet1", "H2", "image.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`); err != nil { if err := f.AddPicture("Sheet1", "H2", "image.gif", `{
"x_offset": 15,
"y_offset": 10,
"print_obj": true,
"lock_aspect_ratio": false,
"locked": false
}`); err != nil {
fmt.Println(err) fmt.Println(err)
} }
// Save the spreadsheet with the origin path. // Save the spreadsheet with the origin path.
......
...@@ -99,7 +99,7 @@ func main() { ...@@ -99,7 +99,7 @@ func main() {
使用 Excelize 生成图表十分简单,仅需几行代码。您可以根据工作表中的已有数据构建图表,或向工作表中添加数据并创建图表。 使用 Excelize 生成图表十分简单,仅需几行代码。您可以根据工作表中的已有数据构建图表,或向工作表中添加数据并创建图表。
<p align="center"><img width="650" src="./test/images/chart.png" alt="Excelize"></p> <p align="center"><img width="650" src="./test/images/chart.png" alt="使用 Excelize 在 Excel 电子表格文档中创建图表"></p>
```go ```go
package main package main
...@@ -111,8 +111,10 @@ import ( ...@@ -111,8 +111,10 @@ import (
) )
func main() { func main() {
categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"} categories := map[string]string{
values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} "A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
values := map[string]int{
"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8}
f := excelize.NewFile() f := excelize.NewFile()
for k, v := range categories { for k, v := range categories {
f.SetCellValue("Sheet1", k, v) f.SetCellValue("Sheet1", k, v)
...@@ -120,7 +122,29 @@ func main() { ...@@ -120,7 +122,29 @@ func main() {
for k, v := range values { for k, v := range values {
f.SetCellValue("Sheet1", k, v) f.SetCellValue("Sheet1", k, v)
} }
if err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`); err != nil { if err := f.AddChart("Sheet1", "E1", `{
"type": "col3DClustered",
"series": [
{
"name": "Sheet1!$A$2",
"categories": "Sheet1!$B$1:$D$1",
"values": "Sheet1!$B$2:$D$2"
},
{
"name": "Sheet1!$A$3",
"categories": "Sheet1!$B$1:$D$1",
"values": "Sheet1!$B$3:$D$3"
},
{
"name": "Sheet1!$A$4",
"categories": "Sheet1!$B$1:$D$1",
"values": "Sheet1!$B$4:$D$4"
}],
"title":
{
"name": "Fruit 3D Clustered Column Chart"
}
}`); err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
...@@ -156,11 +180,18 @@ func main() { ...@@ -156,11 +180,18 @@ func main() {
fmt.Println(err) fmt.Println(err)
} }
// 在工作表中插入图片,并设置图片的缩放比例 // 在工作表中插入图片,并设置图片的缩放比例
if err := f.AddPicture("Sheet1", "D2", "image.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`); err != nil { if err := f.AddPicture("Sheet1", "D2", "image.jpg",
`{"x_scale": 0.5, "y_scale": 0.5}`); err != nil {
fmt.Println(err) fmt.Println(err)
} }
// 在工作表中插入图片,并设置图片的打印属性 // 在工作表中插入图片,并设置图片的打印属性
if err := f.AddPicture("Sheet1", "H2", "image.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`); err != nil { if err := f.AddPicture("Sheet1", "H2", "image.gif", `{
"x_offset": 15,
"y_offset": 10,
"print_obj": true,
"lock_aspect_ratio": false,
"locked": false
}`); err != nil {
fmt.Println(err) fmt.Println(err)
} }
// 保存文件 // 保存文件
......
此差异已折叠。
...@@ -470,6 +470,21 @@ func TestCalcCellValue(t *testing.T) { ...@@ -470,6 +470,21 @@ func TestCalcCellValue(t *testing.T) {
// TRIM // TRIM
"=TRIM(\" trim text \")": "trim text", "=TRIM(\" trim text \")": "trim text",
"=TRIM(0)": "0", "=TRIM(0)": "0",
// LOWER
"=LOWER(\"test\")": "test",
"=LOWER(\"TEST\")": "test",
"=LOWER(\"Test\")": "test",
"=LOWER(\"TEST 123\")": "test 123",
// PROPER
"=PROPER(\"this is a test sentence\")": "This Is A Test Sentence",
"=PROPER(\"THIS IS A TEST SENTENCE\")": "This Is A Test Sentence",
"=PROPER(\"123tEST teXT\")": "123Test Text",
"=PROPER(\"Mr. SMITH's address\")": "Mr. Smith'S Address",
// UPPER
"=UPPER(\"test\")": "TEST",
"=UPPER(\"TEST\")": "TEST",
"=UPPER(\"Test\")": "TEST",
"=UPPER(\"TEST 123\")": "TEST 123",
} }
for formula, expected := range mathCalc { for formula, expected := range mathCalc {
f := prepareData() f := prepareData()
...@@ -793,6 +808,15 @@ func TestCalcCellValue(t *testing.T) { ...@@ -793,6 +808,15 @@ func TestCalcCellValue(t *testing.T) {
// TRIM // TRIM
"=TRIM()": "TRIM requires 1 argument", "=TRIM()": "TRIM requires 1 argument",
"=TRIM(1,2)": "TRIM requires 1 argument", "=TRIM(1,2)": "TRIM requires 1 argument",
// LOWER
"=LOWER()": "LOWER requires 1 argument",
"=LOWER(1,2)": "LOWER requires 1 argument",
// UPPER
"=UPPER()": "UPPER requires 1 argument",
"=UPPER(1,2)": "UPPER requires 1 argument",
// PROPER
"=PROPER()": "PROPER requires 1 argument",
"=PROPER(1,2)": "PROPER requires 1 argument",
} }
for formula, expected := range mathCalcError { for formula, expected := range mathCalcError {
f := prepareData() f := prepareData()
......
...@@ -602,7 +602,6 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in ...@@ -602,7 +602,6 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
if err := f.MergeCell(sheet, from, to); err != nil { if err := f.MergeCell(sheet, from, to); err != nil {
return err return err
} }
i++
} }
} }
return nil return nil
......
...@@ -323,7 +323,7 @@ func TestDuplicateRowFromSingleRow(t *testing.T) { ...@@ -323,7 +323,7 @@ func TestDuplicateRowFromSingleRow(t *testing.T) {
assert.NoError(t, f.SetCellStr(sheet, "B1", cells["B1"])) assert.NoError(t, f.SetCellStr(sheet, "B1", cells["B1"]))
assert.NoError(t, f.DuplicateRow(sheet, 1)) assert.NoError(t, f.DuplicateRow(sheet, 1))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.FromSingleRow_1"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "FromSingleRow_1"))) {
t.FailNow() t.FailNow()
} }
expect := map[string]string{ expect := map[string]string{
...@@ -339,7 +339,7 @@ func TestDuplicateRowFromSingleRow(t *testing.T) { ...@@ -339,7 +339,7 @@ func TestDuplicateRowFromSingleRow(t *testing.T) {
} }
assert.NoError(t, f.DuplicateRow(sheet, 2)) assert.NoError(t, f.DuplicateRow(sheet, 2))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.FromSingleRow_2"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "FromSingleRow_2"))) {
t.FailNow() t.FailNow()
} }
expect = map[string]string{ expect = map[string]string{
...@@ -380,7 +380,7 @@ func TestDuplicateRowUpdateDuplicatedRows(t *testing.T) { ...@@ -380,7 +380,7 @@ func TestDuplicateRowUpdateDuplicatedRows(t *testing.T) {
assert.NoError(t, f.SetCellStr(sheet, "A2", cells["A2"])) assert.NoError(t, f.SetCellStr(sheet, "A2", cells["A2"]))
assert.NoError(t, f.SetCellStr(sheet, "B2", cells["B2"])) assert.NoError(t, f.SetCellStr(sheet, "B2", cells["B2"]))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.UpdateDuplicatedRows"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "UpdateDuplicatedRows"))) {
t.FailNow() t.FailNow()
} }
expect := map[string]string{ expect := map[string]string{
...@@ -423,7 +423,7 @@ func TestDuplicateRowFirstOfMultipleRows(t *testing.T) { ...@@ -423,7 +423,7 @@ func TestDuplicateRowFirstOfMultipleRows(t *testing.T) {
assert.NoError(t, f.DuplicateRow(sheet, 1)) assert.NoError(t, f.DuplicateRow(sheet, 1))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.FirstOfMultipleRows"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "FirstOfMultipleRows"))) {
t.FailNow() t.FailNow()
} }
expect := map[string]string{ expect := map[string]string{
...@@ -451,7 +451,7 @@ func TestDuplicateRowZeroWithNoRows(t *testing.T) { ...@@ -451,7 +451,7 @@ func TestDuplicateRowZeroWithNoRows(t *testing.T) {
assert.EqualError(t, f.DuplicateRow(sheet, 0), "invalid row number 0") assert.EqualError(t, f.DuplicateRow(sheet, 0), "invalid row number 0")
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.ZeroWithNoRows"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "ZeroWithNoRows"))) {
t.FailNow() t.FailNow()
} }
...@@ -493,7 +493,7 @@ func TestDuplicateRowMiddleRowOfEmptyFile(t *testing.T) { ...@@ -493,7 +493,7 @@ func TestDuplicateRowMiddleRowOfEmptyFile(t *testing.T) {
assert.NoError(t, f.DuplicateRow(sheet, 99)) assert.NoError(t, f.DuplicateRow(sheet, 99))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.MiddleRowOfEmptyFile"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "MiddleRowOfEmptyFile"))) {
t.FailNow() t.FailNow()
} }
expect := map[string]string{ expect := map[string]string{
...@@ -537,7 +537,7 @@ func TestDuplicateRowWithLargeOffsetToMiddleOfData(t *testing.T) { ...@@ -537,7 +537,7 @@ func TestDuplicateRowWithLargeOffsetToMiddleOfData(t *testing.T) {
assert.NoError(t, f.DuplicateRowTo(sheet, 1, 3)) assert.NoError(t, f.DuplicateRowTo(sheet, 1, 3))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.WithLargeOffsetToMiddleOfData"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "WithLargeOffsetToMiddleOfData"))) {
t.FailNow() t.FailNow()
} }
expect := map[string]string{ expect := map[string]string{
...@@ -582,7 +582,7 @@ func TestDuplicateRowWithLargeOffsetToEmptyRows(t *testing.T) { ...@@ -582,7 +582,7 @@ func TestDuplicateRowWithLargeOffsetToEmptyRows(t *testing.T) {
assert.NoError(t, f.DuplicateRowTo(sheet, 1, 7)) assert.NoError(t, f.DuplicateRowTo(sheet, 1, 7))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.WithLargeOffsetToEmptyRows"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "WithLargeOffsetToEmptyRows"))) {
t.FailNow() t.FailNow()
} }
expect := map[string]string{ expect := map[string]string{
...@@ -627,7 +627,7 @@ func TestDuplicateRowInsertBefore(t *testing.T) { ...@@ -627,7 +627,7 @@ func TestDuplicateRowInsertBefore(t *testing.T) {
assert.NoError(t, f.DuplicateRowTo(sheet, 2, 1)) assert.NoError(t, f.DuplicateRowTo(sheet, 2, 1))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.InsertBefore"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "InsertBefore"))) {
t.FailNow() t.FailNow()
} }
...@@ -673,7 +673,7 @@ func TestDuplicateRowInsertBeforeWithLargeOffset(t *testing.T) { ...@@ -673,7 +673,7 @@ func TestDuplicateRowInsertBeforeWithLargeOffset(t *testing.T) {
assert.NoError(t, f.DuplicateRowTo(sheet, 3, 1)) assert.NoError(t, f.DuplicateRowTo(sheet, 3, 1))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.InsertBeforeWithLargeOffset"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "InsertBeforeWithLargeOffset"))) {
t.FailNow() t.FailNow()
} }
...@@ -722,7 +722,7 @@ func TestDuplicateRowInsertBeforeWithMergeCells(t *testing.T) { ...@@ -722,7 +722,7 @@ func TestDuplicateRowInsertBeforeWithMergeCells(t *testing.T) {
assert.NoError(t, f.DuplicateRowTo(sheet, 2, 1)) assert.NoError(t, f.DuplicateRowTo(sheet, 2, 1))
assert.NoError(t, f.DuplicateRowTo(sheet, 1, 8)) assert.NoError(t, f.DuplicateRowTo(sheet, 1, 8))
if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "TestDuplicateRow.InsertBeforeWithMergeCells"))) { if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "InsertBeforeWithMergeCells"))) {
t.FailNow() t.FailNow()
} }
...@@ -742,9 +742,9 @@ func TestDuplicateRowInsertBeforeWithMergeCells(t *testing.T) { ...@@ -742,9 +742,9 @@ func TestDuplicateRowInsertBeforeWithMergeCells(t *testing.T) {
}) })
} }
func TestDuplicateRowInvalidRownum(t *testing.T) { func TestDuplicateRowInvalidRowNum(t *testing.T) {
const sheet = "Sheet1" const sheet = "Sheet1"
outFile := filepath.Join("test", "TestDuplicateRowInvalidRownum.%s.xlsx") outFile := filepath.Join("test", "TestDuplicateRow.InvalidRowNum.%s.xlsx")
cells := map[string]string{ cells := map[string]string{
"A1": "A1 Value", "A1": "A1 Value",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册