POI & EasyExcel
POI
Excel写操作
导入依赖
<dependency>
<groupId>org.apache.poi
</groupId>
<artifactId>poi
</artifactId>
<version>4.1.2
</version>
</dependency>
<dependency>
<groupId>org.apache.poi
</groupId>
<artifactId>poi-ooxml
</artifactId>
<version>4.1.2
</version>
</dependency>
<dependency>
<groupId>joda-time
</groupId>
<artifactId>joda-time
</artifactId>
<version>2.10.6
</version>
</dependency>
<dependency>
<groupId>junit
</groupId>
<artifactId>junit
</artifactId>
<version>4.13
</version>
</dependency>
写入测试
public class ExcelWriteTest {
String PATH
= "/Users/work/idea_work/poi_easy-excel/";
@Test
public void testWrite03() throws Exception
{
Workbook workbook
= new XSSFWorkbook();
Sheet sheet
= workbook
.createSheet("学生信息表1");
Row row1
= sheet
.createRow(0);
Cell cell11
= row1
.createCell(0);
cell11
.setCellValue("学生姓名");
Cell cell12
= row1
.createCell(1);
cell12
.setCellValue("年龄");
Cell cell31
= row1
.createCell(2);
cell31
.setCellValue("创建时间");
Row row2
= sheet
.createRow(1);
Cell cell21
= row2
.createCell(0);
cell21
.setCellValue("李志鹏");
Cell cell22
= row2
.createCell(1);
cell22
.setCellValue("23");
Cell cell32
= row2
.createCell(2);
String time
= new DateTime().toString("yyyy-MM-dd HH:mm:ss");
cell32
.setCellValue(time
);
FileOutputStream fileOutputStream
= new FileOutputStream(PATH
+ "学生信息表.xlsx");
workbook
.write(fileOutputStream
);
fileOutputStream
.close();
System
.out
.println("学生表创建成功~");
}
}
大数据的写入
HSSF (03)
优点:
在内存中操作,最后一次写入磁盘,速度快
缺点:
最大只能一次插入65536行数据,否则会报错
java.lang.IllegalArgumentException: Invalid row number
(65536
) outside allowable range
(0
..65535
)
@Test
public void testWriteBigData() throws IOException
{
long start
= System
.currentTimeMillis();
Workbook workbook
= new HSSFWorkbook();
Sheet sheet
= workbook
.createSheet();
for (int rowNum
= 0; rowNum
< 65537; rowNum
++) {
Row row
= sheet
.createRow(rowNum
);
for (int cellNum
= 0; cellNum
< 10; cellNum
++) {
Cell cell
= row
.createCell(cellNum
);
cell
.setCellValue(cellNum
);
}
}
System
.out
.println("over");
FileOutputStream outputStream
= new FileOutputStream(PATH
+ "大数据写入.xls");
workbook
.write(outputStream
);
outputStream
.close();
long end
= System
.currentTimeMillis();
System
.out
.println((double) (end
- start
)/1000);
}
XSSF (07)
优点:
可以写入更大的数据量
缺点:
写数据速度慢,耗内存
@Test
public void testWriteBigData2() throws IOException
{
long start
= System
.currentTimeMillis();
Workbook workbook
= new XSSFWorkbook();
Sheet sheet
= workbook
.createSheet();
for (int rowNum
= 0; rowNum
< 100000; rowNum
++) {
Row row
= sheet
.createRow(rowNum
);
for (int cellNum
= 0; cellNum
< 10; cellNum
++) {
Cell cell
= row
.createCell(cellNum
);
cell
.setCellValue(cellNum
);
}
}
System
.out
.println("over");
FileOutputStream outputStream
= new FileOutputStream(PATH
+ "大数据写入2.xlsx");
workbook
.write(outputStream
);
outputStream
.close();
long end
= System
.currentTimeMillis();
System
.out
.println((double) (end
- start
)/1000);
}
SXSSF 大数据操作
优点:
可以写入非常大的数据量,速度更快,占用内存少
注意:
过程中会产生临时文件,需要清理临时文件
@Test
public void testWriteBigData3() throws IOException
{
long start
= System
.currentTimeMillis();
Workbook workbook
= new SXSSFWorkbook();
Sheet sheet
= workbook
.createSheet();
for (int rowNum
= 0; rowNum
< 65536; rowNum
++) {
Row row
= sheet
.createRow(rowNum
);
for (int cellNum
= 0; cellNum
< 10; cellNum
++) {
Cell cell
= row
.createCell(cellNum
);
cell
.setCellValue(cellNum
);
}
}
System
.out
.println("over");
FileOutputStream outputStream
= new FileOutputStream(PATH
+ "大数据写入3.xlsx");
workbook
.write(outputStream
);
outputStream
.close();
((SXSSFWorkbook
) workbook
).dispose();
long end
= System
.currentTimeMillis();
System
.out
.println((double) (end
- start
)/1000);
}
Excel读取操作
HSSF (3)
@Test
public void ExcelRead03() throws IOException
{
FileInputStream inputStream
= new FileInputStream(PATH
+ "学生信息表.xls");
Workbook workbook
= new HSSFWorkbook(inputStream
);
Sheet sheet
= workbook
.getSheet("学生信息表1");
Row row
= sheet
.getRow(0);
Cell cell
= row
.getCell(0);
System
.out
.println(cell
.getStringCellValue());
inputStream
.close();
}
XSSF
@Test
public void ExcelRead07() throws IOException
{
FileInputStream inputStream
= new FileInputStream(PATH
+ "学生信息表.xlsx");
Workbook workbook
= new XSSFWorkbook(inputStream
);
Sheet sheet
= workbook
.getSheet("学生信息表1");
Row row
= sheet
.getRow(1);
Cell cell
= row
.getCell(1);
System
.out
.println(cell
.getStringCellValue());
inputStream
.close();
}
不同数据类型数据读取
@Test
public void testCellType() throws IOException
{
FileInputStream inputStream
= new FileInputStream(PATH
+ "学生信息表.xls");
Workbook workbook
= new HSSFWorkbook(inputStream
);
Sheet sheet
= workbook
.getSheet("学生信息表1");
Row rowTitle
= sheet
.getRow(0);
if (rowTitle
!= null
) {
int cellCount
= rowTitle
.getPhysicalNumberOfCells();
for (int cellNum
= 0; cellNum
< cellCount
; cellNum
++) {
Cell cell
= rowTitle
.getCell(cellNum
);
if (cell
!= null
) {
int cellType
= cell
.getCellType();
String cellValue
= cell
.getStringCellValue();
System
.out
.print(cellValue
+ " | ");
}
}
System
.out
.println();
}
int rowCount
= sheet
.getPhysicalNumberOfRows();
for (int rowNum
= 0; rowNum
< rowCount
; rowNum
++) {
Row row
= sheet
.getRow(rowNum
);
if (row
!= null
) {
int cellCount
= row
.getPhysicalNumberOfCells();
for (int cellNum
= 0; cellNum
< cellCount
; cellNum
++) {
Cell cell
= row
.getCell(cellNum
);
if (cell
!= null
) {
int cellType
= cell
.getCellType();
String cellValue
= "";
switch (cellType
) {
case HSSFCell
.CELL_TYPE_BLANK
:
break;
case HSSFCell
.CELL_TYPE_STRING
:
cellValue
= cell
.getStringCellValue();
break;
case HSSFCell
.CELL_TYPE_BOOLEAN
:
cellValue
= String
.valueOf(cell
.getBooleanCellValue());
break;
case HSSFCell
.CELL_TYPE_NUMERIC
:
if (HSSFDateUtil
.isCellDateFormatted(cell
)) {
Date date
= cell
.getDateCellValue();
cellValue
= new DateTime(date
).toString("yyyy-MM-dd");
} else {
cell
.setCellType(HSSFCell
.CELL_TYPE_STRING
);
cellValue
= cell
.toString();
}
break;
case HSSFCell
.CELL_TYPE_ERROR
:
break;
}
System
.out
.print(cellValue
+ " | ");
}
}
}
System
.out
.println();
}
inputStream
.close();
}
公式类型数据读取
@Test
public void testFormula() throws IOException
{
FileInputStream inputStream
= new FileInputStream(PATH
+ "公式.xlsx");
Workbook workbook
= new XSSFWorkbook(inputStream
);
Sheet sheet
= workbook
.getSheetAt(0);
Row row
= sheet
.getRow(3);
Cell cell
= row
.getCell(0);
FormulaEvaluator evaluator
= new XSSFFormulaEvaluator((XSSFWorkbook
) workbook
);
int cellType
= cell
.getCellType();
switch (cellType
) {
case Cell
.CELL_TYPE_FORMULA
:
String formula
= cell
.getCellFormula();
System
.out
.println(formula
);
CellValue evaluate
= evaluator
.evaluate(cell
);
String cellValue
= evaluate
.formatAsString();
System
.out
.println(cellValue
);
break;
}
inputStream
.close();
}
EasyExcel
导入依赖:
<dependency>
<groupId>com.alibaba
</groupId>
<artifactId>easyexcel
</artifactId>
<version>2.2.6
</version>
</dependency>
<dependency>
<groupId>org.projectlombok
</groupId>
<artifactId>lombok
</artifactId>
<version>1.18.8
</version>
</dependency>
<dependency>
<groupId>junit
</groupId>
<artifactId>junit
</artifactId>
<version>4.13
</version>
</dependency>
实体类:
@Data
public class DemoData {
@ExcelProperty("字符串标题")
private String string
;
@ExcelProperty("日期标题")
private Date date
;
@ExcelProperty("数字标题")
private Double doubleData
;
@ExcelIgnore
private String ignore
;
}
写入操作
简单写入
public class EasyExcelTest {
String PATH
= "/Users/work/idea_work/poi_easy-excel/";
private List
<DemoData> data() {
List
<DemoData> list
= new ArrayList<DemoData>();
for (int i
= 0; i
< 10; i
++) {
DemoData data
= new DemoData();
data
.setString("字符串" + i
);
data
.setDate(new Date());
data
.setDoubleData(0.56);
list
.add(data
);
}
return list
;
}
@Test
public void simpleWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, DemoData
.class).sheet("模板").doWrite(data());
}
}
读取操作
简单读取
监听器:
public class DemoDataListener extends AnalysisEventListener<DemoData> {
private static final Logger LOGGER
= LoggerFactory
.getLogger(DemoDataListener
.class);
private static final int BATCH_COUNT
= 5;
List
<DemoData> list
= new ArrayList<DemoData>();
private DemoDAO demoDAO
;
public DemoDataListener() {
demoDAO
= new DemoDAO();
}
public DemoDataListener(DemoDAO demoDAO
) {
this.demoDAO
= demoDAO
;
}
@Override
public void invoke(DemoData data
, AnalysisContext context
) {
System
.out
.println("解析到一条数据:" + JSON
.toJSONString(data
));
list
.add(data
);
if (list
.size() >= BATCH_COUNT
) {
saveData();
list
.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context
) {
saveData();
System
.out
.println("所有数据解析完成!");
}
private void saveData() {
System
.out
.println(list
.size() + "条数据,开始存储数据库!");
demoDAO
.save(list
);
System
.out
.println("存储数据库成功!");
}
}
简单读取:
String PATH
= "/Users/work/idea_work/poi_easy-excel/";
@Test
public void simpleRead() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.read(fileName
, DemoData
.class, new DemoDataListener()).sheet().doRead();
}
其他API
指定参数不写入
@Test
public void excludeOrIncludeWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
Set
<String> excludeColumnFiledNames
= new HashSet<String>();
excludeColumnFiledNames
.add("date");
EasyExcel
.write(fileName
, DemoData
.class).excludeColumnFiledNames(excludeColumnFiledNames
).sheet("模板").doWrite(data());
}
指定写入的列
@Data
public class IndexData {
@ExcelProperty(value
= "字符串标题", index
= 0)
private String string
;
@ExcelProperty(value
= "日期标题", index
= 1)
private Date date
;
@ExcelProperty(value
= "数字标题", index
= 3)
private Double doubleData
;
}
@Test
public void indexWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, IndexData
.class).sheet("模板").doWrite(data());
}
复杂头写入
@Data
public class ComplexHeadData {
@ExcelProperty({"主标题", "字符串标题"})
private String string
;
@ExcelProperty({"主标题", "日期标题"})
private Date date
;
@ExcelProperty({"主标题", "数字标题"})
private Double doubleData
;
}
@Test
public void complexHeadWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, ComplexHeadData
.class).sheet("模板").doWrite(data());
}
重复多次写入
单个对象写入一个sheet
@Test
public void repeatedWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
ExcelWriter excelWriter
= null
;
try {
excelWriter
= EasyExcel
.write(fileName
, DemoData
.class).build();
WriteSheet sheet
= EasyExcel
.writerSheet("模板").build();
for (int i
= 0; i
< 2; i
++) {
List
<DemoData> data
= data();
excelWriter
.write(data
, sheet
);
}
} finally {
if (excelWriter
!= null
) {
excelWriter
.finish();
}
}
}
同一对象写入不同sheet
@Test
public void repeatedWrite2() {
String fileName
= PATH
+ "EasyExcelTest.xls";
ExcelWriter excelWriter
= null
;
try {
excelWriter
= EasyExcel
.write(fileName
, DemoData
.class).build();
for (int i
= 0; i
< 5; i
++) {
WriteSheet sheet
= EasyExcel
.writerSheet("模板" + i
).build();
List
<DemoData> data
= data();
excelWriter
.write(data
, sheet
);
}
} finally {
if (excelWriter
!= null
) {
excelWriter
.finish();
}
}
}
不同对象写入不同sheet
@Test
public void repeatedWrite3() {
String fileName
= PATH
+ "EasyExcelTest.xls";
ExcelWriter excelWriter
= null
;
try {
excelWriter
= EasyExcel
.write(fileName
).build();
for (int i
= 1; i
<= 3; i
++) {
switch (i
) {
case 1:
WriteSheet sheet1
= EasyExcel
.writerSheet(i
, "模板1").head(DemoData
.class).build();
List
<DemoData> data
= data();
excelWriter
.write(data
, sheet1
);
break;
case 2:
WriteSheet sheet2
= EasyExcel
.writerSheet(i
, "模板2").head(IndexData
.class).build();
List
<IndexData> indexData
= indexData();
excelWriter
.write(indexData
, sheet2
);
break;
case 3:
WriteSheet sheet3
= EasyExcel
.writerSheet(i
, "模板3").head(ComplexHeadData
.class).build();
List
<ComplexHeadData> complexHeadData
= complexHeadData();
excelWriter
.write(complexHeadData
, sheet3
);
break;
}
}
} finally {
if (excelWriter
!= null
) {
excelWriter
.finish();
}
}
}
模板1:
模板2:
模板3:
日期、数字自定义格式转换
@Data
public class ConverterData {
@ExcelProperty(value
= "字符串标题", converter
= CustomStringStringConverter
.class)
private String string
;
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
@ExcelProperty("日期标题")
private Date date
;
@NumberFormat("#.##%")
@ExcelProperty(value
= "数字标题")
private Double doubleData
;
}
public class CustomStringStringConverter implements Converter<String> {
@Override
public Class
supportJavaTypeKey() {
return String
.class;
}
@Override
public CellDataTypeEnum
supportExcelTypeKey() {
return CellDataTypeEnum
.STRING
;
}
@Override
public String
convertToJavaData(CellData cellData
, ExcelContentProperty contentProperty
,
GlobalConfiguration globalConfiguration
) {
return cellData
.getStringValue();
}
@Override
public CellData
convertToExcelData(String value
, ExcelContentProperty contentProperty
,
GlobalConfiguration globalConfiguration
) {
return new CellData("自定义:" + value
);
}
}
@Test
public void converterWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, ConverterData
.class).sheet("模板").doWrite(data());
}
图片写入
@Data
@ContentRowHeight(100)
@ColumnWidth(100/8)
public class ImageData {
private File file
;
private InputStream inputStream
;
@ExcelProperty(converter
= StringImageConverter
.class)
private String string
;
private byte[] byteArray
;
private URL url
;
}
public class TestFileUtil {
public static InputStream
getResourcesFileInputStream(String fileName
) {
return Thread
.currentThread().getContextClassLoader().getResourceAsStream("" + fileName
);
}
public static String
getPath() {
return TestFileUtil
.class.getResource("/").getPath();
}
public static File
createNewFile(String pathName
) {
File file
= new File(getPath() + pathName
);
if (file
.exists()) {
file
.delete();
} else {
if (!file
.getParentFile().exists()) {
file
.getParentFile().mkdirs();
}
}
return file
;
}
public static File
readFile(String pathName
) {
return new File(getPath() + pathName
);
}
public static File
readUserHomeFile(String pathName
) {
return new File(System
.getProperty("user.home") + File
.separator
+ pathName
);
}
}
@Test
public void imageWrite() throws Exception
{
String fileName
= PATH
+ "EasyExcelTest.xls";
FileInputStream inputStream
= null
;
try {
ArrayList
<ImageData> list
= new ArrayList<ImageData>();
ImageData imageData
= new ImageData();
list
.add(imageData
);
String imagePath
= TestFileUtil
.getPath() + "图片1.png";
imageData
.setFile(new File(imagePath
));
imageData
.setByteArray(FileUtils
.readFileToByteArray(new File(imagePath
)));
imageData
.setString(imagePath
);
inputStream
= FileUtils
.openInputStream(new File(imagePath
));
imageData
.setInputStream(inputStream
);
imageData
.setUrl(new URL("https://raw.githubusercontent.com/alibaba/easyexcel/master/src/test/resources/converter/img.jpg"));
EasyExcel
.write(fileName
, ImageData
.class).sheet().doWrite(list
);
} finally {
if (inputStream
!= null
) {
inputStream
.close();
}
}
}
根据模板写入
@Test
public void templateWrite() {
String templateFileName
= PATH
+ "demo.xls";
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, DemoData
.class).withTemplate(templateFileName
).sheet().doWrite(data());
}
写入时设置列宽行高
@Data
@ContentRowHeight(10)
@HeadRowHeight(20)
@ColumnWidth(25)
public class WidthAndHeightData {
@ExcelProperty("字符串标题")
private String string
;
@ExcelProperty("日期标题")
private Date date
;
@ColumnWidth(50)
@ExcelProperty("数字标题")
private Double doubleData
;
}
@Test
public void widthAndHeightWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, WidthAndHeightData
.class).sheet().doWrite(data());
}
写入时配置自定义样式(注解形式)
@Data
@HeadStyle(fillPatternType
= FillPatternType
.SOLID_FOREGROUND
, fillForegroundColor
= 10)
@HeadFontStyle(fontHeightInPoints
= 20)
@ContentStyle(fillPatternType
= FillPatternType
.SOLID_FOREGROUND
, fillForegroundColor
= 17)
@ContentFontStyle(fontHeightInPoints
= 20)
public class DemoStyleData {
@HeadStyle(fillPatternType
= FillPatternType
.SOLID_FOREGROUND
, fillForegroundColor
= 14)
@HeadFontStyle(fontHeightInPoints
= 30)
@ContentStyle(fillPatternType
= FillPatternType
.SOLID_FOREGROUND
, fillForegroundColor
= 40)
@ContentFontStyle(fontHeightInPoints
= 30)
@ExcelProperty("字符串标题")
private String string
;
@ExcelProperty("日期标题")
private Date date
;
@ExcelProperty("数字标题")
private Double doubleData
;
}
@Test
public void annotationStyleWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, DemoStyleData
.class).sheet().doWrite(data());
}
写入时自定义样式
@Test
public void styleWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
WriteCellStyle headWriteCellStyle
= new WriteCellStyle();
headWriteCellStyle
.setFillForegroundColor(IndexedColors
.RED
.getIndex());
WriteFont headWriteFont
= new WriteFont();
headWriteFont
.setFontHeightInPoints((short)20);
headWriteCellStyle
.setWriteFont(headWriteFont
);
WriteCellStyle contentWriteCellStyle
= new WriteCellStyle();
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
);
EasyExcel
.write(fileName
, DemoData
.class).registerWriteHandler(horizontalCellStyleStrategy
).sheet("模板")
.doWrite(data());
}
合并单元格
@Test
public void mergeWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, DemoMergeData
.class).sheet().doWrite(data());
}
@Test
public void mergeWrite2() {
String fileName
= PATH
+ "EasyExcelTest.xls";
LoopMergeStrategy strategy
= new LoopMergeStrategy(2, 0);
EasyExcel
.write(fileName
, DemoData
.class).registerWriteHandler(strategy
).sheet().doWrite(data());
}
使用table去写入
@Test
public void tableWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
ExcelWriter excelWriter
= null
;
try {
excelWriter
= EasyExcel
.write(fileName
, DemoData
.class).build();
WriteSheet writeSheet
= EasyExcel
.writerSheet("模板").needHead(Boolean
.FALSE
).build();
WriteTable writeTable0
= EasyExcel
.writerTable(0).needHead(Boolean
.TRUE
).build();
WriteTable writeTable1
= EasyExcel
.writerTable(1).needHead(Boolean
.TRUE
).build();
excelWriter
.write(data(), writeSheet
, writeTable0
);
excelWriter
.write(data(), writeSheet
, writeTable1
);
} finally {
if (excelWriter
!= null
) {
excelWriter
.finish();
}
}
}
动态头
private List
<List
<String>> head() {
List
<List
<String>> list
= new ArrayList<List
<String>>();
List
<String> head0
= new ArrayList<String>();
head0
.add("字符串" + System
.currentTimeMillis());
List
<String> head1
= new ArrayList<String>();
head1
.add("数字" + System
.currentTimeMillis());
List
<String> head2
= new ArrayList<String>();
head2
.add("日期" + System
.currentTimeMillis());
list
.add(head0
);
list
.add(head1
);
list
.add(head2
);
return list
;
}
@Test
public void dynamicHeadWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
)
.head(head()).sheet("模板")
.doWrite(data());
}
自动列宽(不太精确)
@Data
public class LongestMatchColumnWidthData {
@ExcelProperty("字符串标题")
private String string
;
@ExcelProperty("日期标题很长日期标题很长日期标题很长很长")
private Date date
;
@ExcelProperty("数字")
private Double doubleData
;
}
@Test
public void longestMatchColumnWidthWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, LongestMatchColumnWidthData
.class)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(dataLong());
}
private List
<LongestMatchColumnWidthData> dataLong() {
List
<LongestMatchColumnWidthData> list
= new ArrayList<LongestMatchColumnWidthData>();
for (int i
= 0; i
< 10; i
++) {
LongestMatchColumnWidthData data
= new LongestMatchColumnWidthData();
data
.setString("测试很长的字符串测试很长的字符串测试很长的字符串" + i
);
data
.setDate(new Date());
data
.setDoubleData(1000000000000.0);
list
.add(data
);
}
return list
;
}
自定义拦截器
对第一行第一列的头超链接到:https://github.com/alibaba/easyexcel
public class CustomCellWriteHandler implements CellWriteHandler {
private static final Logger LOGGER
= LoggerFactory
.getLogger(CustomCellWriteHandler
.class);
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder
, WriteTableHolder writeTableHolder
, Row row
,
Head head
, Integer columnIndex
, Integer relativeRowIndex
, Boolean isHead
) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder
, WriteTableHolder writeTableHolder
, Cell cell
,
Head head
, Integer relativeRowIndex
, Boolean isHead
) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder
, WriteTableHolder writeTableHolder
, CellData cellData
, Cell cell
, Head head
, Integer integer
, Boolean aBoolean
) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder
, WriteTableHolder writeTableHolder
,
List
<CellData> cellDataList
, Cell cell
, Head head
, Integer relativeRowIndex
, Boolean isHead
) {
LOGGER
.info("第{}行,第{}列写入完成。", cell
.getRowIndex(), cell
.getColumnIndex());
if (isHead
&& cell
.getColumnIndex() == 0) {
CreationHelper createHelper
= writeSheetHolder
.getSheet().getWorkbook().getCreationHelper();
Hyperlink hyperlink
= createHelper
.createHyperlink(HyperlinkType
.URL
);
hyperlink
.setAddress("https://github.com/alibaba/easyexcel");
cell
.setHyperlink(hyperlink
);
}
}
}
对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2
public class CustomSheetWriteHandler implements SheetWriteHandler {
private static final Logger LOGGER
= LoggerFactory
.getLogger(CustomSheetWriteHandler
.class);
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder
, WriteSheetHolder writeSheetHolder
) {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder
, WriteSheetHolder writeSheetHolder
) {
LOGGER
.info("第{}个Sheet写入成功。", writeSheetHolder
.getSheetNo());
CellRangeAddressList cellRangeAddressList
= new CellRangeAddressList(1, 2, 0, 0);
DataValidationHelper helper
= writeSheetHolder
.getSheet().getDataValidationHelper();
DataValidationConstraint constraint
= helper
.createExplicitListConstraint(new String[] {"测试1", "测试2"});
DataValidation dataValidation
= helper
.createValidation(constraint
, cellRangeAddressList
);
writeSheetHolder
.getSheet().addValidationData(dataValidation
);
}
}
@Test
public void customHandlerWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, DemoData
.class).registerWriteHandler(new CustomCellWriteHandler())
.registerWriteHandler(new CustomSheetWriteHandler()).sheet().doWrite(data());
}
插入批注
public class CommentWriteHandler extends AbstractRowWriteHandler {
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder
, WriteTableHolder writeTableHolder
, Row row
,
Integer relativeRowIndex
, Boolean isHead
) {
if (isHead
) {
Sheet sheet
= writeSheetHolder
.getSheet();
Drawing
<?> drawingPatriarch
= sheet
.createDrawingPatriarch();
Comment comment
= drawingPatriarch
.createCellComment(
new HSSFClientAnchor(0, 0, 0, 0, (short) 1, 0, (short) 2, 1));
comment
.setString(new HSSFRichTextString("创建批注!"));
sheet
.getRow(0).getCell(1).setCellComment(comment
);
}
}
}
@Test
public void commentWrite() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.write(fileName
, DemoData
.class).inMemory(Boolean
.TRUE
).registerWriteHandler(new CommentWriteHandler()).sheet().doWrite(data());
}
读取指定列名或下标
@Data
public class IndexOrNameData {
@ExcelProperty(index
= 2)
private Double doubleData
;
@ExcelProperty("字符串标题")
private String string
;
@ExcelProperty("日期标题")
private Date date
;
}
public class IndexOrNameDataListener extends AnalysisEventListener<IndexOrNameData> {
private static final Logger LOGGER
= LoggerFactory
.getLogger(IndexOrNameDataListener
.class);
private static final int BATCH_COUNT
= 5;
List
<IndexOrNameData> list
= new ArrayList<IndexOrNameData>();
@Override
public void invoke(IndexOrNameData data
, AnalysisContext context
) {
LOGGER
.info("解析到一条数据:{}", JSON
.toJSONString(data
));
System
.out
.println("解析到一条数据:" + 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("存储数据库成功!");
}
}
@Test
public void indexOrNameRead() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.read(fileName
, IndexOrNameData
.class, new IndexOrNameDataListener()).sheet().doRead();
}
读取多个sheet
读取全部sheet
@Test
public void repeatedRead() {
String fileName
= PATH
+ "EasyExcelTest.xls";
EasyExcel
.read(fileName
, DemoData
.class, new DemoDataListener()).doReadAll();
}
读取部分sheet
@Test
public void repeatedRead2() {
String fileName
= PATH
+ "EasyExcelTest.xls";
ExcelReader excelReader
= null
;
try {
excelReader
= EasyExcel
.read(fileName
).build();
ReadSheet readSheet1
=
EasyExcel
.readSheet(0).head(DemoData
.class).registerReadListener(new DemoDataListener()).build();
ReadSheet readSheet2
=
EasyExcel
.readSheet(1).head(DemoData
.class).registerReadListener(new DemoDataListener()).build();
excelReader
.read(readSheet1
, readSheet2
);
} finally {
if (excelReader
!= null
) {
excelReader
.finish();
}
}
}