Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
ffad7aec
excelize
项目概览
xuri
/
excelize
通知
13
Star
2
Fork
4
代码
文件
提交
分支
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
ffad7aec
编写于
3月 28, 2024
作者:
Y
yunkeweb
提交者:
GitHub
3月 28, 2024
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support get rich data value rels index from rich value part (#1866)
上级
5e500f5e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
110 addition
and
25 deletion
+110
-25
excelize.go
excelize.go
+11
-0
picture.go
picture.go
+35
-7
picture_test.go
picture_test.go
+46
-18
templates.go
templates.go
+1
-0
xmlMetaData.go
xmlMetaData.go
+17
-0
未找到文件。
excelize.go
浏览文件 @
ffad7aec
...
...
@@ -601,6 +601,17 @@ func (f *File) metadataReader() (*xlsxMetadata, error) {
return
&
mataData
,
nil
}
// richValueReader provides a function to get the pointer to the structure after
// deserialization of xl/richData/richvalue.xml.
func
(
f
*
File
)
richValueReader
()
(
*
xlsxRichValueData
,
error
)
{
var
richValue
xlsxRichValueData
if
err
:=
f
.
xmlNewDecoder
(
bytes
.
NewReader
(
namespaceStrictToTransitional
(
f
.
readXML
(
defaultXMLRichDataRichValue
))))
.
Decode
(
&
richValue
);
err
!=
nil
&&
err
!=
io
.
EOF
{
return
&
richValue
,
err
}
return
&
richValue
,
nil
}
// richValueRelReader provides a function to get the pointer to the structure
// after deserialization of xl/richData/richValueRel.xml.
func
(
f
*
File
)
richValueRelReader
()
(
*
xlsxRichValueRels
,
error
)
{
...
...
picture.go
浏览文件 @
ffad7aec
...
...
@@ -450,7 +450,8 @@ func (f *File) addMedia(file []byte, ext string) string {
// GetPictures provides a function to get picture meta info and raw content
// embed in spreadsheet by given worksheet and cell name. This function
// returns the image contents as []byte data types. This function is
// concurrency safe. For example:
// concurrency safe. Note that, this function doesn't support getting cell image
// inserted by IMAGE formula function currently. For example:
//
// f, err := excelize.OpenFile("Book1.xlsx")
// if err != nil {
...
...
@@ -506,7 +507,8 @@ func (f *File) GetPictures(sheet, cell string) ([]Picture, error) {
}
// GetPictureCells returns all picture cell references in a worksheet by a
// specific worksheet name.
// specific worksheet name. Note that, this function doesn't support getting
// cell image inserted by IMAGE formula function currently.
func
(
f
*
File
)
GetPictureCells
(
sheet
string
)
([]
string
,
error
)
{
f
.
mu
.
Lock
()
ws
,
err
:=
f
.
workSheetReader
(
sheet
)
...
...
@@ -790,7 +792,7 @@ func (f *File) cellImagesReader() (*decodeCellImages, error) {
return
f
.
DecodeCellImages
,
nil
}
// getImageCells returns all the
Microsoft 365
cell images and the Kingsoft WPS
// getImageCells returns all the cell images and the Kingsoft WPS
// Office embedded image cells reference by given worksheet name.
func
(
f
*
File
)
getImageCells
(
sheet
string
)
([]
string
,
error
)
{
var
(
...
...
@@ -823,7 +825,29 @@ func (f *File) getImageCells(sheet string) ([]string, error) {
return
cells
,
err
}
// getImageCellRel returns the Microsoft 365 cell image relationship.
// getImageCellRichValueIdx returns index of the cell image rich value by given
// cell value meta index and meta blocks.
func
(
f
*
File
)
getImageCellRichValueIdx
(
vm
uint
,
blocks
*
xlsxMetadataBlocks
)
(
int
,
error
)
{
richValueIdx
:=
blocks
.
Bk
[
vm
-
1
]
.
Rc
[
0
]
.
V
richValue
,
err
:=
f
.
richValueReader
()
if
err
!=
nil
{
return
-
1
,
err
}
if
richValueIdx
>=
len
(
richValue
.
Rv
)
{
return
-
1
,
err
}
rv
:=
richValue
.
Rv
[
richValueIdx
]
.
V
if
len
(
rv
)
!=
2
||
rv
[
1
]
!=
"5"
{
return
-
1
,
err
}
richValueRelIdx
,
err
:=
strconv
.
Atoi
(
rv
[
0
])
if
err
!=
nil
{
return
-
1
,
err
}
return
richValueRelIdx
,
err
}
// getImageCellRel returns the cell image relationship.
func
(
f
*
File
)
getImageCellRel
(
c
*
xlsxC
)
(
*
xlsxRelationship
,
error
)
{
var
r
*
xlsxRelationship
if
c
.
Vm
==
nil
||
c
.
V
!=
formulaErrorVALUE
{
...
...
@@ -837,21 +861,25 @@ func (f *File) getImageCellRel(c *xlsxC) (*xlsxRelationship, error) {
if
vmd
==
nil
||
int
(
*
c
.
Vm
)
>
len
(
vmd
.
Bk
)
||
len
(
vmd
.
Bk
[
*
c
.
Vm
-
1
]
.
Rc
)
==
0
{
return
r
,
err
}
richValueRelIdx
,
err
:=
f
.
getImageCellRichValueIdx
(
*
c
.
Vm
,
vmd
)
if
err
!=
nil
||
richValueRelIdx
==
-
1
{
return
r
,
err
}
richValueRel
,
err
:=
f
.
richValueRelReader
()
if
err
!=
nil
{
return
r
,
err
}
if
vmd
.
Bk
[
*
c
.
Vm
-
1
]
.
Rc
[
0
]
.
V
>=
len
(
richValueRel
.
Rels
)
{
if
richValueRelIdx
>=
len
(
richValueRel
.
Rels
)
{
return
r
,
err
}
rID
:=
richValueRel
.
Rels
[
vmd
.
Bk
[
*
c
.
Vm
-
1
]
.
Rc
[
0
]
.
V
]
.
ID
rID
:=
richValueRel
.
Rels
[
richValueRelIdx
]
.
ID
if
r
=
f
.
getRichDataRichValueRelRelationships
(
rID
);
r
!=
nil
&&
r
.
Type
!=
SourceRelationshipImage
{
return
nil
,
err
}
return
r
,
err
}
// getCellImages provides a function to get the
Microsoft 365
cell images and
// getCellImages provides a function to get the cell images and
// the Kingsoft WPS Office embedded cell images by given worksheet name and cell
// reference.
func
(
f
*
File
)
getCellImages
(
sheet
,
cell
string
)
([]
Picture
,
error
)
{
...
...
picture_test.go
浏览文件 @
ffad7aec
...
...
@@ -452,17 +452,22 @@ func TestGetCellImages(t *testing.T) {
assert
.
EqualError
(
t
,
err
,
"XML syntax error on line 1: invalid UTF-8"
)
assert
.
NoError
(
t
,
f
.
Close
())
// Test get the Microsoft 365 cell images
f
=
NewFile
()
assert
.
NoError
(
t
,
f
.
AddPicture
(
"Sheet1"
,
"A1"
,
filepath
.
Join
(
"test"
,
"images"
,
"excel.png"
),
nil
))
f
.
Pkg
.
Store
(
defaultXMLMetadata
,
[]
byte
(
`<metadata><valueMetadata count="1"><bk><rc t="1" v="0"/></bk></valueMetadata></metadata>`
))
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRel
,
[]
byte
(
`<richValueRels><rel r:id="rId1"/></richValueRels>`
))
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRelRels
,
[]
byte
(
fmt
.
Sprintf
(
`<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="%s" Target="../media/image1.png"/></Relationships>`
,
SourceRelationshipImage
)))
f
.
Sheet
.
Store
(
"xl/worksheets/sheet1.xml"
,
&
xlsxWorksheet
{
SheetData
:
xlsxSheetData
{
Row
:
[]
xlsxRow
{
{
R
:
1
,
C
:
[]
xlsxC
{{
R
:
"A1"
,
T
:
"e"
,
V
:
formulaErrorVALUE
,
Vm
:
uintPtr
(
1
)}}},
}},
})
// Test get the cell images
prepareWorkbook
:=
func
()
*
File
{
f
:=
NewFile
()
assert
.
NoError
(
t
,
f
.
AddPicture
(
"Sheet1"
,
"A1"
,
filepath
.
Join
(
"test"
,
"images"
,
"excel.png"
),
nil
))
f
.
Pkg
.
Store
(
defaultXMLMetadata
,
[]
byte
(
`<metadata><valueMetadata count="1"><bk><rc t="1" v="0"/></bk></valueMetadata></metadata>`
))
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValue
,
[]
byte
(
`<rvData count="1"><rv s="0"><v>0</v><v>5</v></rv></rvData>`
))
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRel
,
[]
byte
(
`<richValueRels><rel r:id="rId1"/></richValueRels>`
))
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRelRels
,
[]
byte
(
fmt
.
Sprintf
(
`<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="%s" Target="../media/image1.png"/></Relationships>`
,
SourceRelationshipImage
)))
f
.
Sheet
.
Store
(
"xl/worksheets/sheet1.xml"
,
&
xlsxWorksheet
{
SheetData
:
xlsxSheetData
{
Row
:
[]
xlsxRow
{
{
R
:
1
,
C
:
[]
xlsxC
{{
R
:
"A1"
,
T
:
"e"
,
V
:
formulaErrorVALUE
,
Vm
:
uintPtr
(
1
)}}},
}},
})
return
f
}
f
=
prepareWorkbook
()
pics
,
err
:=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
pics
))
...
...
@@ -471,41 +476,64 @@ func TestGetCellImages(t *testing.T) {
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
[]
string
{
"A1"
},
cells
)
// Test get the
Microsoft 365
cell images without image relationships parts
// Test get the cell images without image relationships parts
f
.
Relationships
.
Delete
(
defaultXMLRichDataRichValueRelRels
)
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRelRels
,
[]
byte
(
fmt
.
Sprintf
(
`<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="%s" Target="../media/image1.png"/></Relationships>`
,
SourceRelationshipHyperLink
)))
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Empty
(
t
,
pics
)
// Test get the
Microsoft 365
cell images with unsupported charset rich data rich value relationships
// Test get the cell images with unsupported charset rich data rich value relationships
f
.
Relationships
.
Delete
(
defaultXMLRichDataRichValueRelRels
)
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRelRels
,
MacintoshCyrillicCharset
)
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Empty
(
t
,
pics
)
// Test get the
Microsoft 365
cell images with unsupported charset rich data rich value
// Test get the cell images with unsupported charset rich data rich value
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRel
,
MacintoshCyrillicCharset
)
_
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
EqualError
(
t
,
err
,
"XML syntax error on line 1: invalid UTF-8"
)
// Test get the
Microsoft 365
image cells without block of metadata records
// Test get the image cells without block of metadata records
cells
,
err
=
f
.
GetPictureCells
(
"Sheet1"
)
assert
.
EqualError
(
t
,
err
,
"XML syntax error on line 1: invalid UTF-8"
)
assert
.
Empty
(
t
,
cells
)
// Test get the
Microsoft 365
cell images with rich data rich value relationships
// Test get the cell images with rich data rich value relationships
f
.
Pkg
.
Store
(
defaultXMLMetadata
,
[]
byte
(
`<metadata><valueMetadata count="1"><bk><rc t="1" v="0"/></bk></valueMetadata></metadata>`
))
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValueRel
,
[]
byte
(
`<richValueRels/>`
))
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Empty
(
t
,
pics
)
// Test get the
Microsoft 365
cell images with unsupported charset meta data
// Test get the cell images with unsupported charset meta data
f
.
Pkg
.
Store
(
defaultXMLMetadata
,
MacintoshCyrillicCharset
)
_
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
EqualError
(
t
,
err
,
"XML syntax error on line 1: invalid UTF-8"
)
// Test get the
Microsoft 365
cell images without block of metadata records
// Test get the cell images without block of metadata records
f
.
Pkg
.
Store
(
defaultXMLMetadata
,
[]
byte
(
`<metadata><valueMetadata/></metadata>`
))
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Empty
(
t
,
pics
)
f
=
prepareWorkbook
()
// Test get the cell images with empty image cell rich value
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValue
,
[]
byte
(
`<rvData count="1"><rv s="0"><v></v><v>5</v></rv></rvData>`
))
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
EqualError
(
t
,
err
,
"strconv.Atoi: parsing
\"\"
: invalid syntax"
)
assert
.
Empty
(
t
,
pics
)
// Test get the cell images without image cell rich value
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValue
,
[]
byte
(
`<rvData count="1"><rv s="0"><v>0</v><v>1</v></rv></rvData>`
))
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Empty
(
t
,
pics
)
// Test get the cell images with unsupported charset rich value
f
.
Pkg
.
Store
(
defaultXMLRichDataRichValue
,
MacintoshCyrillicCharset
)
_
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
EqualError
(
t
,
err
,
"XML syntax error on line 1: invalid UTF-8"
)
f
=
prepareWorkbook
()
// Test get the cell images with invalid rich value index
f
.
Pkg
.
Store
(
defaultXMLMetadata
,
[]
byte
(
`<metadata><valueMetadata count="1"><bk><rc t="1" v="1"/></bk></valueMetadata></metadata>`
))
pics
,
err
=
f
.
GetPictures
(
"Sheet1"
,
"A1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Empty
(
t
,
pics
)
}
func
TestGetImageCells
(
t
*
testing
.
T
)
{
...
...
templates.go
浏览文件 @
ffad7aec
...
...
@@ -280,6 +280,7 @@ const (
defaultXMLPathVolatileDeps
=
"xl/volatileDependencies.xml"
defaultXMLPathWorkbook
=
"xl/workbook.xml"
defaultXMLPathWorkbookRels
=
"xl/_rels/workbook.xml.rels"
defaultXMLRichDataRichValue
=
"xl/richData/rdrichvalue.xml"
defaultXMLRichDataRichValueRel
=
"xl/richData/richValueRel.xml"
defaultXMLRichDataRichValueRelRels
=
"xl/richData/_rels/richValueRel.xml.rels"
)
...
...
xmlMetaData.go
浏览文件 @
ffad7aec
...
...
@@ -68,6 +68,23 @@ type xlsxMetadataRecord struct {
V
int
`xml:"v,attr"`
}
// xlsxRichValueData directly maps the rvData element that specifies rich value
// data.
type
xlsxRichValueData
struct
{
XMLName
xml
.
Name
`xml:"rvData"`
Count
int
`xml:"count,attr,omitempty"`
Rv
[]
xlsxRichValue
`xml:"rv"`
ExtLst
*
xlsxInnerXML
`xml:"extLst"`
}
// xlsxRichValue directly maps the rv element that specifies rich value data
// information for a single rich value
type
xlsxRichValue
struct
{
S
int
`xml:"s,attr"`
V
[]
string
`xml:"v"`
Fb
*
xlsxInnerXML
`xml:"fb"`
}
// xlsxRichValueRels directly maps the richValueRels element. This element that
// specifies a list of rich value relationships.
type
xlsxRichValueRels
struct
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录