Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
此号慢热型
excelize
提交
ae2865d9
excelize
项目概览
此号慢热型
/
excelize
与 Fork 源项目一致
Fork自
xuri / excelize
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
excelize
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
已验证
提交
ae2865d9
编写于
12月 22, 2019
作者:
xurime
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve code coverage unit tests
上级
7358dca4
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
438 addition
and
142 deletion
+438
-142
calcchain_test.go
calcchain_test.go
+19
-0
cell_test.go
cell_test.go
+8
-1
comment_test.go
comment_test.go
+56
-0
datavalidation_test.go
datavalidation_test.go
+9
-0
docProps_test.go
docProps_test.go
+13
-0
excelize_test.go
excelize_test.go
+104
-29
picture.go
picture.go
+26
-13
picture_test.go
picture_test.go
+24
-18
rows_test.go
rows_test.go
+58
-20
sheet.go
sheet.go
+19
-9
sheet_test.go
sheet_test.go
+20
-0
sparkline.go
sparkline.go
+55
-48
sparkline_test.go
sparkline_test.go
+9
-0
stream_test.go
stream_test.go
+16
-2
xmlWorkbook.go
xmlWorkbook.go
+1
-1
xmlWorksheet.go
xmlWorksheet.go
+1
-1
未找到文件。
calcchain_test.go
0 → 100644
浏览文件 @
ae2865d9
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"
)
}
cell_test.go
浏览文件 @
ae2865d9
...
...
@@ -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
()
{
...
...
comment_test.go
0 → 100644
浏览文件 @
ae2865d9
// 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
)
}
datavalidation_test.go
浏览文件 @
ae2865d9
...
...
@@ -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"
)
}
docProps_test.go
浏览文件 @
ae2865d9
...
...
@@ -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"
)
}
excelize_test.go
浏览文件 @
ae2865d9
...
...
@@ -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
{
...
...
picture.go
浏览文件 @
ae2865d9
...
...
@@ -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
}
...
...
picture_test.go
浏览文件 @
ae2865d9
...
...
@@ -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"
)
}
rows_test.go
浏览文件 @
ae2865d9
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
)
{
...
...
sheet.go
浏览文件 @
ae2865d9
...
...
@@ -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 http
s://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
}
...
...
sheet_test.go
浏览文件 @
ae2865d9
...
...
@@ -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
)
{
...
...
sparkline.go
浏览文件 @
ae2865d9
...
...
@@ -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
}
sparkline_test.go
浏览文件 @
ae2865d9
...
...
@@ -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
{
...
...
stream_test.go
浏览文件 @
ae2865d9
...
...
@@ -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
)
{
...
...
xmlWorkbook.go
浏览文件 @
ae2865d9
...
...
@@ -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"`
...
...
xmlWorksheet.go
浏览文件 @
ae2865d9
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录