Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
金手指1668
easyexcel
提交
cba3a9ce
E
easyexcel
项目概览
金手指1668
/
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,发现更多精彩内容 >>
提交
cba3a9ce
编写于
11月 04, 2019
作者:
庄家钜
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
加入解析class缓存
上级
b72fc513
变更
26
隐藏空白更改
内联
并排
Showing
26 changed file
with
450 addition
and
113 deletion
+450
-113
pom.xml
pom.xml
+1
-1
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
...n/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
+2
-0
src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java
...ibaba/excel/analysis/v03/handlers/IndexRecordHandler.java
+42
-0
src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java
...baba/excel/analysis/v07/handlers/CountRowCellHandler.java
+2
-2
src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
...n/java/com/alibaba/excel/event/AnalysisEventListener.java
+1
-1
src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
...om/alibaba/excel/exception/ExcelDataConvertException.java
+19
-16
src/main/java/com/alibaba/excel/metadata/CellData.java
src/main/java/com/alibaba/excel/metadata/CellData.java
+5
-2
src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
...om/alibaba/excel/metadata/property/ExcelHeadProperty.java
+3
-43
src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
.../alibaba/excel/read/listener/ModelBuildEventListener.java
+2
-1
src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
...libaba/excel/read/metadata/holder/AbstractReadHolder.java
+1
-2
src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java
...m/alibaba/excel/read/metadata/holder/ReadSheetHolder.java
+22
-6
src/main/java/com/alibaba/excel/util/ClassUtils.java
src/main/java/com/alibaba/excel/util/ClassUtils.java
+150
-0
src/main/java/com/alibaba/excel/util/ConverterUtils.java
src/main/java/com/alibaba/excel/util/ConverterUtils.java
+11
-8
src/main/java/com/alibaba/excel/util/DateUtils.java
src/main/java/com/alibaba/excel/util/DateUtils.java
+1
-1
src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
...baba/excel/write/executor/AbstractExcelWriteExecutor.java
+10
-6
src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
...m/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
+5
-13
src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
.../alibaba/excel/write/executor/ExcelWriteFillExecutor.java
+35
-3
src/main/java/com/alibaba/excel/write/metadata/fill/AnalysisCell.java
...a/com/alibaba/excel/write/metadata/fill/AnalysisCell.java
+9
-0
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java
...ibaba/easyexcel/test/demo/read/DemoExceptionListener.java
+2
-2
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java
...libaba/easyexcel/test/demo/read/DemoHeadDataListener.java
+2
-2
src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java
...st/java/com/alibaba/easyexcel/test/temp/FillTempTest.java
+110
-0
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
...est/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
+2
-2
src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java
...java/com/alibaba/easyexcel/test/temp/read/HDListener.java
+1
-0
src/test/java/com/alibaba/easyexcel/test/temp/read/HeadReadData.java
...va/com/alibaba/easyexcel/test/temp/read/HeadReadData.java
+2
-0
src/test/java/com/alibaba/easyexcel/test/temp/read/HeadReadTest.java
...va/com/alibaba/easyexcel/test/temp/read/HeadReadTest.java
+5
-2
update.md
update.md
+5
-0
未找到文件。
pom.xml
浏览文件 @
cba3a9ce
...
...
@@ -4,7 +4,7 @@
<modelVersion>
4.0.0
</modelVersion>
<groupId>
com.alibaba
</groupId>
<artifactId>
easyexcel
</artifactId>
<version>
2.1.
0-beta4
</version>
<version>
2.1.
1
</version>
<packaging>
jar
</packaging>
<name>
easyexcel
</name>
...
...
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
浏览文件 @
cba3a9ce
...
...
@@ -27,6 +27,7 @@ import com.alibaba.excel.analysis.ExcelReadExecutor;
import
com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler
;
import
com.alibaba.excel.analysis.v03.handlers.BofRecordHandler
;
import
com.alibaba.excel.analysis.v03.handlers.FormulaRecordHandler
;
import
com.alibaba.excel.analysis.v03.handlers.IndexRecordHandler
;
import
com.alibaba.excel.analysis.v03.handlers.LabelRecordHandler
;
import
com.alibaba.excel.analysis.v03.handlers.MissingCellDummyRecordHandler
;
import
com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler
;
...
...
@@ -211,6 +212,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
recordHandlers
.
add
(
new
RkRecordHandler
());
recordHandlers
.
add
(
new
SstRecordHandler
());
recordHandlers
.
add
(
new
MissingCellDummyRecordHandler
());
recordHandlers
.
add
(
new
IndexRecordHandler
(
analysisContext
));
Collections
.
sort
(
recordHandlers
);
}
...
...
src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java
0 → 100644
浏览文件 @
cba3a9ce
package
com.alibaba.excel.analysis.v03.handlers
;
import
org.apache.poi.hssf.record.IndexRecord
;
import
org.apache.poi.hssf.record.Record
;
import
com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler
;
import
com.alibaba.excel.context.AnalysisContext
;
/**
* Record handler
*
* @author Jiaju Zhuang
*/
public
class
IndexRecordHandler
extends
AbstractXlsRecordHandler
{
private
AnalysisContext
context
;
public
IndexRecordHandler
(
AnalysisContext
context
)
{
this
.
context
=
context
;
}
@Override
public
boolean
support
(
Record
record
)
{
return
record
instanceof
IndexRecord
;
}
@Override
public
void
init
()
{}
@Override
public
void
processRecord
(
Record
record
)
{
if
(
context
.
readSheetHolder
()
==
null
)
{
return
;
}
context
.
readSheetHolder
().
setApproximateTotalRowNumber
(((
IndexRecord
)
record
).
getLastRowAdd1
());
}
@Override
public
int
getOrder
()
{
return
1
;
}
}
src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java
浏览文件 @
cba3a9ce
...
...
@@ -10,7 +10,7 @@ import com.alibaba.excel.context.AnalysisContext;
/**
* Cell Handler
*
*
* @author jipengfei
*/
public
class
CountRowCellHandler
implements
XlsxCellHandler
{
...
...
@@ -31,7 +31,7 @@ public class CountRowCellHandler implements XlsxCellHandler {
String
d
=
attributes
.
getValue
(
DIMENSION_REF
);
String
totalStr
=
d
.
substring
(
d
.
indexOf
(
":"
)
+
1
,
d
.
length
());
String
c
=
totalStr
.
toUpperCase
().
replaceAll
(
"[A-Z]"
,
""
);
analysisContext
.
readSheetHolder
().
set
Total
(
Integer
.
parseInt
(
c
));
analysisContext
.
readSheetHolder
().
set
ApproximateTotalRowNumber
(
Integer
.
parseInt
(
c
));
}
@Override
...
...
src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
浏览文件 @
cba3a9ce
...
...
@@ -16,7 +16,7 @@ public abstract class AnalysisEventListener<T> implements ReadListener<T> {
@Override
public
void
invokeHead
(
Map
<
Integer
,
CellData
>
headMap
,
AnalysisContext
context
)
{
invokeHeadMap
(
ConverterUtils
.
convertToStringMap
(
headMap
,
context
.
currentReadHolder
()
),
context
);
invokeHeadMap
(
ConverterUtils
.
convertToStringMap
(
headMap
,
context
),
context
);
}
/**
...
...
src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
浏览文件 @
cba3a9ce
package
com.alibaba.excel.exception
;
import
com.alibaba.excel.metadata.CellData
;
import
com.alibaba.excel.metadata.property.ExcelContentProperty
;
import
com.alibaba.excel.write.builder.ExcelWriterBuilder
;
...
...
@@ -17,6 +18,10 @@ public class ExcelDataConvertException extends RuntimeException {
* NotNull.
*/
private
Integer
columnIndex
;
/**
* NotNull.
*/
private
CellData
cellData
;
/**
* Nullable.Only when the header is configured and when the class header is used is not null.
*
...
...
@@ -24,34 +29,24 @@ public class ExcelDataConvertException extends RuntimeException {
*/
private
ExcelContentProperty
excelContentProperty
;
public
ExcelDataConvertException
(
String
message
)
{
super
(
message
);
}
public
ExcelDataConvertException
(
Integer
rowIndex
,
Integer
columnIndex
,
ExcelContentProperty
excelContentProperty
,
String
message
)
{
public
ExcelDataConvertException
(
Integer
rowIndex
,
Integer
columnIndex
,
CellData
cellData
,
ExcelContentProperty
excelContentProperty
,
String
message
)
{
super
(
message
);
this
.
rowIndex
=
rowIndex
;
this
.
columnIndex
=
columnIndex
;
this
.
cellData
=
cellData
;
this
.
excelContentProperty
=
excelContentProperty
;
}
public
ExcelDataConvertException
(
Integer
rowIndex
,
Integer
columnIndex
,
ExcelContentProperty
excelContentProperty
,
String
message
,
Throwable
cause
)
{
public
ExcelDataConvertException
(
Integer
rowIndex
,
Integer
columnIndex
,
CellData
cellData
,
ExcelContentProperty
excelContentProperty
,
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
this
.
rowIndex
=
rowIndex
;
this
.
columnIndex
=
columnIndex
;
this
.
cellData
=
cellData
;
this
.
excelContentProperty
=
excelContentProperty
;
}
public
ExcelDataConvertException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
ExcelDataConvertException
(
Throwable
cause
)
{
super
(
cause
);
}
public
Integer
getRowIndex
()
{
return
rowIndex
;
}
...
...
@@ -75,4 +70,12 @@ public class ExcelDataConvertException extends RuntimeException {
public
void
setExcelContentProperty
(
ExcelContentProperty
excelContentProperty
)
{
this
.
excelContentProperty
=
excelContentProperty
;
}
public
CellData
getCellData
()
{
return
cellData
;
}
public
void
setCellData
(
CellData
cellData
)
{
this
.
cellData
=
cellData
;
}
}
src/main/java/com/alibaba/excel/metadata/CellData.java
浏览文件 @
cba3a9ce
...
...
@@ -229,18 +229,21 @@ public class CellData<T> {
@Override
public
String
toString
()
{
if
(
type
==
null
)
{
return
"empty"
;
return
StringUtils
.
EMPTY
;
}
switch
(
type
)
{
case
NUMBER:
return
numberValue
.
toString
();
case
BOOLEAN:
return
booleanValue
.
toString
();
case
DIRECT_STRING:
case
STRING:
case
ERROR:
return
stringValue
;
case
IMAGE:
return
"image["
+
imageValue
.
length
+
"]"
;
default
:
return
"empty"
;
return
StringUtils
.
EMPTY
;
}
}
...
...
src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
浏览文件 @
cba3a9ce
...
...
@@ -24,6 +24,7 @@ import com.alibaba.excel.exception.ExcelCommonException;
import
com.alibaba.excel.exception.ExcelGenerateException
;
import
com.alibaba.excel.metadata.Head
;
import
com.alibaba.excel.metadata.Holder
;
import
com.alibaba.excel.util.ClassUtils
;
import
com.alibaba.excel.util.StringUtils
;
import
com.alibaba.excel.write.metadata.holder.AbstractWriteHolder
;
...
...
@@ -119,51 +120,10 @@ public class ExcelHeadProperty {
if
(
headClazz
==
null
)
{
return
;
}
List
<
Field
>
fieldList
=
new
ArrayList
<
Field
>();
Class
tempClass
=
headClazz
;
// When the parent class is null, it indicates that the parent class (Object class) has reached the top
// level.
while
(
tempClass
!=
null
)
{
Collections
.
addAll
(
fieldList
,
tempClass
.
getDeclaredFields
());
// Get the parent class and give it to yourself
tempClass
=
tempClass
.
getSuperclass
();
}
ExcelIgnoreUnannotated
excelIgnoreUnannotated
=
(
ExcelIgnoreUnannotated
)
headClazz
.
getAnnotation
(
ExcelIgnoreUnannotated
.
class
);
// Screening of field
// Declared fields
List
<
Field
>
defaultFieldList
=
new
ArrayList
<
Field
>();
Map
<
Integer
,
Field
>
customFiledMap
=
new
TreeMap
<
Integer
,
Field
>();
for
(
Field
field
:
fieldList
)
{
ExcelIgnore
excelIgnore
=
field
.
getAnnotation
(
ExcelIgnore
.
class
);
if
(
excelIgnore
!=
null
)
{
ignoreMap
.
put
(
field
.
getName
(),
field
);
continue
;
}
ExcelProperty
excelProperty
=
field
.
getAnnotation
(
ExcelProperty
.
class
);
boolean
noExcelProperty
=
excelProperty
==
null
&&
((
convertAllFiled
!=
null
&&
!
convertAllFiled
)
||
excelIgnoreUnannotated
!=
null
);
if
(
noExcelProperty
)
{
ignoreMap
.
put
(
field
.
getName
(),
field
);
continue
;
}
boolean
isStaticFinalOrTransient
=
(
Modifier
.
isStatic
(
field
.
getModifiers
())
&&
Modifier
.
isFinal
(
field
.
getModifiers
()))
||
Modifier
.
isTransient
(
field
.
getModifiers
());
if
(
excelProperty
==
null
&&
isStaticFinalOrTransient
)
{
ignoreMap
.
put
(
field
.
getName
(),
field
);
continue
;
}
if
(
excelProperty
==
null
||
excelProperty
.
index
()
<
0
)
{
defaultFieldList
.
add
(
field
);
continue
;
}
if
(
customFiledMap
.
containsKey
(
excelProperty
.
index
()))
{
throw
new
ExcelGenerateException
(
"The index of '"
+
customFiledMap
.
get
(
excelProperty
.
index
()).
getName
()
+
"' and '"
+
field
.
getName
()
+
"' must be inconsistent"
);
}
customFiledMap
.
put
(
excelProperty
.
index
(),
field
);
}
ClassUtils
.
declaredFields
(
headClazz
,
defaultFieldList
,
customFiledMap
,
ignoreMap
,
convertAllFiled
);
int
index
=
0
;
for
(
Field
field
:
defaultFieldList
)
{
...
...
src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
浏览文件 @
cba3a9ce
...
...
@@ -93,7 +93,8 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
try
{
resultModel
=
excelReadHeadProperty
.
getHeadClazz
().
newInstance
();
}
catch
(
Exception
e
)
{
throw
new
ExcelDataConvertException
(
throw
new
ExcelDataConvertException
(
context
.
readRowHolder
().
getRowIndex
(),
0
,
new
CellData
(
CellDataTypeEnum
.
EMPTY
),
null
,
"Can not instance class: "
+
excelReadHeadProperty
.
getHeadClazz
().
getName
(),
e
);
}
Map
<
Integer
,
Head
>
headMap
=
excelReadHeadProperty
.
getHeadMap
();
...
...
src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
浏览文件 @
cba3a9ce
...
...
@@ -190,8 +190,7 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
if
(!
HeadKindEnum
.
CLASS
.
equals
(
analysisContext
.
currentReadHolder
().
excelReadHeadProperty
().
getHeadKind
()))
{
return
;
}
Map
<
Integer
,
String
>
dataMap
=
ConverterUtils
.
convertToStringMap
(
cellDataMap
,
analysisContext
.
currentReadHolder
());
Map
<
Integer
,
String
>
dataMap
=
ConverterUtils
.
convertToStringMap
(
cellDataMap
,
analysisContext
);
ExcelReadHeadProperty
excelHeadPropertyData
=
analysisContext
.
readSheetHolder
().
excelReadHeadProperty
();
Map
<
Integer
,
Head
>
headMapData
=
excelHeadPropertyData
.
getHeadMap
();
Map
<
Integer
,
ExcelContentProperty
>
contentPropertyMapData
=
excelHeadPropertyData
.
getContentPropertyMap
();
...
...
src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java
浏览文件 @
cba3a9ce
...
...
@@ -26,10 +26,9 @@ public class ReadSheetHolder extends AbstractReadHolder {
*/
private
String
sheetName
;
/**
*
get total row , D
ata may be inaccurate
*
Gets the total number of rows , d
ata may be inaccurate
*/
@Deprecated
private
Integer
total
;
private
Integer
approximateTotalRowNumber
;
public
ReadSheetHolder
(
ReadSheet
readSheet
,
ReadWorkbookHolder
readWorkbookHolder
)
{
super
(
readSheet
,
readWorkbookHolder
,
readWorkbookHolder
.
getReadWorkbook
().
getConvertAllFiled
());
...
...
@@ -71,12 +70,29 @@ public class ReadSheetHolder extends AbstractReadHolder {
this
.
sheetName
=
sheetName
;
}
/**
*
* Approximate total number of rows
*
* @return
* @see #getApproximateTotalRowNumber()
*/
@Deprecated
public
Integer
getTotal
()
{
return
total
;
return
approximateTotalRowNumber
;
}
/**
* Approximate total number of rows
*
* @return
*/
public
Integer
getApproximateTotalRowNumber
()
{
return
approximateTotalRowNumber
;
}
public
void
set
Total
(
Integer
total
)
{
this
.
total
=
total
;
public
void
set
ApproximateTotalRowNumber
(
Integer
approximateTotalRowNumber
)
{
this
.
approximateTotalRowNumber
=
approximateTotalRowNumber
;
}
@Override
...
...
src/main/java/com/alibaba/excel/util/ClassUtils.java
0 → 100644
浏览文件 @
cba3a9ce
package
com.alibaba.excel.util
;
import
java.lang.ref.SoftReference
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Modifier
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TreeMap
;
import
java.util.concurrent.ConcurrentHashMap
;
import
com.alibaba.excel.annotation.ExcelIgnore
;
import
com.alibaba.excel.annotation.ExcelIgnoreUnannotated
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
com.alibaba.excel.exception.ExcelCommonException
;
import
com.alibaba.excel.metadata.BaseRowModel
;
/**
* Class utils
*
* @author Jiaju Zhuang
**/
public
class
ClassUtils
{
private
static
final
Map
<
Class
,
SoftReference
<
FieldCache
>>
FIELD_CACHE
=
new
ConcurrentHashMap
<
Class
,
SoftReference
<
FieldCache
>>();
public
static
void
declaredFields
(
Class
clazz
,
List
<
Field
>
defaultFieldList
,
Map
<
Integer
,
Field
>
customFiledMap
,
Map
<
String
,
Field
>
ignoreMap
,
Boolean
convertAllFiled
)
{
FieldCache
fieldCache
=
getFieldCache
(
clazz
,
convertAllFiled
);
if
(
fieldCache
!=
null
)
{
defaultFieldList
.
addAll
(
fieldCache
.
getDefaultFieldList
());
customFiledMap
.
putAll
(
fieldCache
.
getCustomFiledMap
());
ignoreMap
.
putAll
(
fieldCache
.
getIgnoreMap
());
}
}
public
static
void
declaredFields
(
Class
clazz
,
List
<
Field
>
fieldList
,
Boolean
convertAllFiled
)
{
FieldCache
fieldCache
=
getFieldCache
(
clazz
,
convertAllFiled
);
if
(
fieldCache
!=
null
)
{
fieldList
.
addAll
(
fieldCache
.
getAllFieldList
());
}
}
private
static
FieldCache
getFieldCache
(
Class
clazz
,
Boolean
convertAllFiled
)
{
if
(
clazz
==
null
)
{
return
null
;
}
SoftReference
<
FieldCache
>
fieldCacheSoftReference
=
FIELD_CACHE
.
get
(
clazz
);
if
(
fieldCacheSoftReference
!=
null
&&
fieldCacheSoftReference
.
get
()
!=
null
)
{
return
fieldCacheSoftReference
.
get
();
}
synchronized
(
clazz
)
{
fieldCacheSoftReference
=
FIELD_CACHE
.
get
(
clazz
);
if
(
fieldCacheSoftReference
!=
null
&&
fieldCacheSoftReference
.
get
()
!=
null
)
{
return
fieldCacheSoftReference
.
get
();
}
declaredFields
(
clazz
,
convertAllFiled
);
}
return
FIELD_CACHE
.
get
(
clazz
).
get
();
}
private
static
void
declaredFields
(
Class
clazz
,
Boolean
convertAllFiled
)
{
List
<
Field
>
tempFieldList
=
new
ArrayList
<
Field
>();
Class
tempClass
=
clazz
;
// When the parent class is null, it indicates that the parent class (Object class) has reached the top
// level.
while
(
tempClass
!=
null
&&
tempClass
!=
BaseRowModel
.
class
)
{
Collections
.
addAll
(
tempFieldList
,
tempClass
.
getDeclaredFields
());
// Get the parent class and give it to yourself
tempClass
=
tempClass
.
getSuperclass
();
}
// Screening of field
List
<
Field
>
defaultFieldList
=
new
ArrayList
<
Field
>();
Map
<
Integer
,
Field
>
customFiledMap
=
new
TreeMap
<
Integer
,
Field
>();
List
<
Field
>
allFieldList
=
new
ArrayList
<
Field
>();
Map
<
String
,
Field
>
ignoreMap
=
new
HashMap
<
String
,
Field
>(
16
);
ExcelIgnoreUnannotated
excelIgnoreUnannotated
=
(
ExcelIgnoreUnannotated
)
clazz
.
getAnnotation
(
ExcelIgnoreUnannotated
.
class
);
for
(
Field
field
:
tempFieldList
)
{
ExcelIgnore
excelIgnore
=
field
.
getAnnotation
(
ExcelIgnore
.
class
);
if
(
excelIgnore
!=
null
)
{
ignoreMap
.
put
(
field
.
getName
(),
field
);
continue
;
}
ExcelProperty
excelProperty
=
field
.
getAnnotation
(
ExcelProperty
.
class
);
boolean
noExcelProperty
=
excelProperty
==
null
&&
((
convertAllFiled
!=
null
&&
!
convertAllFiled
)
||
excelIgnoreUnannotated
!=
null
);
if
(
noExcelProperty
)
{
ignoreMap
.
put
(
field
.
getName
(),
field
);
continue
;
}
boolean
isStaticFinalOrTransient
=
(
Modifier
.
isStatic
(
field
.
getModifiers
())
&&
Modifier
.
isFinal
(
field
.
getModifiers
()))
||
Modifier
.
isTransient
(
field
.
getModifiers
());
if
(
excelProperty
==
null
&&
isStaticFinalOrTransient
)
{
ignoreMap
.
put
(
field
.
getName
(),
field
);
continue
;
}
if
(
excelProperty
==
null
||
excelProperty
.
index
()
<
0
)
{
defaultFieldList
.
add
(
field
);
allFieldList
.
add
(
field
);
continue
;
}
if
(
customFiledMap
.
containsKey
(
excelProperty
.
index
()))
{
throw
new
ExcelCommonException
(
"The index of '"
+
customFiledMap
.
get
(
excelProperty
.
index
()).
getName
()
+
"' and '"
+
field
.
getName
()
+
"' must be inconsistent"
);
}
customFiledMap
.
put
(
excelProperty
.
index
(),
field
);
allFieldList
.
add
(
field
);
}
FIELD_CACHE
.
put
(
clazz
,
new
SoftReference
<
FieldCache
>(
new
FieldCache
(
defaultFieldList
,
customFiledMap
,
allFieldList
,
ignoreMap
)));
}
private
static
class
FieldCache
{
private
List
<
Field
>
defaultFieldList
;
private
Map
<
Integer
,
Field
>
customFiledMap
;
private
List
<
Field
>
allFieldList
;
private
Map
<
String
,
Field
>
ignoreMap
;
public
FieldCache
(
List
<
Field
>
defaultFieldList
,
Map
<
Integer
,
Field
>
customFiledMap
,
List
<
Field
>
allFieldList
,
Map
<
String
,
Field
>
ignoreMap
)
{
this
.
defaultFieldList
=
defaultFieldList
;
this
.
customFiledMap
=
customFiledMap
;
this
.
allFieldList
=
allFieldList
;
this
.
ignoreMap
=
ignoreMap
;
}
public
List
<
Field
>
getDefaultFieldList
()
{
return
defaultFieldList
;
}
public
Map
<
Integer
,
Field
>
getCustomFiledMap
()
{
return
customFiledMap
;
}
public
List
<
Field
>
getAllFieldList
()
{
return
allFieldList
;
}
public
Map
<
String
,
Field
>
getIgnoreMap
()
{
return
ignoreMap
;
}
}
}
src/main/java/com/alibaba/excel/util/ConverterUtils.java
浏览文件 @
cba3a9ce
...
...
@@ -6,6 +6,7 @@ import java.lang.reflect.Type;
import
java.util.HashMap
;
import
java.util.Map
;
import
com.alibaba.excel.context.AnalysisContext
;
import
com.alibaba.excel.converters.Converter
;
import
com.alibaba.excel.converters.ConverterKeyBuild
;
import
com.alibaba.excel.enums.CellDataTypeEnum
;
...
...
@@ -28,11 +29,12 @@ public class ConverterUtils {
* Convert it into a String map
*
* @param cellDataMap
* @param
readHolder
* @param
context
* @return
*/
public
static
Map
<
Integer
,
String
>
convertToStringMap
(
Map
<
Integer
,
CellData
>
cellDataMap
,
ReadHolder
readHolder
)
{
public
static
Map
<
Integer
,
String
>
convertToStringMap
(
Map
<
Integer
,
CellData
>
cellDataMap
,
AnalysisContext
context
)
{
Map
<
Integer
,
String
>
stringMap
=
new
HashMap
<
Integer
,
String
>(
cellDataMap
.
size
()
*
4
/
3
+
1
);
ReadHolder
currentReadHolder
=
context
.
currentReadHolder
();
int
index
=
0
;
for
(
Map
.
Entry
<
Integer
,
CellData
>
entry
:
cellDataMap
.
entrySet
())
{
Integer
key
=
entry
.
getKey
();
...
...
@@ -47,16 +49,17 @@ public class ConverterUtils {
continue
;
}
Converter
converter
=
r
eadHolder
.
converterMap
().
get
(
ConverterKeyBuild
.
buildKey
(
String
.
class
,
cellData
.
getType
()));
currentR
eadHolder
.
converterMap
().
get
(
ConverterKeyBuild
.
buildKey
(
String
.
class
,
cellData
.
getType
()));
if
(
converter
==
null
)
{
throw
new
ExcelDataConvertException
(
throw
new
ExcelDataConvertException
(
context
.
readRowHolder
().
getRowIndex
(),
key
,
cellData
,
null
,
"Converter not found, convert "
+
cellData
.
getType
()
+
" to String"
);
}
try
{
stringMap
.
put
(
key
,
(
String
)(
converter
.
convertToJavaData
(
cellData
,
null
,
r
eadHolder
.
globalConfiguration
())));
(
String
)(
converter
.
convertToJavaData
(
cellData
,
null
,
currentR
eadHolder
.
globalConfiguration
())));
}
catch
(
Exception
e
)
{
throw
new
ExcelDataConvertException
(
"Convert data "
+
cellData
+
" to String error "
,
e
);
throw
new
ExcelDataConvertException
(
context
.
readRowHolder
().
getRowIndex
(),
key
,
cellData
,
null
,
"Convert data "
+
cellData
+
" to String error "
,
e
);
}
}
return
stringMap
;
...
...
@@ -123,13 +126,13 @@ public class ConverterUtils {
converter
=
converterMap
.
get
(
ConverterKeyBuild
.
buildKey
(
clazz
,
cellData
.
getType
()));
}
if
(
converter
==
null
)
{
throw
new
ExcelDataConvertException
(
rowIndex
,
columnIndex
,
contentProperty
,
throw
new
ExcelDataConvertException
(
rowIndex
,
columnIndex
,
c
ellData
,
c
ontentProperty
,
"Converter not found, convert "
+
cellData
.
getType
()
+
" to "
+
clazz
.
getName
());
}
try
{
return
converter
.
convertToJavaData
(
cellData
,
contentProperty
,
globalConfiguration
);
}
catch
(
Exception
e
)
{
throw
new
ExcelDataConvertException
(
rowIndex
,
columnIndex
,
contentProperty
,
throw
new
ExcelDataConvertException
(
rowIndex
,
columnIndex
,
c
ellData
,
c
ontentProperty
,
"Convert data "
+
cellData
+
" to "
+
clazz
+
" error "
,
e
);
}
}
...
...
src/main/java/com/alibaba/excel/util/DateUtils.java
浏览文件 @
cba3a9ce
...
...
@@ -69,7 +69,7 @@ public class DateUtils {
case
10
:
return
DATE_FORMAT_10
;
default
:
throw
new
ExcelDataConver
tException
(
"can not find date format for:"
+
dateString
);
throw
new
IllegalArgumen
tException
(
"can not find date format for:"
+
dateString
);
}
}
...
...
src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
浏览文件 @
cba3a9ce
...
...
@@ -59,8 +59,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
case
EMPTY:
return
cellData
;
default
:
throw
new
ExcelDataConvertException
(
"Not supported data:"
+
value
+
" return type:"
+
cell
.
getCellType
()
+
"at row:"
+
cell
.
getRow
().
getRowNum
());
throw
new
ExcelDataConvertException
(
cell
.
getRow
().
getRowNum
(),
cell
.
getColumnIndex
(),
cellData
,
excelContentProperty
,
"Not supported data:"
+
value
+
" return type:"
+
cell
.
getCellType
()
+
"at row:"
+
cell
.
getRow
().
getRowNum
());
}
}
...
...
@@ -102,7 +103,8 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
converter
=
currentWriteHolder
.
converterMap
().
get
(
ConverterKeyBuild
.
buildKey
(
clazz
));
}
if
(
converter
==
null
)
{
throw
new
ExcelDataConvertException
(
throw
new
ExcelDataConvertException
(
cell
.
getRow
().
getRowNum
(),
cell
.
getColumnIndex
(),
new
CellData
(
CellDataTypeEnum
.
EMPTY
),
excelContentProperty
,
"Can not find 'Converter' support class "
+
clazz
.
getSimpleName
()
+
"."
);
}
CellData
cellData
;
...
...
@@ -110,11 +112,13 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
cellData
=
converter
.
convertToExcelData
(
value
,
excelContentProperty
,
currentWriteHolder
.
globalConfiguration
());
}
catch
(
Exception
e
)
{
throw
new
ExcelDataConvertException
(
"Convert data:"
+
value
+
" error,at row:"
+
cell
.
getRow
().
getRowNum
(),
e
);
throw
new
ExcelDataConvertException
(
cell
.
getRow
().
getRowNum
(),
cell
.
getColumnIndex
(),
new
CellData
(
CellDataTypeEnum
.
EMPTY
),
excelContentProperty
,
"Convert data:"
+
value
+
" error,at row:"
+
cell
.
getRow
().
getRowNum
(),
e
);
}
if
(
cellData
==
null
||
cellData
.
getType
()
==
null
)
{
throw
new
ExcelDataConvertException
(
throw
new
ExcelDataConvertException
(
cell
.
getRow
().
getRowNum
(),
cell
.
getColumnIndex
(),
new
CellData
(
CellDataTypeEnum
.
EMPTY
),
excelContentProperty
,
"Convert data:"
+
value
+
" return null,at row:"
+
cell
.
getRow
().
getRowNum
());
}
return
cellData
;
...
...
src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
浏览文件 @
cba3a9ce
...
...
@@ -2,7 +2,6 @@ package com.alibaba.excel.write.executor;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -13,10 +12,10 @@ import org.apache.poi.ss.usermodel.Row;
import
com.alibaba.excel.context.WriteContext
;
import
com.alibaba.excel.enums.HeadKindEnum
;
import
com.alibaba.excel.metadata.BaseRowModel
;
import
com.alibaba.excel.metadata.CellData
;
import
com.alibaba.excel.metadata.Head
;
import
com.alibaba.excel.metadata.property.ExcelContentProperty
;
import
com.alibaba.excel.util.ClassUtils
;
import
com.alibaba.excel.util.CollectionUtils
;
import
com.alibaba.excel.util.WorkBookUtil
;
import
com.alibaba.excel.util.WriteHandlerUtils
;
...
...
@@ -158,13 +157,11 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
continue
;
}
Object
value
=
beanMap
.
get
(
filedName
);
if
(
value
==
null
)
{
continue
;
}
WriteHandlerUtils
.
beforeCellCreate
(
writeContext
,
row
,
null
,
cellIndex
,
relativeRowIndex
,
Boolean
.
FALSE
);
Cell
cell
=
WorkBookUtil
.
createCell
(
row
,
cellIndex
++);
WriteHandlerUtils
.
afterCellCreate
(
writeContext
,
cell
,
null
,
relativeRowIndex
,
Boolean
.
FALSE
);
CellData
cellData
=
converterAndSet
(
currentWriteHolder
,
value
.
getClass
(),
cell
,
value
,
null
);
CellData
cellData
=
converterAndSet
(
currentWriteHolder
,
value
==
null
?
null
:
value
.
getClass
(),
cell
,
value
,
null
);
WriteHandlerUtils
.
afterCellDispose
(
writeContext
,
cellData
,
cell
,
null
,
relativeRowIndex
,
Boolean
.
FALSE
);
}
}
...
...
@@ -173,13 +170,8 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if
(!
fieldList
.
isEmpty
())
{
return
;
}
Class
tempClass
=
clazz
;
while
(
tempClass
!=
null
)
{
if
(
tempClass
!=
BaseRowModel
.
class
)
{
Collections
.
addAll
(
fieldList
,
tempClass
.
getDeclaredFields
());
}
tempClass
=
tempClass
.
getSuperclass
();
}
ClassUtils
.
declaredFields
(
clazz
,
fieldList
,
writeContext
.
writeWorkbookHolder
().
getWriteWorkbook
().
getConvertAllFiled
());
}
}
src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
浏览文件 @
cba3a9ce
...
...
@@ -3,9 +3,11 @@ package com.alibaba.excel.write.executor;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.CellStyle
;
...
...
@@ -57,6 +59,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
*/
private
Map
<
Integer
,
Map
<
AnalysisCell
,
CellStyle
>>
collectionFieldStyleCache
=
new
HashMap
<
Integer
,
Map
<
AnalysisCell
,
CellStyle
>>(
8
);
/**
* Row height cache for collection
*/
private
Map
<
Integer
,
Short
>
collectionRowHeightCache
=
new
HashMap
<
Integer
,
Short
>(
8
);
/**
* Last index cache for collection fields
*/
...
...
@@ -121,7 +127,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if
(
collectionLastIndexMap
==
null
)
{
number
--;
}
sheet
.
shiftRows
(
maxRowIndex
+
1
,
lastRowIndex
,
number
);
sheet
.
shiftRows
(
maxRowIndex
+
1
,
lastRowIndex
,
number
,
true
,
false
);
for
(
AnalysisCell
analysisCell
:
templateAnalysisCache
.
get
(
writeContext
.
writeSheetHolder
().
getSheetNo
()))
{
if
(
analysisCell
.
getRowIndex
()
>
maxRowIndex
)
{
analysisCell
.
setRowIndex
(
analysisCell
.
getRowIndex
()
+
number
);
...
...
@@ -245,7 +251,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
else
{
row
=
sheet
.
createRow
(
lastRowIndex
);
}
checkRowHeight
(
analysisCell
,
fillConfig
,
isOriginalCell
,
row
,
sheetNo
);
WriteHandlerUtils
.
afterRowCreate
(
writeContext
,
row
,
null
,
Boolean
.
FALSE
);
}
else
{
checkRowHeight
(
analysisCell
,
fillConfig
,
isOriginalCell
,
row
,
sheetNo
);
}
}
Cell
cell
=
row
.
getCell
(
lastColumnIndex
);
...
...
@@ -271,6 +280,21 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return
cell
;
}
private
void
checkRowHeight
(
AnalysisCell
analysisCell
,
FillConfig
fillConfig
,
boolean
isOriginalCell
,
Row
row
,
Integer
sheetNo
)
{
if
(!
analysisCell
.
getFirstColumn
()
||
!
WriteDirectionEnum
.
VERTICAL
.
equals
(
fillConfig
.
getDirection
()))
{
return
;
}
if
(
isOriginalCell
)
{
collectionRowHeightCache
.
put
(
sheetNo
,
row
.
getHeight
());
return
;
}
Short
rowHeight
=
collectionRowHeightCache
.
get
(
sheetNo
);
if
(
rowHeight
!=
null
)
{
row
.
setHeight
(
rowHeight
);
}
}
private
List
<
AnalysisCell
>
readTemplateData
(
Map
<
Integer
,
List
<
AnalysisCell
>>
analysisCache
)
{
Integer
sheetNo
=
writeContext
.
writeSheetHolder
().
getSheetNo
();
List
<
AnalysisCell
>
analysisCellList
=
analysisCache
.
get
(
sheetNo
);
...
...
@@ -280,6 +304,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
Sheet
sheet
=
writeContext
.
writeSheetHolder
().
getCachedSheet
();
analysisCellList
=
new
ArrayList
<
AnalysisCell
>();
List
<
AnalysisCell
>
collectionAnalysisCellList
=
new
ArrayList
<
AnalysisCell
>();
Set
<
Integer
>
firstColumnCache
=
new
HashSet
<
Integer
>();
for
(
int
i
=
0
;
i
<=
sheet
.
getLastRowNum
();
i
++)
{
Row
row
=
sheet
.
getRow
(
i
);
if
(
row
==
null
)
{
...
...
@@ -290,7 +315,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if
(
cell
==
null
)
{
continue
;
}
String
preparedData
=
prepareData
(
cell
,
analysisCellList
,
collectionAnalysisCellList
,
i
,
j
);
String
preparedData
=
prepareData
(
cell
,
analysisCellList
,
collectionAnalysisCellList
,
i
,
j
,
firstColumnCache
);
// Prevent empty data from not being replaced
if
(
preparedData
!=
null
)
{
cell
.
setCellValue
(
preparedData
);
...
...
@@ -310,10 +336,11 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
* @param collectionAnalysisCellList
* @param rowIndex
* @param columnIndex
* @param firstColumnCache
* @return Returns the data that the cell needs to replace
*/
private
String
prepareData
(
Cell
cell
,
List
<
AnalysisCell
>
analysisCellList
,
List
<
AnalysisCell
>
collectionAnalysisCellList
,
int
rowIndex
,
int
columnIndex
)
{
List
<
AnalysisCell
>
collectionAnalysisCellList
,
int
rowIndex
,
int
columnIndex
,
Set
<
Integer
>
firstColumnCache
)
{
if
(!
CellType
.
STRING
.
equals
(
cell
.
getCellTypeEnum
()))
{
return
null
;
}
...
...
@@ -386,6 +413,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if
(
WriteTemplateAnalysisCellTypeEnum
.
COMMON
.
equals
(
analysisCell
.
getCellType
()))
{
analysisCellList
.
add
(
analysisCell
);
}
else
{
if
(!
firstColumnCache
.
contains
(
rowIndex
))
{
analysisCell
.
setFirstColumn
(
Boolean
.
TRUE
);
firstColumnCache
.
add
(
rowIndex
);
}
collectionAnalysisCellList
.
add
(
analysisCell
);
}
return
preparedData
.
toString
();
...
...
@@ -403,6 +434,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
List
<
String
>
prepareDataList
=
new
ArrayList
<
String
>();
analysisCell
.
setPrepareDataList
(
prepareDataList
);
analysisCell
.
setCellType
(
WriteTemplateAnalysisCellTypeEnum
.
COMMON
);
analysisCell
.
setFirstColumn
(
Boolean
.
FALSE
);
return
analysisCell
;
}
...
...
src/main/java/com/alibaba/excel/write/metadata/fill/AnalysisCell.java
浏览文件 @
cba3a9ce
...
...
@@ -16,6 +16,7 @@ public class AnalysisCell {
private
List
<
String
>
prepareDataList
;
private
Boolean
onlyOneVariable
;
private
WriteTemplateAnalysisCellTypeEnum
cellType
;
private
Boolean
firstColumn
;
public
int
getColumnIndex
()
{
return
columnIndex
;
...
...
@@ -65,6 +66,14 @@ public class AnalysisCell {
this
.
cellType
=
cellType
;
}
public
Boolean
getFirstColumn
()
{
return
firstColumn
;
}
public
void
setFirstColumn
(
Boolean
firstColumn
)
{
this
.
firstColumn
=
firstColumn
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
...
...
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java
浏览文件 @
cba3a9ce
...
...
@@ -39,8 +39,8 @@ public class DemoExceptionListener extends AnalysisEventListener<ExceptionDemoDa
// 如果要获取头的信息 配合invokeHeadMap使用
if
(
exception
instanceof
ExcelDataConvertException
)
{
ExcelDataConvertException
excelDataConvertException
=
(
ExcelDataConvertException
)
exception
;
LOGGER
.
error
(
"第{}行,第{}列解析异常"
,
excelDataConvertException
.
getRowIndex
(),
excelDataConvertException
.
getColumnIndex
());
LOGGER
.
error
(
"第{}行,第{}列解析异常
,数据为:{}
"
,
excelDataConvertException
.
getRowIndex
(),
excelDataConvertException
.
getColumnIndex
()
,
excelDataConvertException
.
getCellData
()
);
}
}
...
...
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java
浏览文件 @
cba3a9ce
...
...
@@ -38,8 +38,8 @@ public class DemoHeadDataListener extends AnalysisEventListener<DemoData> {
LOGGER
.
error
(
"解析失败,但是继续解析下一行:{}"
,
exception
.
getMessage
());
if
(
exception
instanceof
ExcelDataConvertException
)
{
ExcelDataConvertException
excelDataConvertException
=
(
ExcelDataConvertException
)
exception
;
LOGGER
.
error
(
"第{}行,第{}列解析异常"
,
excelDataConvertException
.
getRowIndex
(),
excelDataConvertException
.
getColumnIndex
());
LOGGER
.
error
(
"第{}行,第{}列解析异常
,数据为:{}
"
,
excelDataConvertException
.
getRowIndex
(),
excelDataConvertException
.
getColumnIndex
()
,
excelDataConvertException
.
getCellData
()
);
}
}
...
...
src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java
0 → 100644
浏览文件 @
cba3a9ce
package
com.alibaba.easyexcel.test.temp
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
com.alibaba.easyexcel.test.demo.fill.FillData
;
import
com.alibaba.easyexcel.test.util.TestFileUtil
;
import
com.alibaba.excel.EasyExcel
;
import
com.alibaba.excel.ExcelWriter
;
import
com.alibaba.excel.write.metadata.WriteSheet
;
import
com.alibaba.excel.write.metadata.fill.FillConfig
;
import
com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy
;
/**
* 写的填充写法
*
* @since 2.1.1
* @author Jiaju Zhuang
*/
@Ignore
public
class
FillTempTest
{
/**
* 复杂的填充
*
* @since 2.1.1
*/
@Test
public
void
complexFill
()
{
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
String
templateFileName
=
"D:\\test\\complex.xlsx"
;
String
fileName
=
TestFileUtil
.
getPath
()
+
"complexFill"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
ExcelWriter
excelWriter
=
EasyExcel
.
write
(
fileName
).
withTemplate
(
templateFileName
).
build
();
WriteSheet
writeSheet
=
EasyExcel
.
writerSheet
().
build
();
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
// 如果数据量大 list不是最后一行 参照下一个
FillConfig
fillConfig
=
FillConfig
.
builder
().
forceNewRow
(
Boolean
.
TRUE
).
build
();
excelWriter
.
fill
(
data
(),
fillConfig
,
writeSheet
);
excelWriter
.
fill
(
data
(),
fillConfig
,
writeSheet
);
Map
<
String
,
Object
>
map
=
new
HashMap
<
String
,
Object
>();
map
.
put
(
"date"
,
"2019年10月9日13:28:28"
);
map
.
put
(
"total"
,
1000
);
excelWriter
.
fill
(
map
,
writeSheet
);
excelWriter
.
finish
();
}
/**
* 数据量大的复杂填充
* <p>
* 这里的解决方案是 确保模板list为最后一行,然后再拼接table.还有03版没救,只能刚正面加内存。
*
* @since 2.1.1
*/
@Test
public
void
complexFillWithTable
()
{
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量
// 这里模板 删除了list以后的数据,也就是统计的这一行
String
templateFileName
=
"D:\\test\\complex.xlsx"
;
String
fileName
=
TestFileUtil
.
getPath
()
+
"complexFillWithTable"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
ExcelWriter
excelWriter
=
EasyExcel
.
write
(
fileName
).
withTemplate
(
templateFileName
).
build
();
WriteSheet
writeSheet
=
EasyExcel
.
writerSheet
().
build
();
// 直接写入数据
excelWriter
.
fill
(
data
(),
writeSheet
);
excelWriter
.
fill
(
data
(),
writeSheet
);
// 写入list之前的数据
Map
<
String
,
Object
>
map
=
new
HashMap
<
String
,
Object
>();
map
.
put
(
"date"
,
"2019年10月9日13:28:28"
);
excelWriter
.
fill
(
map
,
writeSheet
);
// list 后面还有个统计 想办法手动写入
// 这里偷懒直接用list 也可以用对象
List
<
List
<
String
>>
totalListList
=
new
ArrayList
<
List
<
String
>>();
List
<
String
>
totalList
=
new
ArrayList
<
String
>();
totalListList
.
add
(
totalList
);
totalList
.
add
(
null
);
totalList
.
add
(
null
);
totalList
.
add
(
null
);
// 第四列
totalList
.
add
(
"统计:1000"
);
// 这里是write 别和fill 搞错了
excelWriter
.
write
(
totalListList
,
writeSheet
);
excelWriter
.
finish
();
// 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动,也不支持备注这种的写入,所以也排除了可以
// 新建一个 然后一点点复制过来的方案,最后导致list需要新增行的时候,后面的列的数据没法后移,后续会继续想想解决方案
}
private
List
<
FillData
>
data
()
{
List
<
FillData
>
list
=
new
ArrayList
<
FillData
>();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
FillData
fillData
=
new
FillData
();
list
.
add
(
fillData
);
fillData
.
setName
(
"张三"
);
fillData
.
setNumber
(
5.2
);
}
return
list
;
}
}
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
浏览文件 @
cba3a9ce
...
...
@@ -79,11 +79,11 @@ public class PoiTest {
@Test
public
void
lastRowNum255
()
throws
IOException
,
InvalidFormatException
{
String
file
=
TestFileUtil
.
getPath
()
+
"fill"
+
File
.
separator
+
"
complex.xlsx"
;
String
file
=
"D:\\test\\
complex.xlsx"
;
XSSFWorkbook
xssfWorkbook
=
new
XSSFWorkbook
(
new
File
(
file
));
SXSSFWorkbook
sxssfWorkbook
=
new
SXSSFWorkbook
(
xssfWorkbook
);
Sheet
xssfSheet
=
xssfWorkbook
.
getSheetAt
(
0
);
xssfSheet
.
shiftRows
(
2
,
4
,
10
);
xssfSheet
.
shiftRows
(
1
,
4
,
10
,
true
,
true
);
FileOutputStream
fileout
=
new
FileOutputStream
(
"d://test/r2"
+
System
.
currentTimeMillis
()
+
".xlsx"
);
sxssfWorkbook
.
write
(
fileout
);
...
...
src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java
浏览文件 @
cba3a9ce
...
...
@@ -25,6 +25,7 @@ public class HDListener extends AnalysisEventListener<HeadReadData> {
@Override
public
void
invokeHeadMap
(
Map
<
Integer
,
String
>
headMap
,
AnalysisContext
context
)
{
LOGGER
.
info
(
"HEAD:{}"
,
JSON
.
toJSONString
(
headMap
));
LOGGER
.
info
(
"total:{}"
,
context
.
readSheetHolder
().
getTotal
());
}
...
...
src/test/java/com/alibaba/easyexcel/test/temp/read/HeadReadData.java
浏览文件 @
cba3a9ce
...
...
@@ -3,6 +3,7 @@ package com.alibaba.easyexcel.test.temp.read;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
/**
* 临时测试
...
...
@@ -10,6 +11,7 @@ import lombok.Data;
* @author Jiaju Zhuang
**/
@Data
@Accessors
(
chain
=
true
)
public
class
HeadReadData
{
@ExcelProperty
(
"头1"
)
private
String
h1
;
...
...
src/test/java/com/alibaba/easyexcel/test/temp/read/HeadReadTest.java
浏览文件 @
cba3a9ce
...
...
@@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.temp.read;
import
java.io.File
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -13,13 +14,15 @@ import com.alibaba.excel.EasyExcel;
*
* @author Jiaju Zhuang
**/
@Ignore
public
class
HeadReadTest
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
HeadReadTest
.
class
);
@Test
public
void
test
()
throws
Exception
{
File
file
=
new
File
(
"D:\\test\\headt1.xlsx"
);
EasyExcel
.
read
(
file
,
HeadReadData
.
class
,
new
HDListener
()).
sheet
().
doRead
();
File
file
=
new
File
(
"D:\\test\\headt1.xls"
);
EasyExcel
.
read
(
file
,
HeadReadData
.
class
,
new
HDListener
()).
sheet
(
0
).
doRead
();
}
}
update.md
浏览文件 @
cba3a9ce
...
...
@@ -7,6 +7,11 @@
*
加入多次关闭判断,防止多次关闭异常
*
加入根据模板自动识别导出的excel类型
*
修改默认失败后,不再往文件流写入数据。通过参数
`writeExcelOnException`
参数设置异常了也要写入前面的数据。
*
循环合并策略支持一次性合并多列
*
`ExcelDataConvertException`
返回新增具体报错的数据
*
加入解析class缓存
*
修复填充的时候行高不复制的Bug
[
Issue #780
](
https://github.com/alibaba/easyexcel/issues/780
)
*
修复03版无法获取大概总行数的bug
# 2.1.0-beta4
*
修改最长匹配策略会空指针的bug
[
Issue #747
](
https://github.com/alibaba/easyexcel/issues/747
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录