环境介绍
技术栈 | springboot+mybatis-plus+mysql+easyexcel |
---|---|
软件 | 版本 |
mysql | 8 |
IDEA | IntelliJ IDEA 2022.2.1 |
JDK | 1.8 |
Spring Boot | 2.7.13 |
mybatis-plus | 3.5.3.2 |
EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
npm install yarn -g
#检查版本
yarn --version
#配置Yarn
yarn config set registry https://registry.npm.taobao.org -g
yarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/ -g
#检查源
yarn config get registry
yarn config get sass_binary_site
#Yarn的常用命令
yarn init // 生成package.json文件
yarn i // 安装yarn.lock的所有依赖
yarn i --force // 重新安装依赖
yarn remove moduleName // 删除依赖
yarn add moduleName // 安装某个依赖
yarn add moduleName --dev/-D // 安装到开发环境
yarn run scriptName // 执行package.json命名的脚本命令
加入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
@TableName(value ="product")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {
/**
* 序号_自动生成
*/
@TableId(type = IdType.AUTO)
@ExcelProperty("序号")
private Integer number;
/**
* 创建时间
*/
@ExcelProperty("创建时间")
private Date createtime;
/**
* 产品名称
*/
@ExcelProperty("产品名称")
private String productname;
/**
* 产品编号
*/
@ExcelProperty("产品编号")
private String productnumber;
/**
* 产品型号
*/
@ExcelProperty("产品型号")
private String manufacturer;
/**
* 产品位置
*/
@ExcelProperty("产品位置")
private String producepath;
/**
* 图片位置
*/
@ExcelProperty("图片位置")
private String imagepath;
/**
* 使用单位
*/
@ExcelProperty("使用单位")
private String unit;
/**
* 金额
*/
@ExcelProperty("金额")
private Integer money;
/**
* 入库时间
*/
@ExcelProperty("入库时间")
private Date intime;
/**
* 出库时间
*/
@ExcelProperty("出库时间")
private Date puttime;
/**
* 操作人
*/
@ExcelProperty("操作人")
private String operator;
/**
* 创建人
*/
@ExcelProperty("创建人")
private String createduser;
/**
* 备注
*/
@ExcelProperty("备注")
private String notes;
/**
* 产品数量
*/
@ExcelProperty("产品数量")
private Integer producedigit;
/**
* 产品单位
*/
@ExcelProperty("产品单位")
private String productunit;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
使用官方默认提供的监听器
@Test
public void simpleRead() {
//String fileName = TestFileUtil.getPath() + "simpleWriteTest1702391756908.xlsx";
String fileName = "C:\\Users\\1111\\Desktop\\simpleWriteTest1702391756908.xlsx";
// 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
// 具体需要返回多少行可以在`PageReadListener`的构造函数设置
EasyExcel.read(fileName, Product.class, new PageReadListener<Product>(dataList -> {
for (Product product : dataList) {
System.out.println(product);
//log.info("读取到一条数据{}", JSON.toJSONString(product));
}
})).sheet().doRead();
}
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 TestPathBuild pathBuild() {
return new TestPathBuild();
}
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);
}
/**
* build to test file path
**/
public static class TestPathBuild {
private TestPathBuild() {
subPath = new ArrayList<>();
}
private final List<String> subPath;
public TestPathBuild sub(String dirOrFile) {
subPath.add(dirOrFile);
return this;
}
public String getPath() {
if (CollectionUtils.isEmpty(subPath)) {
return TestFileUtil.class.getResource("/").getPath();
}
if (subPath.size() == 1) {
return TestFileUtil.class.getResource("/").getPath() + subPath.get(0);
}
StringBuilder path = new StringBuilder(TestFileUtil.class.getResource("/").getPath());
path.append(subPath.get(0));
for (int i = 1; i < subPath.size(); i++) {
path.append(File.separator).append(subPath.get(i));
}
return path.toString();
}
}
}
@TableName(value ="product")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {
/**
* 序号_自动生成
*/
@TableId(type = IdType.AUTO)
@ExcelProperty("序号")
private Integer number;
/**
* 创建时间
*/
@ExcelProperty("创建时间")
private Date createtime;
/**
* 产品名称
*/
@ExcelProperty("产品名称")
private String productname;
/**
* 产品编号
*/
@ExcelProperty("产品编号")
private String productnumber;
/**
* 产品型号
*/
@ExcelProperty("产品型号")
private String manufacturer;
/**
* 产品位置
*/
@ExcelProperty("产品位置")
private String producepath;
/**
* 图片位置
*/
@ExcelProperty("图片位置")
private String imagepath;
/**
* 使用单位
*/
@ExcelProperty("使用单位")
private String unit;
/**
* 金额
*/
@ExcelProperty("金额")
private Integer money;
/**
* 入库时间
*/
@ExcelProperty("入库时间")
private Date intime;
/**
* 出库时间
*/
@ExcelProperty("出库时间")
private Date puttime;
/**
* 操作人
*/
@ExcelProperty("操作人")
private String operator;
/**
* 创建人
*/
@ExcelProperty("创建人")
private String createduser;
/**
* 备注
*/
@ExcelProperty("备注")
private String notes;
/**
* 产品数量
*/
@ExcelProperty("产品数量")
private Integer producedigit;
/**
* 产品单位
*/
@ExcelProperty("产品单位")
private String productunit;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
private List<Product> getData(int count) {
List<Product> list = ListUtils.newArrayList();
for (int i = 0; i < count; i++) {
Product product = new Product();
product.setCreatetime(new Date());
product.setProductname("服务器00"+i);
product.setProductnumber(DigestUtils.md5Hex("hello"+i));
product.setManufacturer("huawei");
product.setProducepath("/test");
product.setImagepath("/test");
product.setIntime(new Date());
product.setOperator("张三");
product.setPuttime(new Date());
list.add(product);
}
return list;
}
@Test
public void simpleWrite() {
// 写法2
String fileName = TestFileUtil.getPath() + "simpleWriteTest" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName, Product.class).sheet("测试01").doWrite(getData(10));
}
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模式,在上层做了模型转换的封装,让使用者更加简单方便
Excel导入导出的应用场景
数据导入:减轻录入工作量
数据导出:统计信息归档
数据传输:异构系统之间数据传输
EasyExcel是开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。