Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
f6f14f50
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 搜索 >>
未验证
提交
f6f14f50
编写于
8月 13, 2021
作者:
T
three
提交者:
GitHub
8月 13, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Speed up merge cells
上级
61d0ed1f
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
226 addition
and
129 deletion
+226
-129
adjust.go
adjust.go
+4
-4
adjust_test.go
adjust_test.go
+4
-0
calc.go
calc.go
+6
-6
cell.go
cell.go
+25
-6
col.go
col.go
+3
-3
lib.go
lib.go
+2
-3
merge.go
merge.go
+149
-68
merge_test.go
merge_test.go
+22
-10
picture.go
picture.go
+2
-0
pivotTable.go
pivotTable.go
+1
-1
rows.go
rows.go
+2
-2
sheet.go
sheet.go
+3
-0
xmlSharedStrings.go
xmlSharedStrings.go
+1
-21
xmlWorksheet.go
xmlWorksheet.go
+2
-5
未找到文件。
adjust.go
浏览文件 @
f6f14f50
...
@@ -145,7 +145,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
...
@@ -145,7 +145,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
return
nil
return
nil
}
}
coordinates
,
err
:=
f
.
areaRefToCoordinates
(
ws
.
AutoFilter
.
Ref
)
coordinates
,
err
:=
areaRefToCoordinates
(
ws
.
AutoFilter
.
Ref
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -199,7 +199,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
...
@@ -199,7 +199,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
for
i
:=
0
;
i
<
len
(
ws
.
MergeCells
.
Cells
);
i
++
{
for
i
:=
0
;
i
<
len
(
ws
.
MergeCells
.
Cells
);
i
++
{
areaData
:=
ws
.
MergeCells
.
Cells
[
i
]
areaData
:=
ws
.
MergeCells
.
Cells
[
i
]
coordinates
,
err
:=
f
.
areaRefToCoordinates
(
areaData
.
Ref
)
coordinates
,
err
:=
areaRefToCoordinates
(
areaData
.
Ref
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -219,7 +219,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
...
@@ -219,7 +219,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
x1
=
f
.
adjustMergeCellsHelper
(
x1
,
num
,
offset
)
x1
=
f
.
adjustMergeCellsHelper
(
x1
,
num
,
offset
)
x2
=
f
.
adjustMergeCellsHelper
(
x2
,
num
,
offset
)
x2
=
f
.
adjustMergeCellsHelper
(
x2
,
num
,
offset
)
}
}
if
x1
==
x2
&&
y1
==
y2
{
if
x1
==
x2
&&
y1
==
y2
&&
i
>=
0
{
f
.
deleteMergeCell
(
ws
,
i
)
f
.
deleteMergeCell
(
ws
,
i
)
i
--
i
--
}
}
...
@@ -234,7 +234,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
...
@@ -234,7 +234,7 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
// compare and calculate cell axis by the given pivot, operation axis and
// compare and calculate cell axis by the given pivot, operation axis and
// offset.
// offset.
func
(
f
*
File
)
adjustMergeCellsHelper
(
pivot
,
num
,
offset
int
)
int
{
func
(
f
*
File
)
adjustMergeCellsHelper
(
pivot
,
num
,
offset
int
)
int
{
if
pivot
>
=
num
{
if
pivot
>
num
{
pivot
+=
offset
pivot
+=
offset
if
pivot
<
1
{
if
pivot
<
1
{
return
1
return
1
...
...
adjust_test.go
浏览文件 @
f6f14f50
...
@@ -84,6 +84,10 @@ func TestAdjustHelper(t *testing.T) {
...
@@ -84,6 +84,10 @@ func TestAdjustHelper(t *testing.T) {
assert
.
EqualError
(
t
,
f
.
adjustHelper
(
"SheetN"
,
rows
,
0
,
0
),
"sheet SheetN is not exist"
)
assert
.
EqualError
(
t
,
f
.
adjustHelper
(
"SheetN"
,
rows
,
0
,
0
),
"sheet SheetN is not exist"
)
}
}
func
TestAdjustMergeCellsHelper
(
t
*
testing
.
T
)
{
assert
.
Equal
(
t
,
1
,
NewFile
()
.
adjustMergeCellsHelper
(
1
,
0
,
-
2
))
}
func
TestAdjustCalcChain
(
t
*
testing
.
T
)
{
func
TestAdjustCalcChain
(
t
*
testing
.
T
)
{
f
:=
NewFile
()
f
:=
NewFile
()
f
.
CalcChain
=
&
xlsxCalcChain
{
f
.
CalcChain
=
&
xlsxCalcChain
{
...
...
calc.go
浏览文件 @
f6f14f50
...
@@ -5103,11 +5103,11 @@ func (fn *formulaFuncs) kth(name string, argsList *list.List) formulaArg {
...
@@ -5103,11 +5103,11 @@ func (fn *formulaFuncs) kth(name string, argsList *list.List) formulaArg {
return
newErrorFormulaArg
(
formulaErrorVALUE
,
fmt
.
Sprintf
(
"%s requires 2 arguments"
,
name
))
return
newErrorFormulaArg
(
formulaErrorVALUE
,
fmt
.
Sprintf
(
"%s requires 2 arguments"
,
name
))
}
}
array
:=
argsList
.
Front
()
.
Value
.
(
formulaArg
)
.
ToList
()
array
:=
argsList
.
Front
()
.
Value
.
(
formulaArg
)
.
ToList
()
kArg
:=
argsList
.
Back
()
.
Value
.
(
formulaArg
)
.
ToNumber
()
argK
:=
argsList
.
Back
()
.
Value
.
(
formulaArg
)
.
ToNumber
()
if
kArg
.
Type
!=
ArgNumber
{
if
argK
.
Type
!=
ArgNumber
{
return
kArg
return
argK
}
}
k
:=
int
(
kArg
.
Number
)
k
:=
int
(
argK
.
Number
)
if
k
<
1
{
if
k
<
1
{
return
newErrorFormulaArg
(
formulaErrorNUM
,
"k should be > 0"
)
return
newErrorFormulaArg
(
formulaErrorNUM
,
"k should be > 0"
)
}
}
...
@@ -7177,7 +7177,7 @@ func (fn *formulaFuncs) VLOOKUP(argsList *list.List) formulaArg {
...
@@ -7177,7 +7177,7 @@ func (fn *formulaFuncs) VLOOKUP(argsList *list.List) formulaArg {
func
vlookupBinarySearch
(
tableArray
,
lookupValue
formulaArg
)
(
matchIdx
int
,
wasExact
bool
)
{
func
vlookupBinarySearch
(
tableArray
,
lookupValue
formulaArg
)
(
matchIdx
int
,
wasExact
bool
)
{
var
low
,
high
,
lastMatchIdx
int
=
0
,
len
(
tableArray
.
Matrix
)
-
1
,
-
1
var
low
,
high
,
lastMatchIdx
int
=
0
,
len
(
tableArray
.
Matrix
)
-
1
,
-
1
for
low
<=
high
{
for
low
<=
high
{
var
mid
int
=
low
+
(
high
-
low
)
/
2
mid
:
=
low
+
(
high
-
low
)
/
2
mtx
:=
tableArray
.
Matrix
[
mid
]
mtx
:=
tableArray
.
Matrix
[
mid
]
lhs
:=
mtx
[
0
]
lhs
:=
mtx
[
0
]
switch
lookupValue
.
Type
{
switch
lookupValue
.
Type
{
...
@@ -7216,7 +7216,7 @@ func vlookupBinarySearch(tableArray, lookupValue formulaArg) (matchIdx int, wasE
...
@@ -7216,7 +7216,7 @@ func vlookupBinarySearch(tableArray, lookupValue formulaArg) (matchIdx int, wasE
func
hlookupBinarySearch
(
row
[]
formulaArg
,
lookupValue
formulaArg
)
(
matchIdx
int
,
wasExact
bool
)
{
func
hlookupBinarySearch
(
row
[]
formulaArg
,
lookupValue
formulaArg
)
(
matchIdx
int
,
wasExact
bool
)
{
var
low
,
high
,
lastMatchIdx
int
=
0
,
len
(
row
)
-
1
,
-
1
var
low
,
high
,
lastMatchIdx
int
=
0
,
len
(
row
)
-
1
,
-
1
for
low
<=
high
{
for
low
<=
high
{
var
mid
int
=
low
+
(
high
-
low
)
/
2
mid
:
=
low
+
(
high
-
low
)
/
2
mtx
:=
row
[
mid
]
mtx
:=
row
[
mid
]
result
:=
compareFormulaArg
(
mtx
,
lookupValue
,
false
,
false
)
result
:=
compareFormulaArg
(
mtx
,
lookupValue
,
false
,
false
)
if
result
==
criteriaEq
{
if
result
==
criteriaEq
{
...
...
cell.go
浏览文件 @
f6f14f50
...
@@ -101,6 +101,28 @@ func (f *File) SetCellValue(sheet, axis string, value interface{}) error {
...
@@ -101,6 +101,28 @@ func (f *File) SetCellValue(sheet, axis string, value interface{}) error {
return
err
return
err
}
}
// String extracts characters from a string item.
func
(
x
xlsxSI
)
String
()
string
{
if
len
(
x
.
R
)
>
0
{
var
rows
strings
.
Builder
for
_
,
s
:=
range
x
.
R
{
if
s
.
T
!=
nil
{
rows
.
WriteString
(
s
.
T
.
Val
)
}
}
return
bstrUnmarshal
(
rows
.
String
())
}
if
x
.
T
!=
nil
{
return
bstrUnmarshal
(
x
.
T
.
Val
)
}
return
""
}
// hasValue determine if cell non-blank value.
func
(
c
*
xlsxC
)
hasValue
()
bool
{
return
c
.
S
!=
0
||
c
.
V
!=
""
||
c
.
F
!=
nil
||
c
.
T
!=
""
}
// setCellIntFunc is a wrapper of SetCellInt.
// setCellIntFunc is a wrapper of SetCellInt.
func
(
f
*
File
)
setCellIntFunc
(
sheet
,
axis
string
,
value
interface
{})
error
{
func
(
f
*
File
)
setCellIntFunc
(
sheet
,
axis
string
,
value
interface
{})
error
{
var
err
error
var
err
error
...
@@ -431,13 +453,11 @@ func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error) {
...
@@ -431,13 +453,11 @@ func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error) {
if
_
,
_
,
err
:=
SplitCellName
(
axis
);
err
!=
nil
{
if
_
,
_
,
err
:=
SplitCellName
(
axis
);
err
!=
nil
{
return
false
,
""
,
err
return
false
,
""
,
err
}
}
ws
,
err
:=
f
.
workSheetReader
(
sheet
)
ws
,
err
:=
f
.
workSheetReader
(
sheet
)
if
err
!=
nil
{
if
err
!=
nil
{
return
false
,
""
,
err
return
false
,
""
,
err
}
}
axis
,
err
=
f
.
mergeCellsParser
(
ws
,
axis
)
if
axis
,
err
=
f
.
mergeCellsParser
(
ws
,
axis
);
err
!=
nil
{
if
err
!=
nil
{
return
false
,
""
,
err
return
false
,
""
,
err
}
}
if
ws
.
Hyperlinks
!=
nil
{
if
ws
.
Hyperlinks
!=
nil
{
...
@@ -485,8 +505,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
...
@@ -485,8 +505,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
axis
,
err
=
f
.
mergeCellsParser
(
ws
,
axis
)
if
axis
,
err
=
f
.
mergeCellsParser
(
ws
,
axis
);
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -932,7 +951,7 @@ func (f *File) checkCellInArea(cell, area string) (bool, error) {
...
@@ -932,7 +951,7 @@ func (f *File) checkCellInArea(cell, area string) (bool, error) {
if
len
(
rng
)
!=
2
{
if
len
(
rng
)
!=
2
{
return
false
,
err
return
false
,
err
}
}
coordinates
,
err
:=
f
.
areaRefToCoordinates
(
area
)
coordinates
,
err
:=
areaRefToCoordinates
(
area
)
if
err
!=
nil
{
if
err
!=
nil
{
return
false
,
err
return
false
,
err
}
}
...
...
col.go
浏览文件 @
f6f14f50
...
@@ -616,10 +616,10 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
...
@@ -616,10 +616,10 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
// getColWidth provides a function to get column width in pixels by given
// getColWidth provides a function to get column width in pixels by given
// sheet name and column number.
// sheet name and column number.
func
(
f
*
File
)
getColWidth
(
sheet
string
,
col
int
)
int
{
func
(
f
*
File
)
getColWidth
(
sheet
string
,
col
int
)
int
{
xlsx
,
_
:=
f
.
workSheetReader
(
sheet
)
ws
,
_
:=
f
.
workSheetReader
(
sheet
)
if
xlsx
.
Cols
!=
nil
{
if
ws
.
Cols
!=
nil
{
var
width
float64
var
width
float64
for
_
,
v
:=
range
xlsx
.
Cols
.
Col
{
for
_
,
v
:=
range
ws
.
Cols
.
Col
{
if
v
.
Min
<=
col
&&
col
<=
v
.
Max
{
if
v
.
Min
<=
col
&&
col
<=
v
.
Max
{
width
=
v
.
Width
width
=
v
.
Width
}
}
...
...
lib.go
浏览文件 @
f6f14f50
...
@@ -221,12 +221,11 @@ func CoordinatesToCellName(col, row int, abs ...bool) (string, error) {
...
@@ -221,12 +221,11 @@ func CoordinatesToCellName(col, row int, abs ...bool) (string, error) {
// areaRefToCoordinates provides a function to convert area reference to a
// areaRefToCoordinates provides a function to convert area reference to a
// pair of coordinates.
// pair of coordinates.
func
(
f
*
File
)
areaRefToCoordinates
(
ref
string
)
([]
int
,
error
)
{
func
areaRefToCoordinates
(
ref
string
)
([]
int
,
error
)
{
rng
:=
strings
.
Split
(
strings
.
Replace
(
ref
,
"$"
,
""
,
-
1
),
":"
)
rng
:=
strings
.
Split
(
strings
.
Replace
(
ref
,
"$"
,
""
,
-
1
),
":"
)
if
len
(
rng
)
<
2
{
if
len
(
rng
)
<
2
{
return
nil
,
ErrParameterInvalid
return
nil
,
ErrParameterInvalid
}
}
return
areaRangeToCoordinates
(
rng
[
0
],
rng
[
1
])
return
areaRangeToCoordinates
(
rng
[
0
],
rng
[
1
])
}
}
...
@@ -290,7 +289,7 @@ func (f *File) flatSqref(sqref string) (cells map[int][][]int, err error) {
...
@@ -290,7 +289,7 @@ func (f *File) flatSqref(sqref string) (cells map[int][][]int, err error) {
}
}
cells
[
col
]
=
append
(
cells
[
col
],
[]
int
{
col
,
row
})
cells
[
col
]
=
append
(
cells
[
col
],
[]
int
{
col
,
row
})
case
2
:
case
2
:
if
coordinates
,
err
=
f
.
areaRefToCoordinates
(
ref
);
err
!=
nil
{
if
coordinates
,
err
=
areaRefToCoordinates
(
ref
);
err
!=
nil
{
return
return
}
}
_
=
sortCoordinates
(
coordinates
)
_
=
sortCoordinates
(
coordinates
)
...
...
merge.go
浏览文件 @
f6f14f50
...
@@ -11,10 +11,16 @@
...
@@ -11,10 +11,16 @@
package
excelize
package
excelize
import
(
import
"strings"
"fmt"
"strings"
// Rect gets merged cell rectangle coordinates sequence.
)
func
(
mc
*
xlsxMergeCell
)
Rect
()
([]
int
,
error
)
{
var
err
error
if
mc
.
rect
==
nil
{
mc
.
rect
,
err
=
areaRefToCoordinates
(
mc
.
Ref
)
}
return
mc
.
rect
,
err
}
// MergeCell provides a function to merge cells by given coordinate area and
// MergeCell provides a function to merge cells by given coordinate area and
// sheet name. Merging cells only keeps the upper-left cell value, and
// sheet name. Merging cells only keeps the upper-left cell value, and
...
@@ -24,7 +30,9 @@ import (
...
@@ -24,7 +30,9 @@ import (
// err := f.MergeCell("Sheet1", "D3", "E9")
// err := f.MergeCell("Sheet1", "D3", "E9")
//
//
// If you create a merged cell that overlaps with another existing merged cell,
// If you create a merged cell that overlaps with another existing merged cell,
// those merged cells that already exist will be removed.
// those merged cells that already exist will be removed. The cell coordinates
// tuple after merging in the following range will be: A1(x3,y1) D1(x2,y1)
// A8(x3,y4) D8(x2,y4)
//
//
// B1(x1,y1) D1(x2,y1)
// B1(x1,y1) D1(x2,y1)
// +------------------------+
// +------------------------+
...
@@ -39,15 +47,15 @@ import (
...
@@ -39,15 +47,15 @@ import (
// +------------------------+
// +------------------------+
//
//
func
(
f
*
File
)
MergeCell
(
sheet
,
hcell
,
vcell
string
)
error
{
func
(
f
*
File
)
MergeCell
(
sheet
,
hcell
,
vcell
string
)
error
{
rect
1
,
err
:=
f
.
areaRefToCoordinates
(
hcell
+
":"
+
vcell
)
rect
,
err
:=
areaRefToCoordinates
(
hcell
+
":"
+
vcell
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
// Correct the coordinate area, such correct C1:B3 to B1:C3.
_
=
sortCoordinates
(
rect
1
)
_
=
sortCoordinates
(
rect
)
hcell
,
_
=
CoordinatesToCellName
(
rect
1
[
0
],
rect1
[
1
])
hcell
,
_
=
CoordinatesToCellName
(
rect
[
0
],
rect
[
1
])
vcell
,
_
=
CoordinatesToCellName
(
rect
1
[
2
],
rect1
[
3
])
vcell
,
_
=
CoordinatesToCellName
(
rect
[
2
],
rect
[
3
])
ws
,
err
:=
f
.
workSheetReader
(
sheet
)
ws
,
err
:=
f
.
workSheetReader
(
sheet
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -55,49 +63,9 @@ func (f *File) MergeCell(sheet, hcell, vcell string) error {
...
@@ -55,49 +63,9 @@ func (f *File) MergeCell(sheet, hcell, vcell string) error {
}
}
ref
:=
hcell
+
":"
+
vcell
ref
:=
hcell
+
":"
+
vcell
if
ws
.
MergeCells
!=
nil
{
if
ws
.
MergeCells
!=
nil
{
for
i
:=
0
;
i
<
len
(
ws
.
MergeCells
.
Cells
);
i
++
{
ws
.
MergeCells
.
Cells
=
append
(
ws
.
MergeCells
.
Cells
,
&
xlsxMergeCell
{
Ref
:
ref
,
rect
:
rect
})
cellData
:=
ws
.
MergeCells
.
Cells
[
i
]
if
cellData
==
nil
{
continue
}
cc
:=
strings
.
Split
(
cellData
.
Ref
,
":"
)
if
len
(
cc
)
!=
2
{
return
fmt
.
Errorf
(
"invalid area %q"
,
cellData
.
Ref
)
}
rect2
,
err
:=
f
.
areaRefToCoordinates
(
cellData
.
Ref
)
if
err
!=
nil
{
return
err
}
// Delete the merged cells of the overlapping area.
if
isOverlap
(
rect1
,
rect2
)
{
ws
.
MergeCells
.
Cells
=
append
(
ws
.
MergeCells
.
Cells
[
:
i
],
ws
.
MergeCells
.
Cells
[
i
+
1
:
]
...
)
i
--
if
rect1
[
0
]
>
rect2
[
0
]
{
rect1
[
0
],
rect2
[
0
]
=
rect2
[
0
],
rect1
[
0
]
}
if
rect1
[
2
]
<
rect2
[
2
]
{
rect1
[
2
],
rect2
[
2
]
=
rect2
[
2
],
rect1
[
2
]
}
if
rect1
[
1
]
>
rect2
[
1
]
{
rect1
[
1
],
rect2
[
1
]
=
rect2
[
1
],
rect1
[
1
]
}
if
rect1
[
3
]
<
rect2
[
3
]
{
rect1
[
3
],
rect2
[
3
]
=
rect2
[
3
],
rect1
[
3
]
}
hcell
,
_
=
CoordinatesToCellName
(
rect1
[
0
],
rect1
[
1
])
vcell
,
_
=
CoordinatesToCellName
(
rect1
[
2
],
rect1
[
3
])
ref
=
hcell
+
":"
+
vcell
}
}
ws
.
MergeCells
.
Cells
=
append
(
ws
.
MergeCells
.
Cells
,
&
xlsxMergeCell
{
Ref
:
ref
})
}
else
{
}
else
{
ws
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
ref
}}}
ws
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
ref
,
rect
:
rect
}}}
}
}
ws
.
MergeCells
.
Count
=
len
(
ws
.
MergeCells
.
Cells
)
ws
.
MergeCells
.
Count
=
len
(
ws
.
MergeCells
.
Cells
)
return
err
return
err
...
@@ -114,7 +82,7 @@ func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
...
@@ -114,7 +82,7 @@ func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
rect1
,
err
:=
f
.
areaRefToCoordinates
(
hcell
+
":"
+
vcell
)
rect1
,
err
:=
areaRefToCoordinates
(
hcell
+
":"
+
vcell
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -126,26 +94,19 @@ func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
...
@@ -126,26 +94,19 @@ func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
if
ws
.
MergeCells
==
nil
{
if
ws
.
MergeCells
==
nil
{
return
nil
return
nil
}
}
if
err
=
f
.
mergeOverlapCells
(
ws
);
err
!=
nil
{
return
err
}
i
:=
0
i
:=
0
for
_
,
cellData
:=
range
ws
.
MergeCells
.
Cells
{
for
_
,
mergeCell
:=
range
ws
.
MergeCells
.
Cells
{
if
cellData
==
nil
{
if
mergeCell
==
nil
{
continue
continue
}
}
cc
:=
strings
.
Split
(
cellData
.
Ref
,
":"
)
rect2
,
_
:=
areaRefToCoordinates
(
mergeCell
.
Ref
)
if
len
(
cc
)
!=
2
{
return
fmt
.
Errorf
(
"invalid area %q"
,
cellData
.
Ref
)
}
rect2
,
err
:=
f
.
areaRefToCoordinates
(
cellData
.
Ref
)
if
err
!=
nil
{
return
err
}
if
isOverlap
(
rect1
,
rect2
)
{
if
isOverlap
(
rect1
,
rect2
)
{
continue
continue
}
}
ws
.
MergeCells
.
Cells
[
i
]
=
cellData
ws
.
MergeCells
.
Cells
[
i
]
=
mergeCell
i
++
i
++
}
}
ws
.
MergeCells
.
Cells
=
ws
.
MergeCells
.
Cells
[
:
i
]
ws
.
MergeCells
.
Cells
=
ws
.
MergeCells
.
Cells
[
:
i
]
...
@@ -165,8 +126,10 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
...
@@ -165,8 +126,10 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
return
mergeCells
,
err
return
mergeCells
,
err
}
}
if
ws
.
MergeCells
!=
nil
{
if
ws
.
MergeCells
!=
nil
{
if
err
=
f
.
mergeOverlapCells
(
ws
);
err
!=
nil
{
return
mergeCells
,
err
}
mergeCells
=
make
([]
MergeCell
,
0
,
len
(
ws
.
MergeCells
.
Cells
))
mergeCells
=
make
([]
MergeCell
,
0
,
len
(
ws
.
MergeCells
.
Cells
))
for
i
:=
range
ws
.
MergeCells
.
Cells
{
for
i
:=
range
ws
.
MergeCells
.
Cells
{
ref
:=
ws
.
MergeCells
.
Cells
[
i
]
.
Ref
ref
:=
ws
.
MergeCells
.
Cells
[
i
]
.
Ref
axis
:=
strings
.
Split
(
ref
,
":"
)[
0
]
axis
:=
strings
.
Split
(
ref
,
":"
)[
0
]
...
@@ -174,10 +137,128 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
...
@@ -174,10 +137,128 @@ func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
mergeCells
=
append
(
mergeCells
,
[]
string
{
ref
,
val
})
mergeCells
=
append
(
mergeCells
,
[]
string
{
ref
,
val
})
}
}
}
}
return
mergeCells
,
err
return
mergeCells
,
err
}
}
// overlapRange calculate overlap range of merged cells, and returns max
// column and rows of the range.
func
overlapRange
(
ws
*
xlsxWorksheet
)
(
row
,
col
int
,
err
error
)
{
var
rect
[]
int
for
_
,
mergeCell
:=
range
ws
.
MergeCells
.
Cells
{
if
mergeCell
==
nil
{
continue
}
if
rect
,
err
=
mergeCell
.
Rect
();
err
!=
nil
{
return
}
x1
,
y1
,
x2
,
y2
:=
rect
[
0
],
rect
[
1
],
rect
[
2
],
rect
[
3
]
if
x1
>
col
{
col
=
x1
}
if
x2
>
col
{
col
=
x2
}
if
y1
>
row
{
row
=
y1
}
if
y2
>
row
{
row
=
y2
}
}
return
}
// flatMergedCells convert merged cells range reference to cell-matrix.
func
flatMergedCells
(
ws
*
xlsxWorksheet
,
matrix
[][]
*
xlsxMergeCell
)
error
{
for
i
,
cell
:=
range
ws
.
MergeCells
.
Cells
{
rect
,
err
:=
cell
.
Rect
()
if
err
!=
nil
{
return
err
}
x1
,
y1
,
x2
,
y2
:=
rect
[
0
]
-
1
,
rect
[
1
]
-
1
,
rect
[
2
]
-
1
,
rect
[
3
]
-
1
var
overlapCells
[]
*
xlsxMergeCell
for
x
:=
x1
;
x
<=
x2
;
x
++
{
for
y
:=
y1
;
y
<=
y2
;
y
++
{
if
matrix
[
x
][
y
]
!=
nil
{
overlapCells
=
append
(
overlapCells
,
matrix
[
x
][
y
])
}
matrix
[
x
][
y
]
=
cell
}
}
if
len
(
overlapCells
)
!=
0
{
newCell
:=
cell
for
_
,
overlapCell
:=
range
overlapCells
{
newCell
=
mergeCell
(
cell
,
overlapCell
)
}
newRect
,
_
:=
newCell
.
Rect
()
x1
,
y1
,
x2
,
y2
:=
newRect
[
0
]
-
1
,
newRect
[
1
]
-
1
,
newRect
[
2
]
-
1
,
newRect
[
3
]
-
1
for
x
:=
x1
;
x
<=
x2
;
x
++
{
for
y
:=
y1
;
y
<=
y2
;
y
++
{
matrix
[
x
][
y
]
=
newCell
}
}
ws
.
MergeCells
.
Cells
[
i
]
=
newCell
}
}
return
nil
}
// mergeOverlapCells merge overlap cells.
func
(
f
*
File
)
mergeOverlapCells
(
ws
*
xlsxWorksheet
)
error
{
rows
,
cols
,
err
:=
overlapRange
(
ws
)
if
err
!=
nil
{
return
err
}
if
rows
==
0
||
cols
==
0
{
return
nil
}
matrix
:=
make
([][]
*
xlsxMergeCell
,
cols
)
for
i
:=
range
matrix
{
matrix
[
i
]
=
make
([]
*
xlsxMergeCell
,
rows
)
}
_
=
flatMergedCells
(
ws
,
matrix
)
mergeCells
:=
ws
.
MergeCells
.
Cells
[
:
0
]
for
_
,
cell
:=
range
ws
.
MergeCells
.
Cells
{
rect
,
_
:=
cell
.
Rect
()
x1
,
y1
,
x2
,
y2
:=
rect
[
0
]
-
1
,
rect
[
1
]
-
1
,
rect
[
2
]
-
1
,
rect
[
3
]
-
1
if
matrix
[
x1
][
y1
]
==
cell
{
mergeCells
=
append
(
mergeCells
,
cell
)
for
x
:=
x1
;
x
<=
x2
;
x
++
{
for
y
:=
y1
;
y
<=
y2
;
y
++
{
matrix
[
x
][
y
]
=
nil
}
}
}
}
ws
.
MergeCells
.
Count
,
ws
.
MergeCells
.
Cells
=
len
(
mergeCells
),
mergeCells
return
nil
}
// mergeCell merge two cells.
func
mergeCell
(
cell1
,
cell2
*
xlsxMergeCell
)
*
xlsxMergeCell
{
rect1
,
_
:=
cell1
.
Rect
()
rect2
,
_
:=
cell2
.
Rect
()
if
rect1
[
0
]
>
rect2
[
0
]
{
rect1
[
0
],
rect2
[
0
]
=
rect2
[
0
],
rect1
[
0
]
}
if
rect1
[
2
]
<
rect2
[
2
]
{
rect1
[
2
],
rect2
[
2
]
=
rect2
[
2
],
rect1
[
2
]
}
if
rect1
[
1
]
>
rect2
[
1
]
{
rect1
[
1
],
rect2
[
1
]
=
rect2
[
1
],
rect1
[
1
]
}
if
rect1
[
3
]
<
rect2
[
3
]
{
rect1
[
3
],
rect2
[
3
]
=
rect2
[
3
],
rect1
[
3
]
}
hcell
,
_
:=
CoordinatesToCellName
(
rect1
[
0
],
rect1
[
1
])
vcell
,
_
:=
CoordinatesToCellName
(
rect1
[
2
],
rect1
[
3
])
return
&
xlsxMergeCell
{
rect
:
rect1
,
Ref
:
hcell
+
":"
+
vcell
}
}
// MergeCell define a merged cell data.
// MergeCell define a merged cell data.
// It consists of the following structure.
// It consists of the following structure.
// example: []string{"D4:E10", "cell value"}
// example: []string{"D4:E10", "cell value"}
...
...
merge_test.go
浏览文件 @
f6f14f50
...
@@ -27,7 +27,7 @@ func TestMergeCell(t *testing.T) {
...
@@ -27,7 +27,7 @@ func TestMergeCell(t *testing.T) {
assert
.
NoError
(
t
,
f
.
SetCellHyperLink
(
"Sheet1"
,
"J11"
,
"https://github.com/xuri/excelize"
,
"External"
))
assert
.
NoError
(
t
,
f
.
SetCellHyperLink
(
"Sheet1"
,
"J11"
,
"https://github.com/xuri/excelize"
,
"External"
))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"G12"
,
"SUM(Sheet1!B19,Sheet1!C19)"
))
assert
.
NoError
(
t
,
f
.
SetCellFormula
(
"Sheet1"
,
"G12"
,
"SUM(Sheet1!B19,Sheet1!C19)"
))
value
,
err
:=
f
.
GetCellValue
(
"Sheet1"
,
"H11"
)
value
,
err
:=
f
.
GetCellValue
(
"Sheet1"
,
"H11"
)
assert
.
Equal
(
t
,
"
0.5
"
,
value
)
assert
.
Equal
(
t
,
"
100
"
,
value
)
assert
.
NoError
(
t
,
err
)
assert
.
NoError
(
t
,
err
)
value
,
err
=
f
.
GetCellValue
(
"Sheet2"
,
"A6"
)
// Merged cell ref is single coordinate.
value
,
err
=
f
.
GetCellValue
(
"Sheet2"
,
"A6"
)
// Merged cell ref is single coordinate.
assert
.
Equal
(
t
,
""
,
value
)
assert
.
Equal
(
t
,
""
,
value
)
...
@@ -75,16 +75,24 @@ func TestMergeCell(t *testing.T) {
...
@@ -75,16 +75,24 @@ func TestMergeCell(t *testing.T) {
assert
.
True
(
t
,
ok
)
assert
.
True
(
t
,
ok
)
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{
nil
,
nil
}}
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{
nil
,
nil
}}
assert
.
NoError
(
t
,
f
.
MergeCell
(
"Sheet1"
,
"A2"
,
"B3"
))
assert
.
NoError
(
t
,
f
.
MergeCell
(
"Sheet1"
,
"A2"
,
"B3"
))
}
ws
,
ok
=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
func
TestMergeCellOverlap
(
t
*
testing
.
T
)
{
assert
.
True
(
t
,
ok
)
f
:=
NewFile
()
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A1"
}}}
assert
.
NoError
(
t
,
f
.
MergeCell
(
"Sheet1"
,
"A1"
,
"C2"
))
assert
.
EqualError
(
t
,
f
.
MergeCell
(
"Sheet1"
,
"A2"
,
"B3"
),
`invalid area "A1"`
)
assert
.
NoError
(
t
,
f
.
MergeCell
(
"Sheet1"
,
"B2"
,
"D3"
))
assert
.
NoError
(
t
,
f
.
SaveAs
(
filepath
.
Join
(
"test"
,
"TestMergeCellOverlap.xlsx"
)))
ws
,
ok
=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
f
,
err
:=
OpenFile
(
filepath
.
Join
(
"test"
,
"TestMergeCellOverlap.xlsx"
))
assert
.
True
(
t
,
ok
)
if
!
assert
.
NoError
(
t
,
err
)
{
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A:A"
}}}
t
.
FailNow
()
assert
.
EqualError
(
t
,
f
.
MergeCell
(
"Sheet1"
,
"A2"
,
"B3"
),
`cannot convert cell "A" to coordinates: invalid cell name "A"`
)
}
mc
,
err
:=
f
.
GetMergeCells
(
"Sheet1"
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
mc
))
assert
.
Equal
(
t
,
"A1"
,
mc
[
0
]
.
GetStartAxis
())
assert
.
Equal
(
t
,
"D3"
,
mc
[
0
]
.
GetEndAxis
())
assert
.
Equal
(
t
,
""
,
mc
[
0
]
.
GetCellValue
())
}
}
func
TestGetMergeCells
(
t
*
testing
.
T
)
{
func
TestGetMergeCells
(
t
*
testing
.
T
)
{
...
@@ -173,11 +181,15 @@ func TestUnmergeCell(t *testing.T) {
...
@@ -173,11 +181,15 @@ func TestUnmergeCell(t *testing.T) {
ws
,
ok
=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
ws
,
ok
=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
assert
.
True
(
t
,
ok
)
assert
.
True
(
t
,
ok
)
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A1"
}}}
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A1"
}}}
assert
.
EqualError
(
t
,
f
.
UnmergeCell
(
"Sheet1"
,
"A2"
,
"B3"
),
`invalid area "A1"`
)
assert
.
EqualError
(
t
,
f
.
UnmergeCell
(
"Sheet1"
,
"A2"
,
"B3"
),
"parameter is invalid"
)
ws
,
ok
=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
ws
,
ok
=
f
.
Sheet
.
Load
(
"xl/worksheets/sheet1.xml"
)
assert
.
True
(
t
,
ok
)
assert
.
True
(
t
,
ok
)
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A:A"
}}}
ws
.
(
*
xlsxWorksheet
)
.
MergeCells
=
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A:A"
}}}
assert
.
EqualError
(
t
,
f
.
UnmergeCell
(
"Sheet1"
,
"A2"
,
"B3"
),
`cannot convert cell "A" to coordinates: invalid cell name "A"`
)
assert
.
EqualError
(
t
,
f
.
UnmergeCell
(
"Sheet1"
,
"A2"
,
"B3"
),
`cannot convert cell "A" to coordinates: invalid cell name "A"`
)
}
func
TestFlatMergedCells
(
t
*
testing
.
T
)
{
ws
:=
&
xlsxWorksheet
{
MergeCells
:
&
xlsxMergeCells
{
Cells
:
[]
*
xlsxMergeCell
{{
Ref
:
"A1"
}}}}
assert
.
EqualError
(
t
,
flatMergedCells
(
ws
,
[][]
*
xlsxMergeCell
{}),
"parameter is invalid"
)
}
}
picture.go
浏览文件 @
f6f14f50
...
@@ -148,6 +148,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
...
@@ -148,6 +148,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
ws
.
Lock
()
// Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
// Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
drawingID
:=
f
.
countDrawings
()
+
1
drawingID
:=
f
.
countDrawings
()
+
1
drawingXML
:=
"xl/drawings/drawing"
+
strconv
.
Itoa
(
drawingID
)
+
".xml"
drawingXML
:=
"xl/drawings/drawing"
+
strconv
.
Itoa
(
drawingID
)
+
".xml"
...
@@ -162,6 +163,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
...
@@ -162,6 +163,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
}
}
drawingHyperlinkRID
=
f
.
addRels
(
drawingRels
,
SourceRelationshipHyperLink
,
formatSet
.
Hyperlink
,
hyperlinkType
)
drawingHyperlinkRID
=
f
.
addRels
(
drawingRels
,
SourceRelationshipHyperLink
,
formatSet
.
Hyperlink
,
hyperlinkType
)
}
}
ws
.
Unlock
()
err
=
f
.
addDrawingPicture
(
sheet
,
drawingXML
,
cell
,
name
,
img
.
Width
,
img
.
Height
,
drawingRID
,
drawingHyperlinkRID
,
formatSet
)
err
=
f
.
addDrawingPicture
(
sheet
,
drawingXML
,
cell
,
name
,
img
.
Width
,
img
.
Height
,
drawingRID
,
drawingHyperlinkRID
,
formatSet
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
...
pivotTable.go
浏览文件 @
f6f14f50
...
@@ -198,7 +198,7 @@ func (f *File) adjustRange(rangeStr string) (string, []int, error) {
...
@@ -198,7 +198,7 @@ func (f *File) adjustRange(rangeStr string) (string, []int, error) {
return
""
,
[]
int
{},
ErrParameterInvalid
return
""
,
[]
int
{},
ErrParameterInvalid
}
}
trimRng
:=
strings
.
Replace
(
rng
[
1
],
"$"
,
""
,
-
1
)
trimRng
:=
strings
.
Replace
(
rng
[
1
],
"$"
,
""
,
-
1
)
coordinates
,
err
:=
f
.
areaRefToCoordinates
(
trimRng
)
coordinates
,
err
:=
areaRefToCoordinates
(
trimRng
)
if
err
!=
nil
{
if
err
!=
nil
{
return
rng
[
0
],
[]
int
{},
err
return
rng
[
0
],
[]
int
{},
err
}
}
...
...
rows.go
浏览文件 @
f6f14f50
...
@@ -614,7 +614,7 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
...
@@ -614,7 +614,7 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
row
++
row
++
}
}
for
_
,
rng
:=
range
ws
.
MergeCells
.
Cells
{
for
_
,
rng
:=
range
ws
.
MergeCells
.
Cells
{
coordinates
,
err
:=
f
.
areaRefToCoordinates
(
rng
.
Ref
)
coordinates
,
err
:=
areaRefToCoordinates
(
rng
.
Ref
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -624,7 +624,7 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
...
@@ -624,7 +624,7 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
}
}
for
i
:=
0
;
i
<
len
(
ws
.
MergeCells
.
Cells
);
i
++
{
for
i
:=
0
;
i
<
len
(
ws
.
MergeCells
.
Cells
);
i
++
{
areaData
:=
ws
.
MergeCells
.
Cells
[
i
]
areaData
:=
ws
.
MergeCells
.
Cells
[
i
]
coordinates
,
_
:=
f
.
areaRefToCoordinates
(
areaData
.
Ref
)
coordinates
,
_
:=
areaRefToCoordinates
(
areaData
.
Ref
)
x1
,
y1
,
x2
,
y2
:=
coordinates
[
0
],
coordinates
[
1
],
coordinates
[
2
],
coordinates
[
3
]
x1
,
y1
,
x2
,
y2
:=
coordinates
[
0
],
coordinates
[
1
],
coordinates
[
2
],
coordinates
[
3
]
if
y1
==
y2
&&
y1
==
row
{
if
y1
==
y2
&&
y1
==
row
{
from
,
_
:=
CoordinatesToCellName
(
x1
,
row2
)
from
,
_
:=
CoordinatesToCellName
(
x1
,
row2
)
...
...
sheet.go
浏览文件 @
f6f14f50
...
@@ -158,6 +158,9 @@ func (f *File) workSheetWriter() {
...
@@ -158,6 +158,9 @@ func (f *File) workSheetWriter() {
f
.
Sheet
.
Range
(
func
(
p
,
ws
interface
{})
bool
{
f
.
Sheet
.
Range
(
func
(
p
,
ws
interface
{})
bool
{
if
ws
!=
nil
{
if
ws
!=
nil
{
sheet
:=
ws
.
(
*
xlsxWorksheet
)
sheet
:=
ws
.
(
*
xlsxWorksheet
)
if
sheet
.
MergeCells
!=
nil
&&
len
(
sheet
.
MergeCells
.
Cells
)
>
0
{
_
=
f
.
mergeOverlapCells
(
sheet
)
}
for
k
,
v
:=
range
sheet
.
SheetData
.
Row
{
for
k
,
v
:=
range
sheet
.
SheetData
.
Row
{
sheet
.
SheetData
.
Row
[
k
]
.
C
=
trimCell
(
v
.
C
)
sheet
.
SheetData
.
Row
[
k
]
.
C
=
trimCell
(
v
.
C
)
}
}
...
...
xmlSharedStrings.go
浏览文件 @
f6f14f50
...
@@ -11,10 +11,7 @@
...
@@ -11,10 +11,7 @@
package
excelize
package
excelize
import
(
import
"encoding/xml"
"encoding/xml"
"strings"
)
// xlsxSST directly maps the sst element from the namespace
// xlsxSST directly maps the sst element from the namespace
// http://schemas.openxmlformats.org/spreadsheetml/2006/main. String values may
// http://schemas.openxmlformats.org/spreadsheetml/2006/main. String values may
...
@@ -44,23 +41,6 @@ type xlsxSI struct {
...
@@ -44,23 +41,6 @@ type xlsxSI struct {
PhoneticPr
*
xlsxPhoneticPr
`xml:"phoneticPr"`
PhoneticPr
*
xlsxPhoneticPr
`xml:"phoneticPr"`
}
}
// String extracts characters from a string item.
func
(
x
xlsxSI
)
String
()
string
{
if
len
(
x
.
R
)
>
0
{
var
rows
strings
.
Builder
for
_
,
s
:=
range
x
.
R
{
if
s
.
T
!=
nil
{
rows
.
WriteString
(
s
.
T
.
Val
)
}
}
return
bstrUnmarshal
(
rows
.
String
())
}
if
x
.
T
!=
nil
{
return
bstrUnmarshal
(
x
.
T
.
Val
)
}
return
""
}
// xlsxR represents a run of rich text. A rich text run is a region of text
// xlsxR represents a run of rich text. A rich text run is a region of text
// that share a common set of properties, such as formatting properties. The
// that share a common set of properties, such as formatting properties. The
// properties are defined in the rPr element, and the text displayed to the
// properties are defined in the rPr element, and the text displayed to the
...
...
xmlWorksheet.go
浏览文件 @
f6f14f50
...
@@ -399,7 +399,8 @@ type xlsxCustomSheetView struct {
...
@@ -399,7 +399,8 @@ type xlsxCustomSheetView struct {
// xlsxMergeCell directly maps the mergeCell element. A single merged cell.
// xlsxMergeCell directly maps the mergeCell element. A single merged cell.
type
xlsxMergeCell
struct
{
type
xlsxMergeCell
struct
{
Ref
string
`xml:"ref,attr,omitempty"`
Ref
string
`xml:"ref,attr,omitempty"`
rect
[]
int
}
}
// xlsxMergeCells directly maps the mergeCells element. This collection
// xlsxMergeCells directly maps the mergeCells element. This collection
...
@@ -468,10 +469,6 @@ type xlsxC struct {
...
@@ -468,10 +469,6 @@ type xlsxC struct {
IS
*
xlsxSI
`xml:"is"`
IS
*
xlsxSI
`xml:"is"`
}
}
func
(
c
*
xlsxC
)
hasValue
()
bool
{
return
c
.
S
!=
0
||
c
.
V
!=
""
||
c
.
F
!=
nil
||
c
.
T
!=
""
}
// xlsxF represents a formula for the cell. The formula expression is
// xlsxF represents a formula for the cell. The formula expression is
// contained in the character node of this element.
// contained in the character node of this element.
type
xlsxF
struct
{
type
xlsxF
struct
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录