Java利用EasyExcel读取写入Excel详情

Java利用EasyExcel读取写入Excel详情

目录

EasyExcel介绍

为什么使用EasyExcel?

封装使用

例子

EasyExcel介绍

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

为什么使用EasyExcel?

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。

封装使用

引入EasyExcel依赖

<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version> </dependency>

Excel文档的自动列宽设置

public class CustomColumnWidthHandler extends AbstractColumnWidthStyleStrategy { private static final int MAX_COLUMN_WIDTH = 255; private static final int PADDING_WIDTH = 6; @Override protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) { if (isHead) { int columnWidth = cell.getStringCellValue().length() * 2 + PADDING_WIDTH; columnWidth = Math.min(columnWidth, MAX_COLUMN_WIDTH); writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256); } } }

消费监听器:

import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; public class EasyExcelConsumerListener<T> extends AnalysisEventListener<T> { private int pageSize; private List<T> list; private Consumer<List<T>> consumer; public EasyExcelConsumerListener(int pageSize, Consumer<List<T>> consumer) { this.pageSize = pageSize; this.consumer = consumer; list = new ArrayList<>(pageSize); } @Override public void invoke(T data, AnalysisContext context) { list.add(data); if (list.size() >= pageSize) { consumer.accept(list); list.clear(); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { consumer.accept(list); } @Override public void onException(Exception exception, AnalysisContext context) throws Exception { exception.printStackTrace(); throw exception; } }

ExcelSheet

public class ExcelSheet<T> { private String sheetName; private T clazz; private List<T> data; public ExcelSheet() { } public ExcelSheet(String sheetName, T clazz, List<T> data) { this.sheetName = sheetName; this.clazz = clazz; this.data = data; } public String getSheetName() { return sheetName; } public void setSheetName(String sheetName) { this.sheetName = sheetName; } public T getClazz() { return clazz; } public void setClazz(T clazz) { this.clazz = clazz; } public List<T> getData() { return data; } public void setData(List<T> data) { this.data = data; } @Override public String toString() { return "CreateExcelSheet{" + "sheetName='" + sheetName + '\'' + ", clazz=" + clazz + ", data=" + data + '}'; } }

LocalDateConverter

import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ReadConverterContext; import com.alibaba.excel.converters.WriteConverterContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.data.WriteCellData; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class LocalDateConverter implements Converter<LocalDate> { @Override public Class<LocalDate> supportJavaTypeKey() { return LocalDate.class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } @Override public LocalDate convertToJavaData(ReadConverterContext<?> context) { Calendar calendar = new GregorianCalendar(1900, 0, -1); Date gregorianDate = calendar.getTime(); return LocalDate.parse((new SimpleDateFormat("yyyy-MM-dd")).format( addDay(gregorianDate, context.getReadCellData().getNumberValue().intValue())), DateTimeFormatter.ofPattern("yyyy-MM-dd") ); } @Override public WriteCellData<?> convertToExcelData(WriteConverterContext<LocalDate> context) { return new WriteCellData<>(context.getValue().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); } public static Date addDay(Date date, int day) { Calendar calendar = new GregorianCalendar(); calendar.setTime(date); calendar.add(5, day); date = calendar.getTime(); return date; } }

LocalDateTimeConverter

import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ReadConverterContext; import com.alibaba.excel.converters.WriteConverterContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.data.WriteCellData; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class LocalDateTimeConverter implements Converter<LocalDateTime> { @Override public Class<LocalDateTime> supportJavaTypeKey() { return LocalDateTime.class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } @Override public LocalDateTime convertToJavaData(ReadConverterContext<?> context) { return LocalDateTime.parse(context.getReadCellData().getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } @Override public WriteCellData<?> convertToExcelData(WriteConverterContext<LocalDateTime> context) { return new WriteCellData<>(context.getValue().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } }

ByteArrayConverter

import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ReadConverterContext; import com.alibaba.excel.converters.WriteConverterContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.data.WriteCellData; import java.nio.charset.StandardCharsets; public class ByteArrayConverter implements Converter<byte[]> { public ByteArrayConverter() { } @Override public Class<byte[]> supportJavaTypeKey() { return byte[].class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } @Override public byte[] convertToJavaData(ReadConverterContext<?> context) { String stringValue = context.getReadCellData().getStringValue(); return stringValue.getBytes(StandardCharsets.UTF_8); } @Override public WriteCellData<?> convertToExcelData(WriteConverterContext<byte[]> context) { return new WriteCellData((byte[])context.getValue()); } }

EasyExcel工具类

import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.read.builder.ExcelReaderBuilder; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.net.URLEncoder; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; public class ExcelUtil extends EasyExcel { private static final Logger LOGGER = LoggerFactory.getLogger(ExcelUtil.class); private ExcelUtil() {} /** * 分批读取 */ public static <T> ExcelReaderBuilder read(String pathName, Class<T> head, Integer pageSize, Consumer<List<T>> consumer) { return read(pathName, head, new EasyExcelConsumerListener<>(pageSize, consumer)); } /** * 分批读取 */ public static <T> ExcelReaderBuilder read(File file, Class<T> head, Integer pageSize, Consumer<List<T>> consumer) { return read(file, head, new EasyExcelConsumerListener<>(pageSize, consumer)); } /** * 分批读取 */ public static <T> ExcelReaderBuilder read(InputStream inputStream, Class<T> head, Integer pageSize, Consumer<List<T>> consumer) { return read(inputStream, head, new EasyExcelConsumerListener<>(pageSize, consumer)); } /** * 根据实体生成Excel模版(用于数据导入的模版下载) */ public static ExcelWriterBuilder write(String pathName, Class head) { return EasyExcel.write(pathName, head) .excelType(ExcelTypeEnum.XLSX) .registerWriteHandler(buildCellStyle()) .registerWriteHandler(new CustomColumnWidthHandler()); } /** * 写入 */ public static void write(HttpServletResponse response, List<?> data, String fileName, String sheetName, Class clazz) throws Exception { EasyExcel.write(getOutputStream(fileName, response), clazz) .excelType(ExcelTypeEnum.XLSX) .sheet(sheetName) .registerWriteHandler(buildCellStyle()) .registerWriteHandler(new CustomColumnWidthHandler()) .doWrite(data); } /** * 写入 */ public static void write(OutputStream outputStream, List<?> data, String sheetName, Class clazz) { EasyExcel.write(outputStream, clazz) .excelType(ExcelTypeEnum.XLSX) .sheet(sheetName) .registerWriteHandler(buildCellStyle()) .registerWriteHandler(new CustomColumnWidthHandler()) .doWrite(data); } private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception { fileName = URLEncoder.encode(fileName, "UTF-8"); response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf8"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); return response.getOutputStream(); } /** * 获取表头 */ public static Map<String, String> getHeadMap(Class<?> aClass) { Map<String, String> HeadMap = new LinkedHashMap<>(); Field[] declaredFields = aClass.getDeclaredFields(); ExcelProperty excelProperty; for (Field field : declaredFields) { if (field != null) { field.setAccessible(true); if (field.isAnnotationPresent(ExcelProperty.class)) { excelProperty = field.getAnnotation(ExcelProperty.class); HeadMap.put(field.getName(), StringUtils.join(Arrays.asList(excelProperty.value()), ",")); } } } return HeadMap; } /** * 生成通用表格样式 */ public static HorizontalCellStyleStrategy buildCellStyle(){ //表头样式 WriteCellStyle headWriteCellStyle = new WriteCellStyle(); headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); headWriteCellStyle.setFillForegroundColor(IndexedColors.TEAL.getIndex()); headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); WriteFont font = new WriteFont(); font.setFontName("Microsoft YaHei Light"); font.setColor(IndexedColors.WHITE.getIndex()); font.setFontHeightInPoints((short) 11); headWriteCellStyle.setWriteFont(font); //内容样式 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT); return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); } /** * 创建一个Excel文件多个Sheet * @param sheetList */ public static void createExcel(List<ExcelSheet> sheetList, OutputStream os){ ExcelWriter excelWriter = null; WriteSheet writeSheet = null; int count = 0; try { excelWriter = EasyExcel.write(os) .registerWriteHandler(buildCellStyle()) .registerWriteHandler(new CustomColumnWidthHandler()) .build(); for (ExcelSheet sheet : sheetList) { writeSheet = EasyExcel.writerSheet(count++, sheet.getSheetName()).head((Class) sheet.getClazz()).build(); excelWriter.write(sheet.getData(),writeSheet); } } catch (Exception e) { LOGGER.error("创建一个Excel文件多个Sheet失败", e); }finally { if (null != excelWriter){ excelWriter.finish(); } } } } 例子

UserVo实体

import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; import java.time.LocalDate; @Data public class UserVo { @ExcelProperty(value = "姓名") private String name; @ExcelProperty(value = "年龄") private int age; @ExcelProperty(value = "出生日期", converter = LocalDateConverter.class) private LocalDate birthdate; }

 导出用户信息

ExcelUtil.write(httpServletResponse, list, "用户信息.xlsx", "用户信息", UserVo.class);

读取用户信息

ExcelUtil.read(filePath, UserVo.class, 1000, pageList -> { pageList.forEach(user -> { // 业务逻辑 }); }).sheet().doRead();

到此这篇关于Java利用EasyExcel读取写入Excel详情的文章就介绍到这了,更多相关Java 读取Excel内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    无法读取U盘中的数据

    无法读取U盘中的数据,,核心提示:我有一个512MB的U盘,把它插在电脑显示器里面是空的,但右键单击以查看已经使用USB 480mb文件的属性未设置为隐

    提高3A四核羿龙II游戏配置的性能

    提高3A四核羿龙II游戏配置的性能,,以节能环保为主题的IT产业,目前3A低端平台处理器、主板芯片组、独立开发卡性能突出,特别是在与AMD的处理

    优化PostgreSQL中的批量更新性能

    优化PostgreSQL中的批量更新性能,数据,表格,在Ubuntu 12.04上使用PG 9.1. 我们目前需要24小时才能运行大量UPDATE数据库上的语句,其形式

    诺基亚威图性能好到哪里

    诺基亚威图性能好到哪里,诺基亚,手机,诺基亚威图性能好到哪里这是一部以前列出的手机。即使当时配置不高,该品牌的手机也不依赖于该功能吸

    魅蓝note6性能参数有哪些

    魅蓝note6性能参数有哪些,摄像头,蓝牙,魅蓝note6性能参数有哪些魅力蓝色Note6最好拍照。电池寿命更长。蓝色Note6使用高通 snapdragon 625

    电脑店u修复工具|u盘修复电脑工具

    电脑店u修复工具|u盘修复电脑工具,,u盘修复电脑工具你好,1、电脑管家是没有修复U盘的功能的。所以不好修复U盘的。2、如果要修复U盘的话,可

    内存插槽坏了 怎么办

    内存插槽坏了 怎么办,插槽,内存,电脑,一个插槽能用,就不要修了,修主板成本高,不划算,而且返修过的东东,一不小心,说不定其它某个地方就坏了,主板