Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
戈吧噶吧噶了吧爬爬公主
easyexcel
提交
22dc33d4
E
easyexcel
项目概览
戈吧噶吧噶了吧爬爬公主
/
easyexcel
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
easyexcel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
22dc33d4
编写于
8月 06, 2019
作者:
Z
zhuangjiaju
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
优化读写逻辑
上级
99f041e9
变更
26
展开全部
隐藏空白更改
内联
并排
Showing
26 changed file
with
863 addition
and
411 deletion
+863
-411
README.md
README.md
+2
-2
img/readme/quickstart/read/demo.png
img/readme/quickstart/read/demo.png
+0
-0
quickstart.md
quickstart.md
+266
-299
src/main/java/com/alibaba/excel/context/WriteContextImpl.java
...main/java/com/alibaba/excel/context/WriteContextImpl.java
+5
-11
src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
.../com/alibaba/excel/converters/DefaultConverterLoader.java
+75
-57
src/main/java/com/alibaba/excel/enums/WriteLastRowType.java
src/main/java/com/alibaba/excel/enums/WriteLastRowType.java
+8
-4
src/main/java/com/alibaba/excel/util/WorkBookUtil.java
src/main/java/com/alibaba/excel/util/WorkBookUtil.java
+11
-2
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
+4
-14
src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java
...java/com/alibaba/excel/write/merge/LoopMergeStrategy.java
+10
-7
src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java
...alibaba/excel/write/metadata/holder/WriteSheetHolder.java
+33
-2
src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
...baba/excel/write/metadata/holder/WriteWorkbookHolder.java
+14
-0
src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java
.../alibaba/excel/write/property/ExcelWriteHeadProperty.java
+13
-1
src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataTest.java
...libaba/easyexcel/test/core/template/TemplateDataTest.java
+2
-2
src/test/java/com/alibaba/easyexcel/test/demo/poi/PoiTest.java
...est/java/com/alibaba/easyexcel/test/demo/poi/PoiTest.java
+54
-0
src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
...t/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
+9
-5
src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
...est/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
+1
-1
src/test/java/com/alibaba/easyexcel/test/demo/write/ComplexHeadData.java
...om/alibaba/easyexcel/test/demo/write/ComplexHeadData.java
+22
-0
src/test/java/com/alibaba/easyexcel/test/demo/write/ConverterData.java
.../com/alibaba/easyexcel/test/demo/write/ConverterData.java
+35
-0
src/test/java/com/alibaba/easyexcel/test/demo/write/CustomStringStringConverter.java
...asyexcel/test/demo/write/CustomStringStringConverter.java
+59
-0
src/test/java/com/alibaba/easyexcel/test/demo/write/IndexData.java
...java/com/alibaba/easyexcel/test/demo/write/IndexData.java
+25
-0
src/test/java/com/alibaba/easyexcel/test/demo/write/WidthAndHeightData.java
...alibaba/easyexcel/test/demo/write/WidthAndHeightData.java
+32
-0
src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
...java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
+181
-4
src/test/resources/demo/demo.xlsx
src/test/resources/demo/demo.xlsx
+0
-0
src/test/resources/template/template03.xls
src/test/resources/template/template03.xls
+0
-0
src/test/resources/template/template07.xlsx
src/test/resources/template/template07.xlsx
+0
-0
update.md
update.md
+2
-0
未找到文件。
README.md
浏览文件 @
22dc33d4
...
...
@@ -15,8 +15,8 @@
# JAVA解析Excel工具easyexcel
Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便
## 相关文档
*
[
关于软件
](
/abouteasyexcel.md
)
*
[
快速使用
](
/quickstart.md
)
*
[
关于软件
](
/abouteasyexcel.md
)
*
[
常见问题
](
/problem.md
)
*
[
更新记事
](
/update.md
)
*
[
English-README
](
/easyexcel_en.md
)
...
...
@@ -74,7 +74,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
* 文件下载
* <li>1. 创建excel对应的实体对象 参照{@link DownloadData}
* <li>2. 设置返回的 参数
* <li>3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭
异常
问题不大
* <li>3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭
流
问题不大
*/
@GetMapping
(
"download"
)
public
void
download
(
HttpServletResponse
response
)
throws
IOException
{
...
...
img/readme/quickstart/read/demo.png
0 → 100644
浏览文件 @
22dc33d4
10.3 KB
quickstart.md
浏览文件 @
22dc33d4
此差异已折叠。
点击以展开。
src/main/java/com/alibaba/excel/context/WriteContextImpl.java
浏览文件 @
22dc33d4
...
...
@@ -13,7 +13,6 @@ import org.apache.poi.ss.util.CellRangeAddress;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.alibaba.excel.enums.WriteLastRowType
;
import
com.alibaba.excel.exception.ExcelGenerateException
;
import
com.alibaba.excel.metadata.Head
;
import
com.alibaba.excel.util.WorkBookUtil
;
...
...
@@ -198,18 +197,13 @@ public class WriteContextImpl implements WriteContext {
if
(!
currentWriteHolder
.
needHead
()
||
!
currentWriteHolder
.
excelWriteHeadProperty
().
hasHead
())
{
return
;
}
int
lastRowNum
=
writeSheetHolder
.
getSheet
().
getLastRowNum
();
// 'lastRowNum' doesn't matter if it has one or zero,is's zero
if
(
WriteLastRowType
.
HAVE_DATA
==
writeSheetHolder
.
getWriteLastRowType
())
{
lastRowNum
++;
}
writeSheetHolder
.
setWriteLastRowType
(
WriteLastRowType
.
HAVE_DATA
);
int
rowIndex
=
lastRowNum
+
currentWriteHolder
.
relativeHeadRowIndex
();
int
newRowIndex
=
writeSheetHolder
.
getNewRowIndexAndStartDoWrite
();
newRowIndex
+=
currentWriteHolder
.
relativeHeadRowIndex
();
// Combined head
addMergedRegionToCurrentSheet
(
excelWriteHeadProperty
,
r
owIndex
);
for
(
int
relativeRowIndex
=
0
,
i
=
rowIndex
;
i
<
excelWriteHeadProperty
.
getHeadRowNumber
()
+
r
owIndex
;
addMergedRegionToCurrentSheet
(
excelWriteHeadProperty
,
newR
owIndex
);
for
(
int
relativeRowIndex
=
0
,
i
=
newRowIndex
;
i
<
excelWriteHeadProperty
.
getHeadRowNumber
()
+
newR
owIndex
;
i
++,
relativeRowIndex
++)
{
beforeRowCreate
(
r
owIndex
,
relativeRowIndex
);
beforeRowCreate
(
newR
owIndex
,
relativeRowIndex
);
Row
row
=
WorkBookUtil
.
createRow
(
writeSheetHolder
.
getSheet
(),
i
);
afterRowCreate
(
row
,
relativeRowIndex
);
addOneRowOfHeadDataToExcel
(
row
,
excelWriteHeadProperty
.
getHeadMap
(),
relativeRowIndex
);
...
...
src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
浏览文件 @
22dc33d4
...
...
@@ -40,28 +40,34 @@ import com.alibaba.excel.converters.string.StringStringConverter;
* @author Jiaju Zhuang
*/
public
class
DefaultConverterLoader
{
private
static
Map
<
String
,
Converter
>
defaultWriteConverter
;
private
static
Map
<
String
,
Converter
>
allConverter
;
/**
* Load default write converter
*
* @return
*/
public
static
Map
<
String
,
Converter
>
loadDefaultWriteConverter
()
{
Map
<
String
,
Converter
>
converterMap
=
new
HashMap
<
String
,
Converter
>(
16
);
putWriteConverter
(
converterMap
,
new
BigDecimalNumberConverter
());
putWriteConverter
(
converterMap
,
new
BooleanBooleanConverter
());
putWriteConverter
(
converterMap
,
new
ByteNumberConverter
());
putWriteConverter
(
converterMap
,
new
DateStringConverter
());
putWriteConverter
(
converterMap
,
new
DoubleNumberConverter
());
putWriteConverter
(
converterMap
,
new
FloatNumberConverter
());
putWriteConverter
(
converterMap
,
new
IntegerNumberConverter
());
putWriteConverter
(
converterMap
,
new
LongNumberConverter
());
putWriteConverter
(
converterMap
,
new
ShortNumberConverter
());
putWriteConverter
(
converterMap
,
new
StringStringConverter
());
return
converterMap
;
if
(
defaultWriteConverter
!=
null
)
{
return
defaultWriteConverter
;
}
defaultWriteConverter
=
new
HashMap
<
String
,
Converter
>(
16
);
putWriteConverter
(
new
BigDecimalNumberConverter
());
putWriteConverter
(
new
BooleanBooleanConverter
());
putWriteConverter
(
new
ByteNumberConverter
());
putWriteConverter
(
new
DateStringConverter
());
putWriteConverter
(
new
DoubleNumberConverter
());
putWriteConverter
(
new
FloatNumberConverter
());
putWriteConverter
(
new
IntegerNumberConverter
());
putWriteConverter
(
new
LongNumberConverter
());
putWriteConverter
(
new
ShortNumberConverter
());
putWriteConverter
(
new
StringStringConverter
());
return
defaultWriteConverter
;
}
private
static
void
putWriteConverter
(
Map
<
String
,
Converter
>
converterMap
,
Converter
converter
)
{
converterMap
.
put
(
ConverterKeyBuild
.
buildKey
(
converter
.
supportJavaTypeKey
()),
converter
);
private
static
void
putWriteConverter
(
Converter
converter
)
{
defaultWriteConverter
.
put
(
ConverterKeyBuild
.
buildKey
(
converter
.
supportJavaTypeKey
()),
converter
);
}
/**
...
...
@@ -70,51 +76,63 @@ public class DefaultConverterLoader {
* @return
*/
public
static
Map
<
String
,
Converter
>
loadDefaultReadConverter
()
{
Map
<
String
,
Converter
>
converterMap
=
new
HashMap
<
String
,
Converter
>(
64
);
putReadConverter
(
converterMap
,
new
BigDecimalBooleanConverter
());
putReadConverter
(
converterMap
,
new
BigDecimalNumberConverter
());
putReadConverter
(
converterMap
,
new
BigDecimalStringConverter
());
putReadConverter
(
converterMap
,
new
BooleanBooleanConverter
());
putReadConverter
(
converterMap
,
new
BooleanNumberConverter
());
putReadConverter
(
converterMap
,
new
BooleanStringConverter
());
putReadConverter
(
converterMap
,
new
ByteBooleanConverter
());
putReadConverter
(
converterMap
,
new
ByteNumberConverter
());
putReadConverter
(
converterMap
,
new
ByteStringConverter
());
putReadConverter
(
converterMap
,
new
DateNumberConverter
());
putReadConverter
(
converterMap
,
new
DateStringConverter
());
putReadConverter
(
converterMap
,
new
DoubleBooleanConverter
());
putReadConverter
(
converterMap
,
new
DoubleNumberConverter
());
putReadConverter
(
converterMap
,
new
DoubleStringConverter
());
putReadConverter
(
converterMap
,
new
FloatBooleanConverter
());
putReadConverter
(
converterMap
,
new
FloatNumberConverter
());
putReadConverter
(
converterMap
,
new
FloatStringConverter
());
putReadConverter
(
converterMap
,
new
IntegerBooleanConverter
());
putReadConverter
(
converterMap
,
new
IntegerNumberConverter
());
putReadConverter
(
converterMap
,
new
IntegerStringConverter
());
putReadConverter
(
converterMap
,
new
LongBooleanConverter
());
putReadConverter
(
converterMap
,
new
LongNumberConverter
());
putReadConverter
(
converterMap
,
new
LongStringConverter
());
putReadConverter
(
converterMap
,
new
ShortBooleanConverter
());
putReadConverter
(
converterMap
,
new
ShortNumberConverter
());
putReadConverter
(
converterMap
,
new
ShortStringConverter
());
putReadConverter
(
converterMap
,
new
StringBooleanConverter
());
putReadConverter
(
converterMap
,
new
StringNumberConverter
());
putReadConverter
(
converterMap
,
new
StringStringConverter
());
putReadConverter
(
converterMap
,
new
StringErrorConverter
());
return
converterMap
;
return
loadAllConverter
();
}
/**
* Load all converter
*
* @return
*/
public
static
Map
<
String
,
Converter
>
loadAllConverter
()
{
if
(
allConverter
!=
null
)
{
return
allConverter
;
}
allConverter
=
new
HashMap
<
String
,
Converter
>(
64
);
putAllConverter
(
new
BigDecimalBooleanConverter
());
putAllConverter
(
new
BigDecimalNumberConverter
());
putAllConverter
(
new
BigDecimalStringConverter
());
putAllConverter
(
new
BooleanBooleanConverter
());
putAllConverter
(
new
BooleanNumberConverter
());
putAllConverter
(
new
BooleanStringConverter
());
putAllConverter
(
new
ByteBooleanConverter
());
putAllConverter
(
new
ByteNumberConverter
());
putAllConverter
(
new
ByteStringConverter
());
putAllConverter
(
new
DateNumberConverter
());
putAllConverter
(
new
DateStringConverter
());
putAllConverter
(
new
DoubleBooleanConverter
());
putAllConverter
(
new
DoubleNumberConverter
());
putAllConverter
(
new
DoubleStringConverter
());
putAllConverter
(
new
FloatBooleanConverter
());
putAllConverter
(
new
FloatNumberConverter
());
putAllConverter
(
new
FloatStringConverter
());
putAllConverter
(
new
IntegerBooleanConverter
());
putAllConverter
(
new
IntegerNumberConverter
());
putAllConverter
(
new
IntegerStringConverter
());
putAllConverter
(
new
LongBooleanConverter
());
putAllConverter
(
new
LongNumberConverter
());
putAllConverter
(
new
LongStringConverter
());
putAllConverter
(
new
ShortBooleanConverter
());
putAllConverter
(
new
ShortNumberConverter
());
putAllConverter
(
new
ShortStringConverter
());
putAllConverter
(
new
StringBooleanConverter
());
putAllConverter
(
new
StringNumberConverter
());
putAllConverter
(
new
StringStringConverter
());
putAllConverter
(
new
StringErrorConverter
());
return
allConverter
;
}
private
static
void
put
ReadConverter
(
Map
<
String
,
Converter
>
converterMap
,
Converter
converter
)
{
converterMap
.
put
(
ConverterKeyBuild
.
buildKey
(
converter
.
supportJavaTypeKey
(),
converter
.
supportExcelTypeKey
()),
private
static
void
put
AllConverter
(
Converter
converter
)
{
allConverter
.
put
(
ConverterKeyBuild
.
buildKey
(
converter
.
supportJavaTypeKey
(),
converter
.
supportExcelTypeKey
()),
converter
);
}
}
src/main/java/com/alibaba/excel/enums/WriteLastRowType.java
浏览文件 @
22dc33d4
...
...
@@ -7,11 +7,15 @@ package com.alibaba.excel.enums;
**/
public
enum
WriteLastRowType
{
/**
*
Tables
are created without templates ,And any data has been written;
*
Excel
are created without templates ,And any data has been written;
*/
EMPTY
,
COMMON_
EMPTY
,
/**
*
It's supposed to have data in it.Tables are created with templates ,or
any data has been written;
*
Excel are created with templates ,And
any data has been written;
*/
HAVE_DATA
,;
TEMPLATE_EMPTY
,
/**
* Any data has been written;
*/
HAS_DATA
,;
}
src/main/java/com/alibaba/excel/util/WorkBookUtil.java
浏览文件 @
22dc33d4
...
...
@@ -25,11 +25,20 @@ public class WorkBookUtil {
public
static
Workbook
createWorkBook
(
WriteWorkbookHolder
writeWorkbookHolder
)
throws
IOException
,
InvalidFormatException
{
if
(
ExcelTypeEnum
.
XLSX
.
equals
(
writeWorkbookHolder
.
getExcelType
()))
{
XSSFWorkbook
xssfWorkbook
=
null
;
if
(
writeWorkbookHolder
.
getTemplateFile
()
!=
null
)
{
return
new
SXSSFWorkbook
(
new
XSSFWorkbook
(
writeWorkbookHolder
.
getTemplateFile
()
));
xssfWorkbook
=
new
XSSFWorkbook
(
writeWorkbookHolder
.
getTemplateFile
(
));
}
if
(
writeWorkbookHolder
.
getTemplateInputStream
()
!=
null
)
{
return
new
SXSSFWorkbook
(
new
XSSFWorkbook
(
writeWorkbookHolder
.
getTemplateInputStream
()));
xssfWorkbook
=
new
XSSFWorkbook
(
writeWorkbookHolder
.
getTemplateInputStream
());
}
// When using SXSSFWorkbook, you can't get the actual last line.But we need to read the last line when we
// are using the template, so we cache it
if
(
xssfWorkbook
!=
null
)
{
for
(
int
i
=
0
;
i
<
xssfWorkbook
.
getNumberOfSheets
();
i
++)
{
writeWorkbookHolder
.
getTemplateLastRowMap
().
put
(
i
,
xssfWorkbook
.
getSheetAt
(
i
).
getLastRowNum
());
}
return
new
SXSSFWorkbook
(
xssfWorkbook
);
}
return
new
SXSSFWorkbook
(
500
);
}
...
...
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
浏览文件 @
22dc33d4
...
...
@@ -10,14 +10,12 @@ import java.util.Set;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.Row
;
import
org.apache.poi.ss.usermodel.Sheet
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
com.alibaba.excel.context.WriteContext
;
import
com.alibaba.excel.context.WriteContextImpl
;
import
com.alibaba.excel.converters.Converter
;
import
com.alibaba.excel.converters.ConverterKeyBuild
;
import
com.alibaba.excel.enums.WriteLastRowType
;
import
com.alibaba.excel.exception.ExcelDataConvertException
;
import
com.alibaba.excel.exception.ExcelGenerateException
;
import
com.alibaba.excel.metadata.BaseRowModel
;
...
...
@@ -64,22 +62,14 @@ public class ExcelBuilderImpl implements ExcelBuilder {
return
;
}
WriteSheetHolder
writeSheetHolder
=
context
.
writeSheetHolder
();
Sheet
currentSheet
=
writeSheetHolder
.
getSheet
();
int
lastRowNum
=
currentSheet
.
getLastRowNum
();
// 'lastRowNum' doesn't matter if it has one or zero,is's zero
if
(
lastRowNum
==
0
&&
WriteLastRowType
.
EMPTY
==
writeSheetHolder
.
getWriteLastRowType
())
{
lastRowNum
--;
}
if
(!
data
.
isEmpty
())
{
writeSheetHolder
.
setWriteLastRowType
(
WriteLastRowType
.
HAVE_DATA
);
}
int
newRowIndex
=
writeSheetHolder
.
getNewRowIndexAndStartDoWrite
();
if
(
writeSheetHolder
.
isNew
()
&&
!
writeSheetHolder
.
getExcelWriteHeadProperty
().
hasHead
())
{
lastRowNum
+=
context
.
currentWriteHolder
().
relativeHeadRowIndex
();
newRowIndex
+=
context
.
currentWriteHolder
().
relativeHeadRowIndex
();
}
// Bean
m
ap is out of order,so use fieldList
// Bean
M
ap is out of order,so use fieldList
List
<
Field
>
fieldList
=
new
ArrayList
<
Field
>();
for
(
int
relativeRowIndex
=
0
;
relativeRowIndex
<
data
.
size
();
relativeRowIndex
++)
{
int
n
=
relativeRowIndex
+
lastRowNum
+
1
;
int
n
=
relativeRowIndex
+
newRowIndex
;
addOneRowOfDataToExcel
(
data
.
get
(
relativeRowIndex
),
n
,
relativeRowIndex
,
fieldList
);
}
}
...
...
src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java
浏览文件 @
22dc33d4
...
...
@@ -13,21 +13,24 @@ import com.alibaba.excel.metadata.Head;
*/
public
class
LoopMergeStrategy
extends
AbstractMergeStrategy
{
private
int
eachRow
;
private
int
eachColumn
;
private
int
columnIndex
;
public
LoopMergeStrategy
(
int
eachRow
,
int
eachColumn
)
{
if
(
eachRow
<
1
||
eachColumn
<
1
)
{
throw
new
IllegalArgumentException
(
"All parameters must be greater than 1"
);
public
LoopMergeStrategy
(
int
eachRow
,
int
columnIndex
)
{
if
(
eachRow
<
1
)
{
throw
new
IllegalArgumentException
(
"EachRows must be greater than 1"
);
}
if
(
columnIndex
<
0
)
{
throw
new
IllegalArgumentException
(
"ColumnIndex must be greater than 0"
);
}
this
.
eachRow
=
eachRow
;
this
.
eachColumn
=
eachColumn
;
this
.
columnIndex
=
columnIndex
;
}
@Override
protected
void
merge
(
Sheet
sheet
,
Cell
cell
,
Head
head
,
int
relativeRowIndex
)
{
if
(
relativeRowIndex
%
eachRow
==
0
&&
head
.
getColumnIndex
()
%
eachColumn
==
0
)
{
if
(
head
.
getColumnIndex
()
==
columnIndex
&&
relativeRowIndex
%
eachRow
==
0
)
{
CellRangeAddress
cellRangeAddress
=
new
CellRangeAddress
(
cell
.
getRowIndex
(),
cell
.
getRowIndex
()
+
eachRow
-
1
,
cell
.
getColumnIndex
(),
cell
.
getColumnIndex
()
+
eachColumn
-
1
);
cell
.
getRowIndex
()
+
eachRow
-
1
,
cell
.
getColumnIndex
(),
cell
.
getColumnIndex
());
sheet
.
addMergedRegion
(
cellRangeAddress
);
}
}
...
...
src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java
浏览文件 @
22dc33d4
...
...
@@ -7,6 +7,7 @@ import org.apache.poi.ss.usermodel.Sheet;
import
com.alibaba.excel.enums.HolderEnum
;
import
com.alibaba.excel.enums.WriteLastRowType
;
import
com.alibaba.excel.support.ExcelTypeEnum
;
import
com.alibaba.excel.write.metadata.WriteSheet
;
/**
...
...
@@ -60,9 +61,9 @@ public class WriteSheetHolder extends AbstractWriteHolder {
this
.
parentWriteWorkbookHolder
=
writeWorkbookHolder
;
this
.
hasBeenInitializedTable
=
new
HashMap
<
Integer
,
WriteTableHolder
>();
if
(
writeWorkbookHolder
.
getTemplateInputStream
()
==
null
&&
writeWorkbookHolder
.
getTemplateFile
()
==
null
)
{
writeLastRowType
=
WriteLastRowType
.
EMPTY
;
writeLastRowType
=
WriteLastRowType
.
COMMON_
EMPTY
;
}
else
{
writeLastRowType
=
WriteLastRowType
.
HAVE_DATA
;
writeLastRowType
=
WriteLastRowType
.
TEMPLATE_EMPTY
;
}
}
...
...
@@ -122,6 +123,36 @@ public class WriteSheetHolder extends AbstractWriteHolder {
this
.
writeLastRowType
=
writeLastRowType
;
}
/**
* Get the last line of index,you have to make sure that the data is written next
*
* @return
*/
public
int
getNewRowIndexAndStartDoWrite
()
{
// 'getLastRowNum' doesn't matter if it has one or zero,is's zero
int
newRowIndex
=
0
;
switch
(
writeLastRowType
)
{
case
TEMPLATE_EMPTY:
if
(
parentWriteWorkbookHolder
.
getExcelType
()
==
ExcelTypeEnum
.
XLSX
)
{
if
(
parentWriteWorkbookHolder
.
getTemplateLastRowMap
().
containsKey
(
sheetNo
))
{
newRowIndex
=
parentWriteWorkbookHolder
.
getTemplateLastRowMap
().
get
(
sheetNo
);
}
}
else
{
newRowIndex
=
sheet
.
getLastRowNum
();
}
newRowIndex
++;
break
;
case
HAS_DATA:
newRowIndex
=
sheet
.
getLastRowNum
();
newRowIndex
++;
break
;
default
:
break
;
}
writeLastRowType
=
WriteLastRowType
.
HAS_DATA
;
return
newRowIndex
;
}
@Override
public
HolderEnum
holderType
()
{
return
HolderEnum
.
SHEET
;
...
...
src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
浏览文件 @
22dc33d4
...
...
@@ -72,6 +72,11 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
* prevent duplicate creation of sheet objects
*/
private
Map
<
Integer
,
WriteSheetHolder
>
hasBeenInitializedSheet
;
/**
* When using SXSSFWorkbook, you can't get the actual last line.But we need to read the last line when we are using
* the template, so we cache it
*/
private
Map
<
Integer
,
Integer
>
templateLastRowMap
;
public
WriteWorkbookHolder
(
WriteWorkbook
writeWorkbook
)
{
super
(
writeWorkbook
,
null
,
writeWorkbook
.
getConvertAllFiled
());
...
...
@@ -114,6 +119,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
this
.
mandatoryUseInputStream
=
writeWorkbook
.
getMandatoryUseInputStream
();
}
this
.
hasBeenInitializedSheet
=
new
HashMap
<
Integer
,
WriteSheetHolder
>();
this
.
templateLastRowMap
=
new
HashMap
<
Integer
,
Integer
>(
8
);
}
public
Workbook
getWorkbook
()
{
...
...
@@ -196,6 +202,14 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
this
.
mandatoryUseInputStream
=
mandatoryUseInputStream
;
}
public
Map
<
Integer
,
Integer
>
getTemplateLastRowMap
()
{
return
templateLastRowMap
;
}
public
void
setTemplateLastRowMap
(
Map
<
Integer
,
Integer
>
templateLastRowMap
)
{
this
.
templateLastRowMap
=
templateLastRowMap
;
}
@Override
public
HolderEnum
holderType
()
{
return
HolderEnum
.
WORKBOOK
;
...
...
src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java
浏览文件 @
22dc33d4
...
...
@@ -7,9 +7,13 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
com.alibaba.excel.annotation.format.NumberFormat
;
import
com.alibaba.excel.annotation.write.style.ColumnWidth
;
import
com.alibaba.excel.annotation.write.style.ContentRowHeight
;
import
com.alibaba.excel.annotation.write.style.HeadRowHeight
;
import
com.alibaba.excel.converters.ConverterKeyBuild
;
import
com.alibaba.excel.converters.DefaultConverterLoader
;
import
com.alibaba.excel.enums.CellDataTypeEnum
;
import
com.alibaba.excel.enums.HeadKindEnum
;
import
com.alibaba.excel.metadata.CellRange
;
import
com.alibaba.excel.metadata.Head
;
...
...
@@ -48,8 +52,16 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty {
columnWidth
=
parentColumnWidth
;
}
headData
.
setColumnWidthProperty
(
ColumnWidthProperty
.
build
(
columnWidth
));
}
// If have @NumberFormat, 'NumberStringConverter' is specified by default
if
(
excelContentPropertyData
.
getConverter
()
==
null
)
{
NumberFormat
numberFormat
=
field
.
getAnnotation
(
NumberFormat
.
class
);
if
(
numberFormat
!=
null
)
{
excelContentPropertyData
.
setConverter
(
DefaultConverterLoader
.
loadAllConverter
()
.
get
(
ConverterKeyBuild
.
buildKey
(
field
.
getType
(),
CellDataTypeEnum
.
STRING
)));
}
}
}
}
public
RowHeightProperty
getHeadRowHeightProperty
()
{
...
...
src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataTest.java
浏览文件 @
22dc33d4
...
...
@@ -42,14 +42,14 @@ public class TemplateDataTest {
EasyExcel
.
write
(
file
,
TemplateData
.
class
)
.
withTemplate
(
TestFileUtil
.
readFile
(
"template"
+
File
.
separator
+
"template07.xlsx"
)).
sheet
()
.
doWrite
(
data
());
EasyExcel
.
read
(
file
,
TemplateData
.
class
,
new
TemplateDataListener
()).
headRowNumber
(
2
).
sheet
().
doRead
();
EasyExcel
.
read
(
file
,
TemplateData
.
class
,
new
TemplateDataListener
()).
headRowNumber
(
3
).
sheet
().
doRead
();
}
private
void
readAndWrite03
(
File
file
)
{
EasyExcel
.
write
(
file
,
TemplateData
.
class
)
.
withTemplate
(
TestFileUtil
.
readFile
(
"template"
+
File
.
separator
+
"template03.xls"
)).
sheet
()
.
doWrite
(
data
());
EasyExcel
.
read
(
file
,
TemplateData
.
class
,
new
TemplateDataListener
()).
headRowNumber
(
2
).
sheet
().
doRead
();
EasyExcel
.
read
(
file
,
TemplateData
.
class
,
new
TemplateDataListener
()).
headRowNumber
(
3
).
sheet
().
doRead
();
}
private
List
<
TemplateData
>
data
()
{
...
...
src/test/java/com/alibaba/easyexcel/test/demo/poi/PoiTest.java
0 → 100644
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.poi
;
import
java.io.File
;
import
java.io.IOException
;
import
org.apache.poi.xssf.streaming.SXSSFRow
;
import
org.apache.poi.xssf.streaming.SXSSFSheet
;
import
org.apache.poi.xssf.streaming.SXSSFWorkbook
;
import
org.apache.poi.xssf.usermodel.XSSFRow
;
import
org.apache.poi.xssf.usermodel.XSSFSheet
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.alibaba.easyexcel.test.util.TestFileUtil
;
/**
* 测试poi
*
* @author Jiaju Zhuang
**/
@Ignore
public
class
PoiTest
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PoiTest
.
class
);
@Test
public
void
lastRowNum
()
throws
IOException
{
String
file
=
TestFileUtil
.
getPath
()
+
"demo"
+
File
.
separator
+
"demo.xlsx"
;
SXSSFWorkbook
xssfWorkbook
=
new
SXSSFWorkbook
(
new
XSSFWorkbook
(
file
));
SXSSFSheet
xssfSheet
=
xssfWorkbook
.
getSheetAt
(
0
);
LOGGER
.
info
(
"一共行数:{}"
,
xssfSheet
.
getLastRowNum
());
SXSSFRow
row
=
xssfSheet
.
getRow
(
0
);
LOGGER
.
info
(
"第一行数据:{}"
,
row
);
xssfSheet
.
createRow
(
20
);
LOGGER
.
info
(
"一共行数:{}"
,
xssfSheet
.
getLastRowNum
());
}
@Test
public
void
lastRowNumXSSF
()
throws
IOException
{
String
file
=
TestFileUtil
.
getPath
()
+
"demo"
+
File
.
separator
+
"demo.xlsx"
;
XSSFWorkbook
xssfWorkbook
=
new
XSSFWorkbook
(
file
);
LOGGER
.
info
(
"一共:{}个sheet"
,
xssfWorkbook
.
getNumberOfSheets
());
XSSFSheet
xssfSheet
=
xssfWorkbook
.
getSheetAt
(
0
);
LOGGER
.
info
(
"一共行数:{}"
,
xssfSheet
.
getLastRowNum
());
XSSFRow
row
=
xssfSheet
.
getRow
(
0
);
LOGGER
.
info
(
"第一行数据:{}"
,
row
);
xssfSheet
.
createRow
(
20
);
LOGGER
.
info
(
"一共行数:{}"
,
xssfSheet
.
getLastRowNum
());
}
}
src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
浏览文件 @
22dc33d4
...
...
@@ -13,6 +13,8 @@ import com.alibaba.easyexcel.test.util.TestFileUtil;
import
com.alibaba.excel.EasyExcelFactory
;
import
com.alibaba.excel.ExcelReader
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
com.alibaba.excel.annotation.format.DateTimeFormat
;
import
com.alibaba.excel.annotation.format.NumberFormat
;
import
com.alibaba.excel.converters.DefaultConverterLoader
;
import
com.alibaba.excel.read.metadata.ReadSheet
;
import
com.alibaba.fastjson.JSON
;
...
...
@@ -50,7 +52,10 @@ public class ReadTest {
/**
* 指定列的下标或者列名
* <li>使用{@link com.alibaba.excel.annotation.ExcelProperty}注解即可
*
* <li>1. 创建excel对应的实体对象,并使用{@link ExcelProperty}注解. 参照{@link IndexOrNameData}
* <li>2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link IndexOrNameDataListener}
* <li>3. 直接读即可
*/
@Test
public
void
indexOrNameRead
()
{
...
...
@@ -78,10 +83,10 @@ public class ReadTest {
}
/**
* 日期、数字或者自定义格式转换
。
* 日期、数字或者自定义格式转换
* <p>
* 默认读的转换器{@link DefaultConverterLoader#loadDefaultReadConverter()}
* <li>1. 创建excel对应的实体对象 参照{@link ConverterData}.里面可以使用注解
.
* <li>1. 创建excel对应的实体对象 参照{@link ConverterData}.里面可以使用注解
{@link DateTimeFormat}、{@link NumberFormat}或者自定义注解
* <li>2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link ConverterDataListener}
* <li>3. 直接读即可
*/
...
...
@@ -98,7 +103,7 @@ public class ReadTest {
}
/**
* 多行头
.
* 多行头
*
* <li>1. 创建excel对应的实体对象 参照{@link DemoData}
* <li>2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
...
...
@@ -134,7 +139,6 @@ public class ReadTest {
Map
<
Integer
,
String
>
data
=
(
Map
<
Integer
,
String
>)
obj
;
LOGGER
.
info
(
"读取到数据:{}"
,
JSON
.
toJSONString
(
data
));
}
}
}
src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
浏览文件 @
22dc33d4
...
...
@@ -26,7 +26,7 @@ public class WebTest {
* 文件下载
* <li>1. 创建excel对应的实体对象 参照{@link DownloadData}
* <li>2. 设置返回的 参数
* <li>3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭
异常
问题不大
* <li>3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭
流
问题不大
*/
@GetMapping
(
"download"
)
public
void
download
(
HttpServletResponse
response
)
throws
IOException
{
...
...
src/test/java/com/alibaba/easyexcel/test/demo/write/ComplexHeadData.java
0 → 100644
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.write
;
import
java.util.Date
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.Data
;
/**
* 复杂头数据.这里最终效果是第一行就一个主标题,第二行分类
*
* @author Jiaju Zhuang
**/
@Data
public
class
ComplexHeadData
{
@ExcelProperty
({
"主标题"
,
"字符串标题"
})
private
String
string
;
@ExcelProperty
({
"主标题"
,
"日期标题"
})
private
Date
date
;
@ExcelProperty
({
"主标题"
,
"数字标题"
})
private
Double
doubleData
;
}
src/test/java/com/alibaba/easyexcel/test/demo/write/ConverterData.java
0 → 100644
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.write
;
import
java.util.Date
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
com.alibaba.excel.annotation.format.DateTimeFormat
;
import
com.alibaba.excel.annotation.format.NumberFormat
;
import
lombok.Data
;
/**
* 基础数据类.这里的排序和excel里面的排序一致
*
* @author Jiaju Zhuang
**/
@Data
public
class
ConverterData
{
/**
* 我想所有的 字符串起前面加上"自定义:"三个字
*/
@ExcelProperty
(
value
=
"字符串标题"
,
converter
=
CustomStringStringConverter
.
class
)
private
String
string
;
/**
* 我想写到excel 用年月日的格式
*/
@DateTimeFormat
(
"yyyy年MM月dd日HH时mm分ss秒"
)
@ExcelProperty
(
"日期标题"
)
private
Date
date
;
/**
* 我想写到excel 用百分比表示
*/
@NumberFormat
(
"#.##%"
)
@ExcelProperty
(
value
=
"数字标题"
)
private
Double
doubleData
;
}
src/test/java/com/alibaba/easyexcel/test/demo/write/CustomStringStringConverter.java
0 → 100644
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.write
;
import
com.alibaba.excel.converters.Converter
;
import
com.alibaba.excel.enums.CellDataTypeEnum
;
import
com.alibaba.excel.metadata.CellData
;
import
com.alibaba.excel.metadata.GlobalConfiguration
;
import
com.alibaba.excel.metadata.property.ExcelContentProperty
;
/**
* String and string converter
*
* @author Jiaju Zhuang
*/
public
class
CustomStringStringConverter
implements
Converter
<
String
>
{
@Override
public
Class
supportJavaTypeKey
()
{
return
String
.
class
;
}
@Override
public
CellDataTypeEnum
supportExcelTypeKey
()
{
return
CellDataTypeEnum
.
STRING
;
}
/**
* 这里是读的时候会调用 不用管
*
* @param cellData
* NotNull
* @param contentProperty
* Nullable
* @param globalConfiguration
* NotNull
* @return
*/
@Override
public
String
convertToJavaData
(
CellData
cellData
,
ExcelContentProperty
contentProperty
,
GlobalConfiguration
globalConfiguration
)
{
return
cellData
.
getStringValue
();
}
/**
* 这里是写的时候会调用 不用管
*
* @param value
* NotNull
* @param contentProperty
* Nullable
* @param globalConfiguration
* NotNull
* @return
*/
@Override
public
CellData
convertToExcelData
(
String
value
,
ExcelContentProperty
contentProperty
,
GlobalConfiguration
globalConfiguration
)
{
return
new
CellData
(
"自定义:"
+
value
);
}
}
src/test/java/com/alibaba/easyexcel/test/demo/write/IndexData.java
0 → 100644
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.write
;
import
java.util.Date
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.Data
;
/**
* 基础数据类
*
* @author Jiaju Zhuang
**/
@Data
public
class
IndexData
{
@ExcelProperty
(
value
=
"字符串标题"
,
index
=
0
)
private
String
string
;
@ExcelProperty
(
value
=
"日期标题"
,
index
=
1
)
private
Date
date
;
/**
* 这里设置3 会导致第二列空的
*/
@ExcelProperty
(
value
=
"数字标题"
,
index
=
3
)
private
Double
doubleData
;
}
src/test/java/com/alibaba/easyexcel/test/demo/write/WidthAndHeightData.java
0 → 100644
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.write
;
import
java.util.Date
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
com.alibaba.excel.annotation.write.style.ColumnWidth
;
import
com.alibaba.excel.annotation.write.style.ContentRowHeight
;
import
com.alibaba.excel.annotation.write.style.HeadRowHeight
;
import
lombok.Data
;
/**
* 基础数据类
*
* @author Jiaju Zhuang
**/
@Data
@ContentRowHeight
(
10
)
@HeadRowHeight
(
20
)
@ColumnWidth
(
25
)
public
class
WidthAndHeightData
{
@ExcelProperty
(
"字符串标题"
)
private
String
string
;
@ExcelProperty
(
"日期标题"
)
private
Date
date
;
/**
* 宽度为50
*/
@ColumnWidth
(
50
)
@ExcelProperty
(
"数字标题"
)
private
Double
doubleData
;
}
src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
浏览文件 @
22dc33d4
package
com.alibaba.easyexcel.test.demo.write
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
org.apache.poi.ss.usermodel.FillPatternType
;
import
org.apache.poi.ss.usermodel.IndexedColors
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
com.alibaba.easyexcel.test.util.TestFileUtil
;
import
com.alibaba.excel.EasyExcelFactory
;
import
com.alibaba.excel.ExcelWriter
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
com.alibaba.excel.annotation.format.DateTimeFormat
;
import
com.alibaba.excel.annotation.format.NumberFormat
;
import
com.alibaba.excel.annotation.write.style.ColumnWidth
;
import
com.alibaba.excel.annotation.write.style.ContentRowHeight
;
import
com.alibaba.excel.annotation.write.style.HeadRowHeight
;
import
com.alibaba.excel.write.merge.LoopMergeStrategy
;
import
com.alibaba.excel.write.metadata.WriteSheet
;
import
com.alibaba.excel.write.metadata.WriteTable
;
import
com.alibaba.excel.write.metadata.style.WriteCellStyle
;
import
com.alibaba.excel.write.metadata.style.WriteFont
;
import
com.alibaba.excel.write.style.HorizontalCellStyleStrategy
;
/**
* 写的常见写法
...
...
@@ -21,19 +35,19 @@ import com.alibaba.excel.write.metadata.WriteSheet;
public
class
WriteTest
{
/**
* 最简单的写
* <li>1. 创建excel对应的实体对象 参照{@link
com.alibaba.easyexcel.test.demo.write.
DemoData}
* <li>1. 创建excel对应的实体对象 参照{@link DemoData}
* <li>2. 直接写即可
*/
@Test
public
void
simpleWrite
()
{
// 写法1
String
fileName
=
TestFileUtil
.
getPath
()
+
"
w
rite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
String
fileName
=
TestFileUtil
.
getPath
()
+
"
simpleW
rite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
sheet
(
"模板"
).
doWrite
(
data
());
// 写法2
fileName
=
TestFileUtil
.
getPath
()
+
"
w
rite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
fileName
=
TestFileUtil
.
getPath
()
+
"
simpleW
rite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读
ExcelWriter
excelWriter
=
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
build
();
WriteSheet
writeSheet
=
EasyExcelFactory
.
writerSheet
(
"模板"
).
build
();
...
...
@@ -42,12 +56,175 @@ public class WriteTest {
excelWriter
.
finish
();
}
/**
* 指定写入的列
* <li>1. 创建excel对应的实体对象 参照{@link IndexData}
* <li>2. 使用{@link ExcelProperty}注解指定写入的列
* <li>3. 直接写即可
*/
@Test
public
void
indexWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"indexWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
IndexData
.
class
).
sheet
(
"模板"
).
doWrite
(
data
());
}
/**
* 复杂头写入 指定写入的列
* <li>1. 创建excel对应的实体对象 参照{@link ComplexHeadData}
* <li>2. 使用{@link ExcelProperty}注解指定复杂的头
* <li>3. 直接写即可
*/
@Test
public
void
complexHeadWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"complexHeadWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
ComplexHeadData
.
class
).
sheet
(
"模板"
).
doWrite
(
data
());
}
/**
* 重复多次写入
* <li>1. 创建excel对应的实体对象 参照{@link ComplexHeadData}
* <li>2. 使用{@link ExcelProperty}注解指定复杂的头
* <li>3. 直接调用二次写入即可
*/
@Test
public
void
repeatedWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"repeatedWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读
ExcelWriter
excelWriter
=
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
build
();
WriteSheet
writeSheet
=
EasyExcelFactory
.
writerSheet
(
"模板"
).
build
();
// 第一次写入会创建头
excelWriter
.
write
(
data
(),
writeSheet
);
// 第二次写入会在上一次写入的最后一行后面写入
excelWriter
.
write
(
data
(),
writeSheet
);
/// 千万别忘记finish 会帮忙关闭流
excelWriter
.
finish
();
}
/**
* 日期、数字或者自定义格式转换。
* <li>1. 创建excel对应的实体对象 参照{@link ConverterData}
* <li>2. 使用{@link ExcelProperty}配合使用注解{@link DateTimeFormat}、{@link NumberFormat}或者自定义注解
* <li>3. 直接写即可
*/
@Test
public
void
converterWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"converterWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
ConverterData
.
class
).
sheet
(
"模板"
).
doWrite
(
data
());
}
/**
* 指定写入的列
* <li>1. 创建excel对应的实体对象 参照{@link IndexData}
* <li>2. 使用{@link ExcelProperty}注解指定写入的列
* <li>3. 使用withTemplate 读取模板
* <li>4. 直接写即可
*/
@Test
public
void
templateWrite
()
{
String
templateFileName
=
TestFileUtil
.
getPath
()
+
"demo"
+
File
.
separator
+
"demo.xlsx"
;
String
fileName
=
TestFileUtil
.
getPath
()
+
"templateWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
withTemplate
(
templateFileName
).
sheet
().
doWrite
(
data
());
}
/**
* 列宽、行高
* <li>1. 创建excel对应的实体对象 参照{@link WidthAndHeightData}
* <li>2. 使用注解{@link ColumnWidth}、{@link HeadRowHeight}、{@link ContentRowHeight}指定宽度或高度
* <li>3. 直接写即可
*/
@Test
public
void
widthAndHeightWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"widthAndHeightWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
WidthAndHeightData
.
class
).
sheet
(
"模板"
).
doWrite
(
data
());
}
/**
* 自定义样式
* <li>1. 创建excel对应的实体对象 参照{@link DemoData}
* <li>2. 创建一个style策略 并注册
* <li>3. 直接写即可
*/
@Test
public
void
styleWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"styleWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 头的策略
WriteCellStyle
headWriteCellStyle
=
new
WriteCellStyle
();
// 背景设置为红色
headWriteCellStyle
.
setFillForegroundColor
(
IndexedColors
.
RED
.
getIndex
());
WriteFont
headWriteFont
=
new
WriteFont
();
headWriteFont
.
setFontHeightInPoints
((
short
)
20
);
headWriteCellStyle
.
setWriteFont
(
headWriteFont
);
// 内容的策略
WriteCellStyle
contentWriteCellStyle
=
new
WriteCellStyle
();
// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
contentWriteCellStyle
.
setFillPatternType
(
FillPatternType
.
SOLID_FOREGROUND
);
// 背景绿色
contentWriteCellStyle
.
setFillForegroundColor
(
IndexedColors
.
GREEN
.
getIndex
());
WriteFont
contentWriteFont
=
new
WriteFont
();
// 字体大小
contentWriteFont
.
setFontHeightInPoints
((
short
)
20
);
contentWriteCellStyle
.
setWriteFont
(
contentWriteFont
);
// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
HorizontalCellStyleStrategy
horizontalCellStyleStrategy
=
new
HorizontalCellStyleStrategy
(
headWriteCellStyle
,
contentWriteCellStyle
);
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
registerWriteHandler
(
horizontalCellStyleStrategy
).
sheet
(
"模板"
)
.
doWrite
(
data
());
}
/**
* 合并单元格
* <li>1. 创建excel对应的实体对象 参照{@link DemoData}
* <li>2. 创建一个merge策略 并注册
* <li>3. 直接写即可
*/
@Test
public
void
mergeWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"mergeWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 每隔2行会合并 把eachColumn 设置成 3 也就是我们数据的长度,所以就第一列会合并。当然其他合并策略也可以自己写
LoopMergeStrategy
loopMergeStrategy
=
new
LoopMergeStrategy
(
2
,
0
);
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
registerWriteHandler
(
loopMergeStrategy
).
sheet
(
"模板"
)
.
doWrite
(
data
());
}
/**
* 使用table去写入
* <li>1. 创建excel对应的实体对象 参照{@link DemoData}
* <li>2. 然后写入table即可
*/
@Test
public
void
tableWrite
()
{
String
fileName
=
TestFileUtil
.
getPath
()
+
"tableWrite"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里直接写多个table的案例了,如果只有一个 也可以直一行代码搞定,参照其他案例
// 这里 需要指定写用哪个class去读
ExcelWriter
excelWriter
=
EasyExcelFactory
.
write
(
fileName
,
DemoData
.
class
).
build
();
// 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了
WriteSheet
writeSheet
=
EasyExcelFactory
.
writerSheet
(
"模板"
).
needHead
(
Boolean
.
FALSE
).
build
();
// 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要
WriteTable
writeTable0
=
EasyExcelFactory
.
writerTable
(
0
).
needHead
(
Boolean
.
TRUE
).
build
();
WriteTable
writeTable1
=
EasyExcelFactory
.
writerTable
(
1
).
needHead
(
Boolean
.
TRUE
).
build
();
// 第一次写入会创建头
excelWriter
.
write
(
data
(),
writeSheet
,
writeTable0
);
// 第二次写如也会创建头,然后在第一次的后面写入数据
excelWriter
.
write
(
data
(),
writeSheet
,
writeTable1
);
/// 千万别忘记finish 会帮忙关闭流
excelWriter
.
finish
();
}
private
List
<
DemoData
>
data
()
{
List
<
DemoData
>
list
=
new
ArrayList
<
DemoData
>();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
DemoData
data
=
new
DemoData
();
data
.
setString
(
"字符串"
+
0
);
data
.
setString
(
"字符串"
+
i
);
data
.
setDate
(
new
Date
());
data
.
setDoubleData
(
0.56
);
list
.
add
(
data
);
...
...
src/test/resources/demo/demo.xlsx
浏览文件 @
22dc33d4
无法预览此类型文件
src/test/resources/template/template03.xls
浏览文件 @
22dc33d4
无法预览此类型文件
src/test/resources/template/template07.xlsx
浏览文件 @
22dc33d4
无法预览此类型文件
update.md
浏览文件 @
22dc33d4
...
...
@@ -3,6 +3,8 @@
*
优化读写对外接口
*
加入转换器,方便格式转换
*
极大优化读大文件的内存和效率
*
sheetNo 改成0开始
*
读支持指定列名
# 1.2.4
修复read()方法存在的bug
# 1.2.1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录