已验证 提交 ae2865d9 编写于 作者: xurime's avatar xurime

Improve code coverage unit tests

上级 7358dca4
package excelize
import "testing"
func TestCalcChainReader(t *testing.T) {
f := NewFile()
f.CalcChain = nil
f.XLSX["xl/calcChain.xml"] = MacintoshCyrillicCharset
f.calcChainReader()
}
func TestDeleteCalcChain(t *testing.T) {
f := NewFile()
f.CalcChain = &xlsxCalcChain{C: []xlsxCalcChainC{}}
f.ContentTypes.Overrides = append(f.ContentTypes.Overrides, xlsxOverride{
PartName: "/xl/calcChain.xml",
})
f.deleteCalcChain(1, "A1")
}
......@@ -95,8 +95,15 @@ func TestSetCellBool(t *testing.T) {
}
func TestGetCellFormula(t *testing.T) {
// Test get cell formula on not exist worksheet.
f := NewFile()
f.GetCellFormula("Sheet", "A1")
_, err := f.GetCellFormula("SheetN", "A1")
assert.EqualError(t, err, "sheet SheetN is not exist")
// Test get cell formula on no formula cell.
f.SetCellValue("Sheet1", "A1", true)
_, err = f.GetCellFormula("Sheet1", "A1")
assert.NoError(t, err)
}
func ExampleFile_SetCellFloat() {
......
// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
// charts of XLSX. This library needs Go version 1.10 or later.
package excelize
import (
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestAddComments(t *testing.T) {
f, err := prepareTestBook1()
if !assert.NoError(t, err) {
t.FailNow()
}
s := strings.Repeat("c", 32768)
assert.NoError(t, f.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`))
assert.NoError(t, f.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`))
// Test add comment on not exists worksheet.
assert.EqualError(t, f.AddComment("SheetN", "B7", `{"author":"Excelize: ","text":"This is a comment."}`), "sheet SheetN is not exist")
if assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
assert.Len(t, f.GetComments(), 2)
}
}
func TestDecodeVMLDrawingReader(t *testing.T) {
f := NewFile()
path := "xl/drawings/vmlDrawing1.xml"
f.XLSX[path] = MacintoshCyrillicCharset
f.decodeVMLDrawingReader(path)
}
func TestCommentsReader(t *testing.T) {
f := NewFile()
path := "xl/comments1.xml"
f.XLSX[path] = MacintoshCyrillicCharset
f.commentsReader(path)
}
func TestCountComments(t *testing.T) {
f := NewFile()
f.Comments["xl/comments1.xml"] = nil
assert.Equal(t, f.countComments(), 1)
}
......@@ -11,6 +11,7 @@ package excelize
import (
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
......@@ -85,4 +86,12 @@ func TestDataValidationError(t *testing.T) {
if !assert.NoError(t, f.SaveAs(resultFile)) {
t.FailNow()
}
// Test width invalid data validation formula.
dvRange.Formula1 = strings.Repeat("s", dataValidationFormulaStrLen+22)
assert.EqualError(t, dvRange.SetRange(10, 20, DataValidationTypeWhole, DataValidationOperatorGreaterThan), "data validation must be 0-255 characters")
// Test add data validation on no exists worksheet.
f = NewFile()
assert.EqualError(t, f.AddDataValidation("SheetN", nil), "sheet SheetN is not exist")
}
......@@ -16,6 +16,8 @@ import (
"github.com/stretchr/testify/assert"
)
var MacintoshCyrillicCharset = []byte{0x8F, 0xF0, 0xE8, 0xE2, 0xE5, 0xF2, 0x20, 0xEC, 0xE8, 0xF0}
func TestSetDocProps(t *testing.T) {
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) {
......@@ -40,6 +42,11 @@ func TestSetDocProps(t *testing.T) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetDocProps.xlsx")))
f.XLSX["docProps/core.xml"] = nil
assert.NoError(t, f.SetDocProps(&DocProperties{}))
// Test unsupport charset
f = NewFile()
f.XLSX["docProps/core.xml"] = MacintoshCyrillicCharset
assert.EqualError(t, f.SetDocProps(&DocProperties{}), "xml decode error: XML syntax error on line 1: invalid UTF-8")
}
func TestGetDocProps(t *testing.T) {
......@@ -53,4 +60,10 @@ func TestGetDocProps(t *testing.T) {
f.XLSX["docProps/core.xml"] = nil
_, err = f.GetDocProps()
assert.NoError(t, err)
// Test unsupport charset
f = NewFile()
f.XLSX["docProps/core.xml"] = MacintoshCyrillicCharset
_, err = f.GetDocProps()
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
}
......@@ -2,6 +2,8 @@ package excelize
import (
"bytes"
"compress/gzip"
"encoding/xml"
"fmt"
"image/color"
_ "image/gif"
......@@ -184,6 +186,11 @@ func TestSaveAsWrongPath(t *testing.T) {
}
}
func TestCharsetTranscoder(t *testing.T) {
f := NewFile()
f.CharsetTranscoder(*new(charsetTranscoderFn))
}
func TestOpenReader(t *testing.T) {
_, err := OpenReader(strings.NewReader(""))
assert.EqualError(t, err, "zip: not a valid zip file")
......@@ -195,6 +202,18 @@ func TestOpenReader(t *testing.T) {
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
}))
assert.EqualError(t, err, "not support encrypted file currently")
// Test unexpected EOF.
var b bytes.Buffer
w := gzip.NewWriter(&b)
defer w.Close()
w.Flush()
r, _ := gzip.NewReader(&b)
defer r.Close()
_, err = OpenReader(r)
assert.EqualError(t, err, "unexpected EOF")
}
func TestBrokenFile(t *testing.T) {
......@@ -924,24 +943,6 @@ func TestAddShape(t *testing.T) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape2.xlsx")))
}
func TestAddComments(t *testing.T) {
f, err := prepareTestBook1()
if !assert.NoError(t, err) {
t.FailNow()
}
s := strings.Repeat("c", 32768)
assert.NoError(t, f.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`))
assert.NoError(t, f.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`))
// Test add comment on not exists worksheet.
assert.EqualError(t, f.AddComment("SheetN", "B7", `{"author":"Excelize: ","text":"This is a comment."}`), "sheet SheetN is not exist")
if assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
assert.Len(t, f.GetComments(), 2)
}
}
func TestGetSheetComments(t *testing.T) {
f := NewFile()
assert.Equal(t, "", f.getSheetComments(0))
......@@ -1005,18 +1006,37 @@ func TestAutoFilterError(t *testing.T) {
}
}
func TestSetPane(t *testing.T) {
func TestSetActiveSheet(t *testing.T) {
f := NewFile()
f.WorkBook.BookViews = nil
f.SetActiveSheet(1)
f.WorkBook.BookViews = &xlsxBookViews{WorkBookView: []xlsxWorkBookView{}}
f.Sheet["xl/worksheets/sheet1.xml"].SheetViews = &xlsxSheetViews{SheetView: []xlsxSheetView{}}
f.SetActiveSheet(1)
}
func TestSetSheetVisible(t *testing.T) {
f := NewFile()
f.WorkBook.Sheets.Sheet[0].Name = "SheetN"
assert.EqualError(t, f.SetSheetVisible("Sheet1", false), "sheet SheetN is not exist")
}
func TestGetActiveSheetIndex(t *testing.T) {
f := NewFile()
f.WorkBook.BookViews = nil
assert.Equal(t, 1, f.GetActiveSheetIndex())
}
func TestRelsWriter(t *testing.T) {
f := NewFile()
f.Relationships["xl/worksheets/sheet/rels/sheet1.xml.rel"] = &xlsxRelationships{}
f.relsWriter()
}
func TestGetSheetView(t *testing.T) {
f := NewFile()
f.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
f.NewSheet("Panes 2")
f.SetPanes("Panes 2", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`)
f.NewSheet("Panes 3")
f.SetPanes("Panes 3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`)
f.NewSheet("Panes 4")
f.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"}]}`)
f.SetPanes("Panes 4", "")
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
_, err := f.getSheetView("SheetN", 0)
assert.EqualError(t, err, "sheet SheetN is not exist")
}
func TestConditionalFormat(t *testing.T) {
......@@ -1207,6 +1227,61 @@ func TestAddVBAProject(t *testing.T) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddVBAProject.xlsm")))
}
func TestContentTypesReader(t *testing.T) {
// Test unsupport charset.
f := NewFile()
f.ContentTypes = nil
f.XLSX["[Content_Types].xml"] = MacintoshCyrillicCharset
f.contentTypesReader()
}
func TestWorkbookReader(t *testing.T) {
// Test unsupport charset.
f := NewFile()
f.WorkBook = nil
f.XLSX["xl/workbook.xml"] = MacintoshCyrillicCharset
f.workbookReader()
}
func TestWorkSheetReader(t *testing.T) {
// Test unsupport charset.
f := NewFile()
delete(f.Sheet, "xl/worksheets/sheet1.xml")
f.XLSX["xl/worksheets/sheet1.xml"] = MacintoshCyrillicCharset
_, err := f.workSheetReader("Sheet1")
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
// Test on no checked worksheet.
f = NewFile()
delete(f.Sheet, "xl/worksheets/sheet1.xml")
f.XLSX["xl/worksheets/sheet1.xml"] = []byte(`<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData/></worksheet>`)
f.checked = nil
_, err = f.workSheetReader("Sheet1")
assert.NoError(t, err)
}
func TestRelsReader(t *testing.T) {
// Test unsupport charset.
f := NewFile()
rels := "xl/_rels/workbook.xml.rels"
f.Relationships[rels] = nil
f.XLSX[rels] = MacintoshCyrillicCharset
f.relsReader(rels)
}
func TestDeleteSheetFromWorkbookRels(t *testing.T) {
f := NewFile()
rels := "xl/_rels/workbook.xml.rels"
f.Relationships[rels] = nil
assert.Equal(t, f.deleteSheetFromWorkbookRels("rID"), "")
}
func TestAttrValToInt(t *testing.T) {
_, err := attrValToInt("r", []xml.Attr{
{Name: xml.Name{Local: "r"}, Value: "s"}})
assert.EqualError(t, err, `strconv.Atoi: parsing "s": invalid syntax`)
}
func prepareTestBook1() (*File, error) {
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if err != nil {
......
......@@ -477,24 +477,14 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
var (
wsDr *xlsxWsDr
ok bool
anchor *xdrCellAnchor
deWsDr *decodeWsDr
drawRel *xlsxRelationship
deTwoCellAnchor *decodeTwoCellAnchor
)
wsDr, _ = f.drawingParser(drawingXML)
for _, anchor = range wsDr.TwoCellAnchor {
if anchor.From != nil && anchor.Pic != nil {
if anchor.From.Col == col && anchor.From.Row == row {
drawRel = f.getDrawingRelationships(drawingRelationships,
anchor.Pic.BlipFill.Blip.Embed)
if _, ok = supportImageTypes[filepath.Ext(drawRel.Target)]; ok {
ret, buf = filepath.Base(drawRel.Target), []byte(f.XLSX[strings.Replace(drawRel.Target, "..", "xl", -1)])
return
}
}
}
if ret, buf = f.getPictureFromWsDr(row, col, drawingRelationships, wsDr); len(buf) > 0 {
return
}
deWsDr = new(decodeWsDr)
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(drawingXML)))).
......@@ -514,13 +504,36 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
if deTwoCellAnchor.From.Col == col && deTwoCellAnchor.From.Row == row {
drawRel = f.getDrawingRelationships(drawingRelationships, deTwoCellAnchor.Pic.BlipFill.Blip.Embed)
if _, ok = supportImageTypes[filepath.Ext(drawRel.Target)]; ok {
ret, buf = filepath.Base(drawRel.Target), []byte(f.XLSX[strings.Replace(drawRel.Target, "..", "xl", -1)])
ret, buf = filepath.Base(drawRel.Target), f.XLSX[strings.Replace(drawRel.Target, "..", "xl", -1)]
return
}
}
}
}
return
}
// getPictureFromWsDr provides a function to get picture base name and raw
// content in worksheet drawing by given coordinates and drawing
// relationships.
func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsDr *xlsxWsDr) (ret string, buf []byte) {
var (
ok bool
anchor *xdrCellAnchor
drawRel *xlsxRelationship
)
for _, anchor = range wsDr.TwoCellAnchor {
if anchor.From != nil && anchor.Pic != nil {
if anchor.From.Col == col && anchor.From.Row == row {
drawRel = f.getDrawingRelationships(drawingRelationships,
anchor.Pic.BlipFill.Blip.Embed)
if _, ok = supportImageTypes[filepath.Ext(drawRel.Target)]; ok {
ret, buf = filepath.Base(drawRel.Target), f.XLSX[strings.Replace(drawRel.Target, "..", "xl", -1)]
return
}
}
}
}
return
}
......
......@@ -92,12 +92,12 @@ func TestAddPictureErrors(t *testing.T) {
}
func TestGetPicture(t *testing.T) {
xlsx, err := prepareTestBook1()
f, err := prepareTestBook1()
if !assert.NoError(t, err) {
t.FailNow()
}
file, raw, err := xlsx.GetPicture("Sheet1", "F21")
file, raw, err := f.GetPicture("Sheet1", "F21")
assert.NoError(t, err)
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
!assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0644)) {
......@@ -106,37 +106,37 @@ func TestGetPicture(t *testing.T) {
}
// Try to get picture from a worksheet with illegal cell coordinates.
_, _, err = xlsx.GetPicture("Sheet1", "A")
_, _, err = f.GetPicture("Sheet1", "A")
assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
// Try to get picture from a worksheet that doesn't contain any images.
file, raw, err = xlsx.GetPicture("Sheet3", "I9")
file, raw, err = f.GetPicture("Sheet3", "I9")
assert.EqualError(t, err, "sheet Sheet3 is not exist")
assert.Empty(t, file)
assert.Empty(t, raw)
// Try to get picture from a cell that doesn't contain an image.
file, raw, err = xlsx.GetPicture("Sheet2", "A2")
file, raw, err = f.GetPicture("Sheet2", "A2")
assert.NoError(t, err)
assert.Empty(t, file)
assert.Empty(t, raw)
xlsx.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
xlsx.getDrawingRelationships("", "")
xlsx.getSheetRelationshipsTargetByID("", "")
xlsx.deleteSheetRelationships("", "")
f.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
f.getDrawingRelationships("", "")
f.getSheetRelationshipsTargetByID("", "")
f.deleteSheetRelationships("", "")
// Try to get picture from a local storage file.
if !assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestGetPicture.xlsx"))) {
if !assert.NoError(t, f.SaveAs(filepath.Join("test", "TestGetPicture.xlsx"))) {
t.FailNow()
}
xlsx, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
f, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
if !assert.NoError(t, err) {
t.FailNow()
}
file, raw, err = xlsx.GetPicture("Sheet1", "F21")
file, raw, err = f.GetPicture("Sheet1", "F21")
assert.NoError(t, err)
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
!assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0644)) {
......@@ -145,7 +145,14 @@ func TestGetPicture(t *testing.T) {
}
// Try to get picture from a local storage file that doesn't contain an image.
file, raw, err = xlsx.GetPicture("Sheet1", "F22")
file, raw, err = f.GetPicture("Sheet1", "F22")
assert.NoError(t, err)
assert.Empty(t, file)
assert.Empty(t, raw)
// Test get picture from none drawing worksheet.
f = NewFile()
file, raw, err = f.GetPicture("Sheet1", "F22")
assert.NoError(t, err)
assert.Empty(t, file)
assert.Empty(t, raw)
......@@ -160,11 +167,9 @@ func TestAddDrawingPicture(t *testing.T) {
func TestAddPictureFromBytes(t *testing.T) {
f := NewFile()
imgFile, err := ioutil.ReadFile("logo.png")
if err != nil {
t.Error("Unable to load logo for test")
}
f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "", "logo", ".png", imgFile)
f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile)
assert.NoError(t, err, "Unable to load logo for test")
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "", "logo", ".png", imgFile))
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile))
imageCount := 0
for fileName := range f.XLSX {
if strings.Contains(fileName, "media/image") {
......@@ -172,4 +177,5 @@ func TestAddPictureFromBytes(t *testing.T) {
}
}
assert.Equal(t, 1, imageCount, "Duplicate image should only be stored once.")
assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), "", "logo", ".png", imgFile), "sheet SheetN is not exist")
}
package excelize
import (
"bytes"
"fmt"
"path/filepath"
"testing"
......@@ -12,12 +13,12 @@ import (
func TestRows(t *testing.T) {
const sheet2 = "Sheet2"
xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) {
t.FailNow()
}
rows, err := xlsx.Rows(sheet2)
rows, err := f.Rows(sheet2)
if !assert.NoError(t, err) {
t.FailNow()
}
......@@ -32,7 +33,7 @@ func TestRows(t *testing.T) {
t.FailNow()
}
returnedRows, err := xlsx.GetRows(sheet2)
returnedRows, err := f.GetRows(sheet2)
assert.NoError(t, err)
for i := range returnedRows {
returnedRows[i] = trimSliceSpace(returnedRows[i])
......@@ -40,6 +41,11 @@ func TestRows(t *testing.T) {
if !assert.Equal(t, collectedRows, returnedRows) {
t.FailNow()
}
f = NewFile()
f.XLSX["xl/worksheets/sheet1.xml"] = []byte(`<worksheet><sheetData><row r="1"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)
_, err = f.Rows("Sheet1")
assert.EqualError(t, err, `strconv.Atoi: parsing "A": invalid syntax`)
}
func TestRowsIterator(t *testing.T) {
......@@ -126,6 +132,35 @@ func TestRowHeight(t *testing.T) {
convertColWidthToPixels(0)
}
func TestColumns(t *testing.T) {
f := NewFile()
rows, err := f.Rows("Sheet1")
assert.NoError(t, err)
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="A"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)))
_, err = rows.Columns()
assert.EqualError(t, err, `strconv.Atoi: parsing "A": invalid syntax`)
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="1"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)))
_, err = rows.Columns()
assert.NoError(t, err)
rows.curRow = 3
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="1"><c r="A" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
_, err = rows.Columns()
assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
// Test token is nil
rows.decoder = f.xmlNewDecoder(bytes.NewReader(nil))
_, err = rows.Columns()
assert.NoError(t, err)
}
func TestSharedStringsReader(t *testing.T) {
f := NewFile()
f.XLSX["xl/sharedStrings.xml"] = MacintoshCyrillicCharset
f.sharedStringsReader()
}
func TestRowVisibility(t *testing.T) {
f, err := prepareTestBook1()
if !assert.NoError(t, err) {
......@@ -149,61 +184,64 @@ func TestRowVisibility(t *testing.T) {
}
func TestRemoveRow(t *testing.T) {
xlsx := NewFile()
sheet1 := xlsx.GetSheetName(1)
r, err := xlsx.workSheetReader(sheet1)
f := NewFile()
sheet1 := f.GetSheetName(1)
r, err := f.workSheetReader(sheet1)
assert.NoError(t, err)
const (
colCount = 10
rowCount = 10
)
fillCells(xlsx, sheet1, colCount, rowCount)
fillCells(f, sheet1, colCount, rowCount)
xlsx.SetCellHyperLink(sheet1, "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
f.SetCellHyperLink(sheet1, "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
assert.EqualError(t, xlsx.RemoveRow(sheet1, -1), "invalid row number -1")
assert.EqualError(t, f.RemoveRow(sheet1, -1), "invalid row number -1")
assert.EqualError(t, xlsx.RemoveRow(sheet1, 0), "invalid row number 0")
assert.EqualError(t, f.RemoveRow(sheet1, 0), "invalid row number 0")
assert.NoError(t, xlsx.RemoveRow(sheet1, 4))
assert.NoError(t, f.RemoveRow(sheet1, 4))
if !assert.Len(t, r.SheetData.Row, rowCount-1) {
t.FailNow()
}
xlsx.MergeCell(sheet1, "B3", "B5")
f.MergeCell(sheet1, "B3", "B5")
assert.NoError(t, xlsx.RemoveRow(sheet1, 2))
assert.NoError(t, f.RemoveRow(sheet1, 2))
if !assert.Len(t, r.SheetData.Row, rowCount-2) {
t.FailNow()
}
assert.NoError(t, xlsx.RemoveRow(sheet1, 4))
assert.NoError(t, f.RemoveRow(sheet1, 4))
if !assert.Len(t, r.SheetData.Row, rowCount-3) {
t.FailNow()
}
err = xlsx.AutoFilter(sheet1, "A2", "A2", `{"column":"A","expression":"x != blanks"}`)
err = f.AutoFilter(sheet1, "A2", "A2", `{"column":"A","expression":"x != blanks"}`)
if !assert.NoError(t, err) {
t.FailNow()
}
assert.NoError(t, xlsx.RemoveRow(sheet1, 1))
assert.NoError(t, f.RemoveRow(sheet1, 1))
if !assert.Len(t, r.SheetData.Row, rowCount-4) {
t.FailNow()
}
assert.NoError(t, xlsx.RemoveRow(sheet1, 2))
assert.NoError(t, f.RemoveRow(sheet1, 2))
if !assert.Len(t, r.SheetData.Row, rowCount-5) {
t.FailNow()
}
assert.NoError(t, xlsx.RemoveRow(sheet1, 1))
assert.NoError(t, f.RemoveRow(sheet1, 1))
if !assert.Len(t, r.SheetData.Row, rowCount-6) {
t.FailNow()
}
assert.NoError(t, xlsx.RemoveRow(sheet1, 10))
assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestRemoveRow.xlsx")))
assert.NoError(t, f.RemoveRow(sheet1, 10))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestRemoveRow.xlsx")))
// Test remove row on not exist worksheet
assert.EqualError(t, f.RemoveRow("SheetN", 1), `sheet SheetN is not exist`)
}
func TestInsertRow(t *testing.T) {
......
......@@ -505,7 +505,7 @@ func (f *File) copySheet(from, to int) error {
// SetSheetVisible provides a function to set worksheet visible by given worksheet
// name. A workbook must contain at least one visible worksheet. If the given
// worksheet has been activated, this setting will be invalidated. Sheet state
// values as defined by http://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.sheetstatevalues.aspx
// values as defined by https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.sheetstatevalues
//
// visible
// hidden
......@@ -738,7 +738,8 @@ func (f *File) searchSheet(name, value string, regSearch bool) (result []string,
d = f.sharedStringsReader()
decoder := f.xmlNewDecoder(bytes.NewReader(f.readXML(name)))
for {
token, err := decoder.Token()
var token xml.Token
token, err = decoder.Token()
if err != nil || token == nil {
if err == io.EOF {
err = nil
......@@ -749,13 +750,9 @@ func (f *File) searchSheet(name, value string, regSearch bool) (result []string,
case xml.StartElement:
inElement = startElement.Name.Local
if inElement == "row" {
for _, attr := range startElement.Attr {
if attr.Name.Local == "r" {
row, err = strconv.Atoi(attr.Value)
if err != nil {
return result, err
}
}
row, err = attrValToInt("r", startElement.Attr)
if err != nil {
return
}
}
if inElement == "c" {
......@@ -785,7 +782,20 @@ func (f *File) searchSheet(name, value string, regSearch bool) (result []string,
default:
}
}
return
}
// attrValToInt provides a function to convert the local names to an integer
// by given XML attributes and specified names.
func attrValToInt(name string, attrs []xml.Attr) (val int, err error) {
for _, attr := range attrs {
if attr.Name.Local == name {
val, err = strconv.Atoi(attr.Value)
if err != nil {
return
}
}
}
return
}
......
......@@ -75,6 +75,20 @@ func TestNewSheet(t *testing.T) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestNewSheet.xlsx")))
}
func TestSetPane(t *testing.T) {
f := excelize.NewFile()
assert.NoError(t, f.SetPanes("Sheet1", `{"freeze":false,"split":false}`))
f.NewSheet("Panes 2")
assert.NoError(t, f.SetPanes("Panes 2", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`))
f.NewSheet("Panes 3")
assert.NoError(t, f.SetPanes("Panes 3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`))
f.NewSheet("Panes 4")
assert.NoError(t, f.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"}]}`))
assert.NoError(t, f.SetPanes("Panes 4", ""))
assert.EqualError(t, f.SetPanes("SheetN", ""), "sheet SheetN is not exist")
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
}
func TestPageLayoutOption(t *testing.T) {
const sheet = "Sheet1"
......@@ -156,6 +170,12 @@ func TestSearchSheet(t *testing.T) {
result, err = f.SearchSheet("Sheet1", "[0-9]", true)
assert.NoError(t, err)
assert.EqualValues(t, expected, result)
// Test search worksheet data after set cell value
f = excelize.NewFile()
assert.NoError(t, f.SetCellValue("Sheet1", "A1", true))
_, err = f.SearchSheet("Sheet1", "")
assert.NoError(t, err)
}
func TestSetPageLayout(t *testing.T) {
......
......@@ -390,21 +390,14 @@ func (f *File) addSparklineGroupByStyle(ID int) *xlsxX14SparklineGroup {
//
func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
var (
ws *xlsxWorksheet
sparkType string
sparkTypes map[string]string
specifiedSparkTypes string
ok bool
group *xlsxX14SparklineGroup
groups *xlsxX14SparklineGroups
decodeExtLst *decodeWorksheetExt
idx int
ext *xlsxWorksheetExt
decodeSparklineGroups *decodeX14SparklineGroups
sparklineGroupBytes []byte
sparklineGroupsBytes []byte
extLst string
extLstBytes, extBytes []byte
ws *xlsxWorksheet
sparkType string
sparkTypes map[string]string
specifiedSparkTypes string
ok bool
group *xlsxX14SparklineGroup
groups *xlsxX14SparklineGroups
sparklineGroupsBytes, extBytes []byte
)
// parameter validation
......@@ -442,38 +435,9 @@ func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
}
f.addSparkline(opt, group)
if ws.ExtLst.Ext != "" { // append mode ext
decodeExtLst = new(decodeWorksheetExt)
if err = f.xmlNewDecoder(bytes.NewReader([]byte("<extLst>" + ws.ExtLst.Ext + "</extLst>"))).
Decode(decodeExtLst); err != nil && err != io.EOF {
if err = f.appendSparkline(ws, group, groups); err != nil {
return
}
for idx, ext = range decodeExtLst.Ext {
if ext.URI == ExtURISparklineGroups {
decodeSparklineGroups = new(decodeX14SparklineGroups)
if err = f.xmlNewDecoder(bytes.NewReader([]byte(ext.Content))).
Decode(decodeSparklineGroups); err != nil && err != io.EOF {
return
}
if sparklineGroupBytes, err = xml.Marshal(group); err != nil {
return
}
groups = &xlsxX14SparklineGroups{
XMLNSXM: NameSpaceSpreadSheetExcel2006Main,
Content: decodeSparklineGroups.Content + string(sparklineGroupBytes),
}
if sparklineGroupsBytes, err = xml.Marshal(groups); err != nil {
return
}
decodeExtLst.Ext[idx].Content = string(sparklineGroupsBytes)
}
}
if extLstBytes, err = xml.Marshal(decodeExtLst); err != nil {
return
}
extLst = string(extLstBytes)
ws.ExtLst = &xlsxExtLst{
Ext: strings.TrimSuffix(strings.TrimPrefix(extLst, "<extLst>"), "</extLst>"),
}
} else {
groups = &xlsxX14SparklineGroups{
XMLNSXM: NameSpaceSpreadSheetExcel2006Main,
......@@ -482,11 +446,10 @@ func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
if sparklineGroupsBytes, err = xml.Marshal(groups); err != nil {
return
}
ext = &xlsxWorksheetExt{
if extBytes, err = xml.Marshal(&xlsxWorksheetExt{
URI: ExtURISparklineGroups,
Content: string(sparklineGroupsBytes),
}
if extBytes, err = xml.Marshal(ext); err != nil {
}); err != nil {
return
}
ws.ExtLst.Ext = string(extBytes)
......@@ -534,3 +497,47 @@ func (f *File) addSparkline(opt *SparklineOption, group *xlsxX14SparklineGroup)
})
}
}
// appendSparkline provides a function to append sparkline to sparkline
// groups.
func (f *File) appendSparkline(ws *xlsxWorksheet, group *xlsxX14SparklineGroup, groups *xlsxX14SparklineGroups) (err error) {
var (
idx int
decodeExtLst *decodeWorksheetExt
decodeSparklineGroups *decodeX14SparklineGroups
ext *xlsxWorksheetExt
sparklineGroupsBytes, sparklineGroupBytes, extLstBytes []byte
)
decodeExtLst = new(decodeWorksheetExt)
if err = f.xmlNewDecoder(bytes.NewReader([]byte("<extLst>" + ws.ExtLst.Ext + "</extLst>"))).
Decode(decodeExtLst); err != nil && err != io.EOF {
return
}
for idx, ext = range decodeExtLst.Ext {
if ext.URI == ExtURISparklineGroups {
decodeSparklineGroups = new(decodeX14SparklineGroups)
if err = f.xmlNewDecoder(bytes.NewReader([]byte(ext.Content))).
Decode(decodeSparklineGroups); err != nil && err != io.EOF {
return
}
if sparklineGroupBytes, err = xml.Marshal(group); err != nil {
return
}
groups = &xlsxX14SparklineGroups{
XMLNSXM: NameSpaceSpreadSheetExcel2006Main,
Content: decodeSparklineGroups.Content + string(sparklineGroupBytes),
}
if sparklineGroupsBytes, err = xml.Marshal(groups); err != nil {
return
}
decodeExtLst.Ext[idx].Content = string(sparklineGroupsBytes)
}
}
if extLstBytes, err = xml.Marshal(decodeExtLst); err != nil {
return
}
ws.ExtLst = &xlsxExtLst{
Ext: strings.TrimSuffix(strings.TrimPrefix(string(extLstBytes), "<extLst>"), "</extLst>"),
}
return
}
......@@ -269,6 +269,15 @@ func TestAddSparkline(t *testing.T) {
}), "XML syntax error on line 6: element <sparklineGroup> closed by </sparklines>")
}
func TestAppendSparkline(t *testing.T) {
// Test unsupport charset.
f := NewFile()
ws, err := f.workSheetReader("Sheet1")
assert.NoError(t, err)
ws.ExtLst = &xlsxExtLst{Ext: string(MacintoshCyrillicCharset)}
assert.EqualError(t, f.appendSparkline(ws, &xlsxX14SparklineGroup{}, &xlsxX14SparklineGroups{}), "XML syntax error on line 1: invalid UTF-8")
}
func prepareSparklineDataset() *File {
f := NewFile()
sheet2 := [][]int{
......
......@@ -37,8 +37,7 @@ func TestStreamWriter(t *testing.T) {
assert.NoError(t, streamWriter.SetRow(cell, &row))
}
err = streamWriter.Flush()
assert.NoError(t, err)
assert.NoError(t, streamWriter.Flush())
// Save xlsx file by the given path.
assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamWriter.xlsx")))
......@@ -54,6 +53,21 @@ func TestFlush(t *testing.T) {
assert.NoError(t, err)
streamWriter.Sheet = "SheetN"
assert.EqualError(t, streamWriter.Flush(), "sheet SheetN is not exist")
// Test close temporary file error
file = NewFile()
streamWriter, err = file.NewStreamWriter("Sheet1")
assert.NoError(t, err)
for rowID := 10; rowID <= 51200; rowID++ {
row := make([]interface{}, 50)
for colID := 0; colID < 50; colID++ {
row[colID] = rand.Intn(640000)
}
cell, _ := CoordinatesToCellName(1, rowID)
assert.NoError(t, streamWriter.SetRow(cell, &row))
}
assert.NoError(t, streamWriter.tmpFile.Close())
assert.Error(t, streamWriter.Flush())
}
func TestSetRow(t *testing.T) {
......
......@@ -203,7 +203,7 @@ type xlsxDefinedNames struct {
// http://schemas.openxmlformats.org/spreadsheetml/2006/main This element
// defines a defined name within this workbook. A defined name is descriptive
// text that is used to represents a cell, range of cells, formula, or constant
// value. For a descriptions of the attributes see https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.definedname.aspx
// value. For a descriptions of the attributes see https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.definedname
type xlsxDefinedName struct {
Comment string `xml:"comment,attr,omitempty"`
CustomMenu string `xml:"customMenu,attr,omitempty"`
......
......@@ -182,7 +182,7 @@ type xlsxSheetViews struct {
// last sheetView definition is loaded, and the others are discarded. When
// multiple windows are viewing the same sheet, multiple sheetView elements
// (with corresponding workbookView entries) are saved.
// See https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.sheetview.aspx
// See https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.sheetview
type xlsxSheetView struct {
WindowProtection bool `xml:"windowProtection,attr,omitempty"`
ShowFormulas bool `xml:"showFormulas,attr,omitempty"`
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册