<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
EasyExcel是一個基於Java的、快速、簡潔、解決大檔案記憶體溢位的Excel處理工具。他能讓你在不用考慮效能、記憶體的等因素的情況下,快速完成Excel的讀、寫等功能。
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內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45