基于EasyExcel实现百万级数据导入导出_easyexcel导出百万级数据-CSDN博客
百万数据导入导出:
想要解决问题我们首先要明白自己遇到的问题是什么?1、 我遇到的数据量超级大,使用传统的POI方式来完成导入导出很明显会内存溢出,并且效率会非常低;
2、 数据量大直接使用select * from tableName肯定不行,一下子查出来300w条数据肯定会很慢;
3、 300w 数据导出到Excel时肯定不能都写在一个Sheet中,这样效率会非常低;估计打开都得几分钟;
4、 300w数据导出到Excel中肯定不能一行一行的导出到Excel中。频繁IO操作绝对不行;
5、 导入时300万数据存储到DB如果循环一条条插入也肯定不行;
6、导入时300w数据如果使用Mybatis的批量插入肯定不行,因为Mybatis的批量插入其实就是SQL的循环;一样很慢。
解决思路:
针对1 :
其实问题所在就是内存溢出,我们只要使用对上面介绍的POI方式即可,主要问题就是原生的POI解决起来相当麻烦。经过查阅资料翻看到阿里的一款POI封装工具EasyExcel,上面问题等到解决;
针对2:
不能一次性查询出全部数据,我们可以分批进行查询,只不过时多查询几次的问题,况且市面上分页插件很多。此问题好解决。针对3:
可以将300w条数据写到不同的Sheet中,每一个Sheet写一百万即可。针对4:
不能一行一行的写入到Excel上,我们可以将分批查询的数据分批写入到Excel中。(官方文档:注意 simpleWrite在数据量不大的情况下可以使用(5000以内,具体也要看实际情况),数据量大参照 重复多次写入)写Excel | Easy Excel针对5:
导入到DB时我们可以将Excel中读取的数据存储到集合中,到了一定数量,直接批量插入到DB中。针对6:
不能使用Mybatis的批量插入,我们可以使用JDBC的批量插入,配合事务来完成批量插入到DB。即 Excel读取分批+JDBC分批插入+事务。
————————————————
版权声明:本文为CSDN博主「llp1110」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44981526/article/details/128738042
Excel常用的几种方法:POI,jxls,easypoi,easyexcel
史上最全的excel读写技术分享_烟花散尽13141的博客-CSDN博客_aftercelldispose
1:Easypoi实现导入导出excel:
EasyPoi实现excel文件导入导出_crysw的博客-CSDN博客_easypoi excel导入
public class OfficialExcelUtil {
public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) {
ExportParams exportParams = new ExportParams();
exportParams.setCreateHeadRows(isCreateHeader);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
if (workbook != null) ;
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
workbook.write(response.getOutputStream());
} catch (IOException e) {
try {
throw new Exception(e.getMessage());
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
Easypoi支持二进制导出图片
//实体字段
private byte[] oilCostRecord;
//下载后下来后转成字节
Result result = systemMinioProvider.downloadBase64(record.getRecord());
String split = result.getData().toString().split("base64,")[1];
byte[] decode = Base64.getDecoder().decode(split);
ExcelVo.setRecord(decode);
//调用导出
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
2:Easyexcel实现导入导出excel:
EasyExcel官方文档
通过实现CellWriteHandler接口,处理WPS打开Excel之后,不识别对应的类型:
EasyExcel 导出 excel 后无法实现日期筛选与数值类型合计问题与解决_easyexcel 数值型-CSDN博客
Easyexcel导出导入字段展示类型转换问题解决:(拦截器实现:注解或者注册拦截器)
合并单元格问题处理:
EasyExcel导入存在合并单元格的Excel_easyexcel导入合并单元格_我可能在扯淡的博客-CSDN博客
EasyExcel模板导出(行和列自动合并)_easyexcel 模板导出_Lzfnemo2009的博客-CSDN博客(牛逼)
EasyExcel导出合并单元格_easyexcel合并单元格_是一个菜鸟程序员啊的博客-CSDN博客
https://www.jb51.net/article/258822.htm EasyExcel工具读取Excel空数据行问题的解决办法
EasyExcel实现Excel文件导入导出_crysw的博客-CSDN博客_easyexcel
3:Java导出复杂数据到Excel(apache poi)(使用反射获取bean的get方法获取值)
https://blog.csdn.net/hjf_1291030386/article/details/75288220
4:HuTool工具包导入导出excel
Hutool参考文档
@Slf4j
@Component
public class ExcelExportHandler {
/**
* 下载Excel格式的数据
*
* @param response response
* @param fileName 文件名(支持中文)
* @param data 待下载的数据
* @param map key 为对象中的字段名 value 为表头展示的文字
* @param <T> 数据泛型
*/
public static <T> void export(HttpServletResponse response, String fileName,
List<T> data, LinkedHashMap<String,String> map) throws IOException {
ExcelWriter writer = ExcelUtil.getWriter();
// 数据为空,打印表头
if (CollectionUtil.isEmpty(data)){
writer.writeHeadRow(map.values());
}
for(String str : map.keySet()){
writer.addHeaderAlias(str,map.get(str));
}
writer.setColumnWidth(-1, 30);
writer.setRowHeight(-1, 20);
writer.write(data,true);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset:utf-8");
fileName= URLEncoder.encode(fileName,"UTF-8");
response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
ServletOutputStream outputStream= response.getOutputStream();
writer.flush(outputStream,true);
outputStream.close();
writer.close();
}
}
5:若依导出使用Field.get(object)获取bean字段的值(apache poi)(Field.get(obj)取得对象obj的Field属性值)
(8条消息) Springboot导出EXCEl方法(若依实例)_星光榴莲鸡的博客-CSDN博客_springboot导出excel表格
6:Java根据模板导出excel(jxls.poi) easyexcel easypoi jxls都支持模板导出
问题1:
使用fileName = URLEncoder.encode(fileName, "UTF-8");偶尔不生效时,使用下面方法解决中文乱码问题。
JAVA输出EXCEL文件名中文乱码解决
response.setCharacterEncoding(“UTF-8”);
String filename = new String( “明细记录”.getBytes(“utf-8” ), “ISO8859-1” );
response.setHeader(“Content-disposition”, “attachment; filename=”+filename+".xls");// 设定输出文件头
response.setContentType(“application/msexcel”);// 定义输出类型
————————————————
版权声明:本文为CSDN博主「weixin_43972670」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43972670/article/details/120525642
问题2:
说法1:
注意导出的controller中,不能有返回值,改为void,防止IO流冲突。
说法2:
controller添加返回值json后报错。
结论:下载文件时controller方法只能返回null或者void。
原因:因为response已经输出了,无论你返回不返回都没啥用了
解决方法:导出的接口调用返回null
@GetMapping("/exportIMO/year")
public ResponseResult exportImo(HttpServletResponse response, @RequestParam Integer year){
Date firstDate = DateUtil.getYearFirst(year);
Date lastDate = DateUtil.getAfterDay(DateUtil.getYearLast(year));
if (!iImoVoyageService.isBeginPeriodOil(firstDate, lastDate)){
return ResponseResult.fail("查询的开始时间和结束时间的期初存油均不能为空");
}else {
try {
iImoVoyageService.exportIMOVoyageData(response,firstDate,lastDate,"1");
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
(8条消息) Java实现根据excel模板导出数据(适合导出结构复杂的excel)_名字看着办的博客-CSDN博客_java根据模板导出excel
7:百万数据量时,导出操作
使用EasyExcel实现excel导出,支持百万大数据量导出-----超简单_easyexcel导出大量数据_MCP~的博客-CSDN博客