1、导入依赖
cn.hutool
hutool-all
5.4.5
org.apache.poi
poi-ooxml
5.0.0
2、工具类 参考 (Hutools实现excel导出 - 简书)
本人使用中发现有一个bug 具体请看代码为59行 (已经修复)
package com.qr.management.util;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
/**
* @author lianJiaYu
* @date 2021/7/30 11:50
*/
public class ExcelByHuTools {
//private static final Logger logger = LoggerFactory.getLogger(ExcelByHuTools.class);
/**
* 导出文件
*
* @param request
* @param response
* @param fileName 文件名
* @param sheetName
* @param headers 表头
* @param data 数据
* @param
*/
public static void exportExcelByHuTools(HttpServletRequest request,
HttpServletResponse response,
String fileName,
String sheetName,
Map headers,
List data) {
long startTime = System.currentTimeMillis();
//通过工具类创建writer
try {
//创建writer
//ExcelWriter writer = ExcelUtil.getWriter();
//数据量特别大时,使用BigExcelWriter对象,可以避免内存溢出
ExcelWriter writer = ExcelUtil.getBigWriter();
//设置sheet的名称
writer.renameSheet(sheetName);
//设置head的名称, 此时的顺寻就是导出的顺序, key就是RecordInfoDetailsDTO的属性名称, value就是别名
headers.entrySet().forEach(entry -> {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
//这个添加顺序和导出顺序相同
writer.addHeaderAlias(entry.getKey(), entry.getValue());
});
//设置宽度 0代表第一列 1代表第二列 以此类推
writer.setColumnWidth(1,30);
writer.setColumnWidth(4,30);
/**
* 设置是否只保留别名中的字段值,如果为true,则不设置alias的字段将不被输出,false表示原样输出
* 这一行很重要 如果不设置只要实体中的属性值 大于 “自定义标题别名” 在Excel中就会多出一列ID字段
*/
writer.setOnlyAlias(true);
writer.write(data, true);
response.reset();
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
//中文名称需要特殊处理
writer.flush(response.getOutputStream());
writer.close();
long endTime = System.currentTimeMillis();
System.out.println("hutool 写入记录耗时 " + (endTime - startTime) / 1000 + "秒");
} catch (Exception e) {
//如果导出异常,则生成一个空的文件
e.printStackTrace();
}
}
}
注释掉//writer.setOnlyAlias(true);的效果 会莫名其妙的多一行ID字段
3、数据库表和数据创建
CREATE TABLE `excel` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`age` int DEFAULT NULL,
`gender` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb3;
/*Data for the table `excel` */
insert into `excel`(`id`,`name`,`age`,`gender`) values (1,'小米',10,'女'),(2,'小兰',12,'女'),(3,'小刚',13,'男');
4、sql编写
5、实体类创建
package com.xyz.rescuetycoon.shopping.entity;
import lombok.Data;
@Data
public class Excel {
private long id;
private String name;
private long age;
private String gender;
}
6、Controller代码编写和调用
@RequestMapping("exportExcel")
public void exportExcel(HttpServletRequest request,
HttpServletResponse response) {
Map headers = new LinkedHashMap<>();
headers.put("id", "id");
headers.put("name", "姓名");
headers.put("age", "年龄");
headers.put("gender", "性别");
List excelList = menuMapper.queryExcel();
ExcelByHuTools.exportExcelByHuTools(request, response, "人员信息表", "sheet1", headers, excelList);
}
7、测试导出
测试四个字段100W条数据导出只需16秒
快速插入100W条数据可以参考以下文章
Mysql8.0使用存储过程 快速插入100W条数据_EvenBoy的博客-CSDN博客