<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>easyExcel</artifactId> <name>easyExcel</name> <version>1.0</version> <groupId>chenwc</groupId> <packaging>jar</packaging> <properties> <java.version>1.8</java.version> <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> <slf4j.version>1.7.36</slf4j.version> <log4j.version>1.2.17</log4j.version> <commons-io.version>2.11.0</commons-io.version> <easyexcel.version>3.1.3</easyexcel.version> </properties> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>${easyexcel.version}</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-reload4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> <type>pom</type> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> </plugin> </plugins> </build> </project>
import java.util.*; /** * 表格数据实体类 */ public class SheetData { /** * 表头 */ private List<String> header = new ArrayList<>(); /** * 表格数据 */ private List<List<String>> datas = new ArrayList<>(); /** * 转换为 List<Map<String, String>> 的表格数据 datas */ private List<Map<String, String>> dataMapList = new ArrayList<>(); /** * 转为excel表头 * @return excel表头 */ public List<List<String>> toExcelHeader(){ List<List<String>> headList = new ArrayList<>(); for(String row : header){ List<String> h = new ArrayList<>(); h.add(row); headList.add(h); } return headList; } /** * 把 List<Map<String, String>> 转换为可以写入excel的List<List<String>>数据 * @return List<List<String>> */ public List<List<String>> toExcelData(){ List<List<String>> list = new ArrayList<>(); for (Map<String, String> dataMap : this.dataMapList) { List<String> data = new ArrayList<>(); for (String s : this.header) { data.add(dataMap.get(s)); } list.add(data); } return list; } /** * 获取转换为 List<Map<String, String>> 的表格数据 * @return 表格数据 */ public List<Map<String, String>> getDataMapList() { for (List<String> list : this.datas) { Map<String, String> row = new HashMap<>(); for (int i = 0; i < this.header.size(); i++) { row.put(this.header.get(i), list.get(i)); } this.dataMapList.add(row); } return dataMapList; } public void setDataMapList(List<Map<String, String>> dataMapList) { this.dataMapList = dataMapList; } public List<String> getHeader() { return header; } public void setHeader(List<String> header) { this.header = header; } public List<List<String>> getDatas() { return datas; } public void setDatas(List<List<String>> datas) { this.datas = datas; } }
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.util.StringUtils; import com.chenwc.easyexcel.entity.SheetData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 读取监听器 */ public class ArrayDataListener extends AnalysisEventListener<Map<Integer, String>> { private SheetData data = new SheetData(); private static final Logger log = LoggerFactory.getLogger(ArrayDataListener.class); /** * 读取表头 * * @param headMap 表头map * @param context 上下文1 */ @Override public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) { super.invokeHead(headMap, context); for (Integer key : headMap.keySet()) { ReadCellData<?> cellData = headMap.get(key); String value = cellData.getStringValue(); if (StringUtils.isEmpty(value)) { value = ""; } data.getHeader().add(value); } log.info("读取到的表头为: {}", data.getHeader()); } /** * 读取行数据 * * @param dataMap 数据map * @param analysisContext 上下文 */ @Override public void invoke(Map<Integer, String> dataMap, AnalysisContext analysisContext) { List<String> line = new ArrayList<>(); for (Integer key : dataMap.keySet()) { String value = dataMap.get(key); if (StringUtils.isEmpty(value)) { value = ""; } line.add(value); } data.getDatas().add(line); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } public SheetData getData() { return data; } public void setData(SheetData data) { this.data = data; } }
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.chenwc.easyexcel.entity.SheetData; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.FileInputStream; import java.io.InputStream; /** * EasyExcel工具类 */ public class ExcelTool { private static final Logger log = LoggerFactory.getLogger(ExcelTool.class); /** * 根据流读取excel文件指定下标的sheet * @param is 文件流 * @param sheetIndex sheet下标 * @return 表格数据 */ public static SheetData read(InputStream is, int sheetIndex) { ArrayDataListener arrayDataListener = new ArrayDataListener(); EasyExcel.read(is, arrayDataListener).sheet(sheetIndex).doRead(); return arrayDataListener.getData(); } /** * 读取 excel文件 sheet 0 * @param path 文件路径 * @return 表格数据 */ public static SheetData read(String path) { return read(path, 0); } /** * 读取指定sheet页的excel文件 * @param path 文件路径 * @param sheetIndex sheet下标 * @return 表格数据 */ public static SheetData read(String path, int sheetIndex){ log.info("开始读取文件..........."); long start = System.currentTimeMillis(); log.info("读取表格文件: {} 第 {} 个 sheet 页内容", path, sheetIndex); FileInputStream fis = null; SheetData data = null; try { fis = new FileInputStream(path); data = read(fis, sheetIndex); }catch (Exception e){ e.printStackTrace(); }finally { try { if (null != fis){ fis.close(); } }catch (Exception e){ e.printStackTrace(); } } if (null != data){ log.info("读取数据行数为: {}", data.getDatas().size()); } log.info("读取文件结束..........."); long end = System.currentTimeMillis(); log.info("读取耗时: {} ms", (end - start)); return data; } /** * 往excel文件的sheet0写入数据 * @param path 文件路径 * @param data 待写入数据 */ public static void write(String path, SheetData data) { write(path, data, 0, null); } /** * 往excel文件的sheet0写入数据 * @param path 文件路径 * @param sheetName sheet页名称 * @param data 待写入数据 */ public static void write(String path, String sheetName, SheetData data) { write(path, data, 0, sheetName); } /** * 指定sheet下标往excel文件写入数据 * @param path 文件路径 * @param data 待写入数据 * @param sheetIndex sheet页下标 * @param sheetName sheet页名称 */ public static void write(String path, SheetData data, int sheetIndex, String sheetName) { log.info("开始写入文件..........."); long start = System.currentTimeMillis(); log.info("往表格文件: {} 第 {} 个 sheet 页写入内容", path, sheetIndex); ExcelWriterBuilder excelWriter = EasyExcel.write(path); excelWriter.head(data.toExcelHeader()); if (StringUtils.isNotEmpty(sheetName)){ excelWriter.sheet(sheetIndex, sheetName).doWrite(data.toExcelData()); } else { excelWriter.sheet(sheetIndex).doWrite(data.toExcelData()); } log.info("写入文件结束..........."); long end = System.currentTimeMillis(); log.info("写入耗时: {} ms", (end - start)); } }
import com.chenwc.easyexcel.entity.SheetData; import com.chenwc.easyexcel.utils.ExcelTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; public class Main { private static final Logger log = LoggerFactory.getLogger(Main.class); public static void main(String[] args) { //读数据 String path = "D:\\Desktop\\新建文件夹\\工作簿1.xlsx"; SheetData data = ExcelTool.read(path, 0); List<Map<String, String>> dataMapList = data.getDataMapList(); for (Map<String, String> row : dataMapList) { log.info("供应商ID: {}\t供应商名: {}", row.get("供应商ID"), row.get("供应商名")); } //写数据 String writePath = "D:\\Desktop\\新建文件夹\\测试写入Excel.xlsx"; List<String> header = new ArrayList<>(); header.add("A列"); header.add("B列"); header.add("C列"); List<Map<String, String>> writeDataMapList = new ArrayList<>(); for (int i = 0; i < 100; i++){ Map<String, String> row = new HashMap<>(); row.put("A列", String.valueOf(System.currentTimeMillis())); row.put("B列", "aaaaaasasa" + UUID.randomUUID()); row.put("C列", String.valueOf(new Random(1))); writeDataMapList.add(row); } SheetData writeData = new SheetData(); writeData.setHeader(header); writeData.setDataMapList(writeDataMapList); ExcelTool.write(writePath, "测试sheet", writeData); } }
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; public class ExcelDataListener extends AnalysisEventListener<Map<Integer, String>> { private static final Logger log = LoggerFactory.getLogger(ExcelDataListener.class); /** * 每隔100条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 100; //行数 private int rows = 0; //表头 private List<String> header = new ArrayList<String>(); //缓存的数据 private List<Map<String, String>> list = new ArrayList<Map<String, String>>(); /** * 这里会返回表头 * * @param headMap 表头map * @param context 上下文 */ @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { this.rows++; for (Integer key : headMap.keySet()) { this.header.add(headMap.get(key)); } log.info("表头: {}", this.header); } /** * 这个每一行数据解析都会来调用 * * @param data 一行数据 * @param context 上下文 */ @Override public void invoke(Map<Integer, String> data, AnalysisContext context) { this.rows++; Map<String, String> row = new HashMap<>(); for (int i = 0; i < this.header.size(); i++) { String key = this.header.get(i); row.put(key, data.get(i)); } this.list.add(row); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (this.list.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list this.list = new ArrayList<>(BATCH_COUNT); } } /** * 所有数据解析完成了 都会来调用 * * @param context 上下文 */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); log.info("所有数据解析完成!"); } /** * 存储数据 */ private void saveData() { log.info("待处理数据: {}", list); log.info("保存 {} 条数据。", list.size()); } }
package com.chenwc.easyexcel; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelReader; import com.alibaba.excel.read.metadata.ReadSheet; import com.chenwc.easyexcel.utils.ExcelDataListener; public class Main2 { public static void main(String[] args) { // TODO 自动生成的方法存根 String path = "D:\\Downloads\\BA417F37CA3342AE8DBA26C0A1C7AF09.xlsx"; // 一个文件一个reader ExcelReader excelReader = null; try { ExcelDataListener listener = new ExcelDataListener(); excelReader = EasyExcel.read(path, listener).build(); // 构建一个sheet 这里可以指定名字或者no ReadSheet readSheet = EasyExcel.readSheet(0).build(); // 读取一个sheet excelReader.read(readSheet); } finally { if (excelReader != null) { // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 excelReader.finish(); } } } }
log4j.rootLogger=info,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %-5p %-5L --- [%-5t] %-10c : %m %n
commons-codec-1.13.jar
commons-collections4-4.4.jar
commons-compress-1.19.jar
commons-csv-1.8.jar
commons-io-2.11.0.jar
commons-lang3-3.12.0.jar
commons-math3-3.6.1.jar
curvesapi-1.06.jar
easyexcel-3.1.3.jar
easyexcel-core-3.1.3.jar
easyexcel-support-3.1.3.jar
ehcache-3.9.9.jar
poi-4.1.2.jar
poi-ooxml-4.1.2.jar
poi-ooxml-schemas-4.1.2.jar
SparseBitSet-1.2.jar
xmlbeans-3.1.0.jar
log4j-1.2.17.jar
slf4j-api-1.7.36.jar
slf4j-log4j12-1.7.7.jar