Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
金手指1668
easyexcel
提交
5f5e6e62
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
5f5e6e62
编写于
9月 05, 2019
作者:
庄家钜
提交者:
GitHub
9月 05, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #551 from alibaba/2.0.0-beta4
2.0.0 beta4
上级
9dbd5869
e7ac15ce
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
229 addition
and
33 deletion
+229
-33
.github/ISSUE_TEMPLATE/1question.md
.github/ISSUE_TEMPLATE/1question.md
+0
-18
pom.xml
pom.xml
+1
-1
quickstart.md
quickstart.md
+1
-0
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
...n/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
+12
-0
src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
...alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
+6
-8
src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
...alibaba/excel/analysis/v07/SharedStringsTableHandler.java
+22
-0
src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
...libaba/excel/read/metadata/holder/ReadWorkbookHolder.java
+15
-0
src/main/java/com/alibaba/excel/util/BooleanUtils.java
src/main/java/com/alibaba/excel/util/BooleanUtils.java
+0
-1
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
+4
-2
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java
...va/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java
+1
-1
src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java
...t/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java
+2
-2
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java
...om/alibaba/easyexcel/test/temp/simple/RepeatListener.java
+51
-0
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatTest.java
...va/com/alibaba/easyexcel/test/temp/simple/RepeatTest.java
+58
-0
src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java
...st/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java
+51
-0
update.md
update.md
+5
-0
未找到文件。
.github/ISSUE_TEMPLATE/1question.md
已删除
100644 → 0
浏览文件 @
9dbd5869
name: 使用疑问
about: 请先阅读“快速使用”,上面无法解决再提交问题
name: 给出建议
about: 给出一些建议的能
title: ''
labels: help wanted
labels: suggest
assignees: ''
---
**异常代码**
```
java
这里写你的代码
```
**异常提示**
请提供完整的异常提示
**建议描述**
\ No newline at end of file
pom.xml
浏览文件 @
5f5e6e62
...
...
@@ -4,7 +4,7 @@
<modelVersion>
4.0.0
</modelVersion>
<groupId>
com.alibaba
</groupId>
<artifactId>
easyexcel
</artifactId>
<version>
2.0.0-beta
3
</version>
<version>
2.0.0-beta
4
</version>
<packaging>
jar
</packaging>
<name>
easyexcel
</name>
...
...
quickstart.md
浏览文件 @
5f5e6e62
...
...
@@ -13,6 +13,7 @@
*
ExcelReaderSheetBuilder ExcelWriterSheetBuilder 构建出一个 ReadSheet WriteSheet对象,可以理解成excel里面的一页,每一页都要构建一个
*
ReadListener 在每一行读取完毕后都会调用ReadListener来处理数据
*
WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用WriteHandler来处理数据
*
所有配置都是继承的,Workbook的配置会被Sheet继承,所以在用EasyExcel设置参数的时候,在EasyExcel...sheet()方法之前作用域是整个sheet,之后针对单个sheet
#### 开源项目不容易,如果觉得本项目对您的工作还是有帮助的话,请在右上角帮忙点个★Star。
### 读
DEMO代码地址:
[
https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/demo/read/ReadTest.java
](
/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
)
...
...
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
浏览文件 @
5f5e6e62
...
...
@@ -14,6 +14,8 @@ import org.apache.poi.hssf.eventusermodel.HSSFListener;
import
org.apache.poi.hssf.eventusermodel.HSSFRequest
;
import
org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener
;
import
org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord
;
import
org.apache.poi.hssf.record.BOFRecord
;
import
org.apache.poi.hssf.record.BoundSheetRecord
;
import
org.apache.poi.hssf.record.Record
;
import
org.apache.poi.hssf.usermodel.HSSFWorkbook
;
import
org.apache.poi.poifs.filesystem.POIFSFileSystem
;
...
...
@@ -83,6 +85,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
@Override
public
void
execute
()
{
analysisContext
.
readSheetHolder
().
getSheetNo
();
MissingRecordAwareHSSFListener
listener
=
new
MissingRecordAwareHSSFListener
(
this
);
formatListener
=
new
FormatTrackingHSSFListener
(
listener
);
workbookBuildingListener
=
new
EventWorkbookBuilder
.
SheetRecordCollectingListener
(
formatListener
);
...
...
@@ -121,6 +124,10 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
@Override
public
void
processRecord
(
Record
record
)
{
// Not data from the current sheet
if
(
ignoreRecord
(
record
))
{
return
;
}
int
thisRow
=
-
1
;
int
thisColumn
=
-
1
;
CellData
cellData
=
null
;
...
...
@@ -164,6 +171,11 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
processLastCellOfRow
(
record
);
}
private
boolean
ignoreRecord
(
Record
record
)
{
return
analysisContext
.
readWorkbookHolder
().
getIgnoreRecord03
()
&&
record
.
getSid
()
!=
BoundSheetRecord
.
sid
&&
record
.
getSid
()
!=
BOFRecord
.
sid
;
}
private
void
processLastCellOfRow
(
Record
record
)
{
// Handle end of row
if
(
record
instanceof
LastCellOfRowDummyRecord
)
{
...
...
src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
浏览文件 @
5f5e6e62
...
...
@@ -23,7 +23,6 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
private
int
sheetIndex
;
private
List
<
ReadSheet
>
sheets
;
private
AnalysisContext
context
;
private
boolean
analyAllSheet
;
private
EventWorkbookBuilder
.
SheetRecordCollectingListener
workbookBuildingListener
;
public
BofRecordHandler
(
EventWorkbookBuilder
.
SheetRecordCollectingListener
workbookBuildingListener
,
...
...
@@ -48,21 +47,20 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
if
(
orderedBsrs
==
null
)
{
orderedBsrs
=
BoundSheetRecord
.
orderByBofPosition
(
boundSheetRecords
);
}
sheetIndex
++;
ReadSheet
readSheet
=
new
ReadSheet
(
sheetIndex
,
orderedBsrs
[
sheetIndex
-
1
].
getSheetname
());
ReadSheet
readSheet
=
new
ReadSheet
(
sheetIndex
,
orderedBsrs
[
sheetIndex
].
getSheetname
());
sheets
.
add
(
readSheet
);
if
(
this
.
analyAllSheet
)
{
context
.
currentSheet
(
null
,
readSheet
);
if
(
sheetIndex
==
context
.
readSheetHolder
().
getSheetNo
())
{
context
.
readWorkbookHolder
().
setIgnoreRecord03
(
Boolean
.
FALSE
);
}
else
{
context
.
readWorkbookHolder
().
setIgnoreRecord03
(
Boolean
.
TRUE
);
}
sheetIndex
++;
}
}
}
@Override
public
void
init
()
{
if
(
context
.
readSheetHolder
()
==
null
)
{
this
.
analyAllSheet
=
true
;
}
sheetIndex
=
0
;
orderedBsrs
=
null
;
boundSheetRecords
.
clear
();
...
...
src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
浏览文件 @
5f5e6e62
...
...
@@ -13,6 +13,11 @@ import com.alibaba.excel.cache.ReadCache;
public
class
SharedStringsTableHandler
extends
DefaultHandler
{
private
static
final
String
T_TAG
=
"t"
;
private
static
final
String
SI_TAG
=
"si"
;
/**
* Mac 2016 2017 will have this extra field to ignore
*/
private
static
final
String
RPH_TAG
=
"rPh"
;
/**
* The final piece of data
*/
...
...
@@ -23,6 +28,14 @@ public class SharedStringsTableHandler extends DefaultHandler {
private
StringBuilder
currentElementData
;
private
ReadCache
readCache
;
/**
* Some fields in the T tag need to be ignored
*/
private
boolean
ignoreTagt
=
false
;
/**
* The only time you need to read the characters in the T tag is when it is used
*/
private
boolean
isTagt
=
false
;
public
SharedStringsTableHandler
(
ReadCache
readCache
)
{
this
.
readCache
=
readCache
;
...
...
@@ -32,8 +45,11 @@ public class SharedStringsTableHandler extends DefaultHandler {
public
void
startElement
(
String
uri
,
String
localName
,
String
name
,
Attributes
attributes
)
{
if
(
T_TAG
.
equals
(
name
))
{
currentElementData
=
null
;
isTagt
=
true
;
}
else
if
(
SI_TAG
.
equals
(
name
))
{
currentData
=
null
;
}
else
if
(
RPH_TAG
.
equals
(
name
))
{
ignoreTagt
=
true
;
}
}
...
...
@@ -46,17 +62,23 @@ public class SharedStringsTableHandler extends DefaultHandler {
}
currentData
.
append
(
currentElementData
);
}
isTagt
=
false
;
}
else
if
(
SI_TAG
.
equals
(
name
))
{
if
(
currentData
==
null
)
{
readCache
.
put
(
null
);
}
else
{
readCache
.
put
(
currentData
.
toString
());
}
}
else
if
(
RPH_TAG
.
equals
(
name
))
{
ignoreTagt
=
false
;
}
}
@Override
public
void
characters
(
char
[]
ch
,
int
start
,
int
length
)
{
if
(!
isTagt
||
ignoreTagt
)
{
return
;
}
if
(
currentElementData
==
null
)
{
currentElementData
=
new
StringBuilder
();
}
...
...
src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
浏览文件 @
5f5e6e62
...
...
@@ -101,6 +101,12 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
*/
private
POIFSFileSystem
poifsFileSystem
;
/**
* Excel 2003 cannot read specific sheet. It can only read sheet by sheet.So when you specify one sheet, you ignore
* the others.
*/
private
Boolean
ignoreRecord03
;
public
ReadWorkbookHolder
(
ReadWorkbook
readWorkbook
)
{
super
(
readWorkbook
,
null
,
readWorkbook
.
getConvertAllFiled
());
this
.
readWorkbook
=
readWorkbook
;
...
...
@@ -144,6 +150,7 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this
.
defaultReturnMap
=
readWorkbook
.
getDefaultReturnMap
();
}
this
.
hasReadSheet
=
new
HashSet
<
Integer
>();
this
.
ignoreRecord03
=
Boolean
.
FALSE
;
}
public
ReadWorkbook
getReadWorkbook
()
{
...
...
@@ -258,6 +265,14 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this
.
poifsFileSystem
=
poifsFileSystem
;
}
public
Boolean
getIgnoreRecord03
()
{
return
ignoreRecord03
;
}
public
void
setIgnoreRecord03
(
Boolean
ignoreRecord03
)
{
this
.
ignoreRecord03
=
ignoreRecord03
;
}
@Override
public
HolderEnum
holderType
()
{
return
HolderEnum
.
WORKBOOK
;
...
...
src/main/java/com/alibaba/excel/util/BooleanUtils.java
浏览文件 @
5f5e6e62
...
...
@@ -8,7 +8,6 @@ package com.alibaba.excel.util;
public
class
BooleanUtils
{
private
static
final
String
TRUE_NUMBER
=
"1"
;
private
static
final
String
FALSE_NUMBER
=
"0"
;
private
BooleanUtils
()
{}
...
...
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
浏览文件 @
5f5e6e62
...
...
@@ -174,7 +174,8 @@ public class ExcelBuilderImpl implements ExcelBuilder {
if
(
cellIndex
!=
0
)
{
cellIndex
++;
}
for
(
int
i
=
0
;
i
<
oneRowData
.
size
()
-
dataIndex
;
i
++)
{
int
size
=
oneRowData
.
size
()
-
dataIndex
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
doAddBasicTypeToExcel
(
oneRowData
,
null
,
row
,
relativeRowIndex
,
dataIndex
++,
cellIndex
++);
}
}
...
...
@@ -184,7 +185,8 @@ public class ExcelBuilderImpl implements ExcelBuilder {
beforeCellCreate
(
row
,
head
,
relativeRowIndex
);
Cell
cell
=
WorkBookUtil
.
createCell
(
row
,
cellIndex
);
Object
value
=
oneRowData
.
get
(
dataIndex
);
CellData
cellData
=
converterAndSet
(
context
.
currentWriteHolder
(),
value
.
getClass
(),
cell
,
value
,
null
);
CellData
cellData
=
converterAndSet
(
context
.
currentWriteHolder
(),
value
==
null
?
null
:
value
.
getClass
(),
cell
,
value
,
null
);
afterCellCreate
(
head
,
cellData
,
cell
,
relativeRowIndex
);
}
...
...
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java
浏览文件 @
5f5e6e62
...
...
@@ -28,7 +28,7 @@ public class PoiFormatTest {
@Test
public
void
lastRowNum
()
throws
IOException
{
String
file
=
TestFileUtil
.
getPath
()
+
"demo"
+
File
.
separator
+
"demo
.xlsx"
;
String
file
=
"D:\\test\\原文件
.xlsx"
;
SXSSFWorkbook
xssfWorkbook
=
new
SXSSFWorkbook
(
new
XSSFWorkbook
(
file
));
SXSSFSheet
xssfSheet
=
xssfWorkbook
.
getSheetAt
(
0
);
LOGGER
.
info
(
"一共行数:{}"
,
xssfSheet
.
getLastRowNum
());
...
...
src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java
浏览文件 @
5f5e6e62
...
...
@@ -23,8 +23,8 @@ public class HgTest {
@Test
public
void
hh
()
throws
IOException
{
List
<
Object
>
list
=
EasyExcel
.
read
(
new
FileInputStream
(
"D:\\test\\hg2.xlsx"
)).
autoTrim
(
Boolean
.
FALSE
).
sheet
()
.
headRowNumber
(
0
).
doReadSync
();
List
<
Object
>
list
=
EasyExcel
.
read
(
new
FileInputStream
(
"D:\\test\\原文件.xlsx"
)).
headRowNumber
(
0
).
sheet
(
).
doReadSync
();
for
(
Object
data
:
list
)
{
LOGGER
.
info
(
"返回数据:{}"
,
JSON
.
toJSONString
(
data
));
}
...
...
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java
0 → 100644
浏览文件 @
5f5e6e62
package
com.alibaba.easyexcel.test.temp.simple
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.alibaba.easyexcel.test.demo.read.DemoDataListener
;
import
com.alibaba.easyexcel.test.temp.LockData
;
import
com.alibaba.excel.context.AnalysisContext
;
import
com.alibaba.excel.event.AnalysisEventListener
;
import
com.alibaba.fastjson.JSON
;
/**
* 模板的读取类
*
* @author Jiaju Zhuang
*/
public
class
RepeatListener
extends
AnalysisEventListener
<
LockData
>
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
DemoDataListener
.
class
);
/**
* 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
*/
private
static
final
int
BATCH_COUNT
=
5
;
List
<
LockData
>
list
=
new
ArrayList
<
LockData
>();
@Override
public
void
invoke
(
LockData
data
,
AnalysisContext
context
)
{
LOGGER
.
info
(
"解析到一条数据:{}"
,
JSON
.
toJSONString
(
data
));
list
.
add
(
data
);
if
(
list
.
size
()
>=
BATCH_COUNT
)
{
saveData
();
list
.
clear
();
}
}
@Override
public
void
doAfterAllAnalysed
(
AnalysisContext
context
)
{
saveData
();
LOGGER
.
info
(
"所有数据解析完成!"
);
}
/**
* 加上存储数据库
*/
private
void
saveData
()
{
LOGGER
.
info
(
"{}条数据,开始存储数据库!"
,
list
.
size
());
LOGGER
.
info
(
"存储数据库成功!"
);
}
}
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatTest.java
0 → 100644
浏览文件 @
5f5e6e62
package
com.alibaba.easyexcel.test.temp.simple
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.util.List
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.alibaba.easyexcel.test.temp.LockData
;
import
com.alibaba.excel.EasyExcel
;
import
com.alibaba.excel.ExcelReader
;
import
com.alibaba.excel.read.metadata.ReadSheet
;
import
com.alibaba.fastjson.JSON
;
/**
* 测试poi
*
* @author Jiaju Zhuang
**/
@Ignore
public
class
RepeatTest
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
RepeatTest
.
class
);
@Test
public
void
hh
()
throws
IOException
{
ExcelReader
reader
=
EasyExcel
.
read
(
new
FileInputStream
(
"D:\\test\\hg2.xls"
),
LockData
.
class
,
new
RepeatListener
())
.
headRowNumber
(
0
).
build
();
ReadSheet
r1
=
EasyExcel
.
readSheet
(
0
).
build
();
ReadSheet
r2
=
EasyExcel
.
readSheet
(
2
).
build
();
reader
.
read
(
r1
);
reader
.
read
(
r2
);
reader
.
finish
();
}
@Test
public
void
hh2
()
throws
IOException
{
ExcelReader
reader
=
EasyExcel
.
read
(
new
FileInputStream
(
"D:\\test\\sheet.xls"
),
LockData
.
class
,
new
RepeatListener
())
.
headRowNumber
(
0
).
build
();
ReadSheet
r2
=
EasyExcel
.
readSheet
(
1
).
build
();
reader
.
read
(
r2
);
reader
.
finish
();
}
@Test
public
void
hh1
()
throws
IOException
{
ExcelReader
reader
=
EasyExcel
.
read
(
new
FileInputStream
(
"D:\\test\\hg2.xls"
),
LockData
.
class
,
new
RepeatListener
())
.
headRowNumber
(
0
).
build
();
ReadSheet
r2
=
EasyExcel
.
readSheet
(
0
).
build
();
reader
.
read
(
r2
);
reader
.
finish
();
}
}
src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java
0 → 100644
浏览文件 @
5f5e6e62
package
com.alibaba.easyexcel.test.temp.simple
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.alibaba.easyexcel.test.demo.write.DemoData
;
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.fastjson.JSON
;
/**
* 测试poi
*
* @author Jiaju Zhuang
**/
@Ignore
public
class
Wirte
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
Wirte
.
class
);
@Test
public
void
simpleWrite
()
{
// 写法1
String
fileName
=
TestFileUtil
.
getPath
()
+
"ttttttttt11"
+
System
.
currentTimeMillis
()
+
".xlsx"
;
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel
.
write
(
fileName
).
sheet
(
"模板"
).
doWrite
(
data
());
}
private
List
<
List
<
Object
>>
data
()
{
List
<
List
<
Object
>>
list
=
new
ArrayList
<
List
<
Object
>>();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
List
<
Object
>
list1
=
new
ArrayList
<
Object
>();
list1
.
add
(
"字符串"
+
i
);
list1
.
add
(
new
Date
());
list1
.
add
(
0.56
);
list
.
add
(
list1
);
}
return
list
;
}
}
update.md
浏览文件 @
5f5e6e62
# 2.0.0-beta4
*
修改在传入List
<List
<
Object
>
>判断行数错误
[
Issue #526
](
https://github.com/alibaba/easyexcel/issues/526
)
*
修复在mac 2016 2017导出的excel 可能存在多余字段的问题
*
修复03版 读取无法指定sheet的问题
[
Issue #533
](
https://github.com/alibaba/easyexcel/issues/533
)
# 2.0.0-beta3
*
导出完成移除临时目录
[
Issue #386
](
https://github.com/alibaba/easyexcel/issues/386
)
*
新增读取返回头数据
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录