通过自定义拦截器优雅的导出Excel并标红的重复数据
平时我们导入导出Excel的时候如果用poi导出,会发现光设置格式都要很多代码,看起来非常的不优雅。后来业务中遇到了需要导入非常巨大的Excel的需求。如果继续用poi的方式,因为poi把所有excel数据都缓存到内存中,服务器资源又是有限的,所以就有可能导致内存溢出,为了解决这个问题,我发现阿里的EasyExcel导出可以完美的解决这个问题,并且实现方式更加优雅。
如果业务中需要标红重复的数据,先列一下大致代码。
/**
* 导出重复的数据
*
* @param planId
* @param stream
* @param tenaId
* @param fileId
* @param response
* @throws IOException
*/
public void screeningExport(Long planId, InputStream stream, Long tenaId, Long fileId, HttpServletResponse response) throws IOException { response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("重复项", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), ScreeningEasyExcelVo.class)
.registerWriteHandler(new CustomCellWriteHandle())
.sheet("模板" + Constant.fileIdSeparator + fileId).doWrite(data(stream, planId, tenaId, fileId)); }
大致的来说,就是我们传入excel文件流,和对应的业务字段就可以导出了。
但是如果想标红某一单元格的数据,那我们就需要自己定义拦截器,同时我们需要知道到底是哪行是重复的,具体校验重复行就不在这里写了,
得到重复行之后,我们把行数存入redis,并且在拦截器中和excel中的行数做对比,如果验证为同一行,那我们就可以对这一行做标红处理,
具体的代码如下
package com.guantong.seeing.screening.common; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.guantong.seeing.screening.util.SpringContextHelper;
import org.apache.poi.ss.usermodel.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils; import java.util.List;
import java.util.stream.Stream; /**
* @author cuixinxin
* @desc easyExcel 自定义拦截器
*/
public class CustomCellWriteHandle implements CellWriteHandler { public CustomCellWriteHandle() {
} @Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { } @Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
} /**
* 重写单元格格式--》通过修改每一个单元格格式达到整列标红的效果
* @param writeSheetHolder
* @param writeTableHolder
* @param list
* @param cell
* @param head
* @param integer
* @param aBoolean
*/
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) { Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
CellStyle cellStyle = cellStyle(workbook);
//根据校验结果设置单元格文字颜色
String sheetName = writeSheetHolder.getSheet().getSheetName();
Long fileId = Long.valueOf(sheetName.substring(sheetName.indexOf(Constant.fileIdSeparator) + 8));
writeSheetHolder.setSheetName(sheetName.substring(0, sheetName.indexOf(Constant.fileIdSeparator)));
int rowIndex = cell.getRowIndex();
if (isExistRepeatData(rowIndex, fileId)) {
//设置单元格背景色
Font font = workbook.createFont();
font.setColor(IndexedColors.RED.getIndex());
cellStyle.setFont(font);
} cell.setCellStyle(cellStyle);
} private boolean isExistRepeatData(Integer rowNow, Long fileId) {
StringRedisTemplate stringRedisTemplate = SpringContextHelper.getBean(StringRedisTemplate.class);
String value = stringRedisTemplate.opsForValue().get(fileId.toString());
if (StringUtils.isEmpty(value)) {
return false;
}
return Stream.of(value.split(","))
.anyMatch(k -> k.equals(rowNow.toString())); } /**
* 通用样式
*
* @param workbook
* @return
*/
public static CellStyle cellStyle(Workbook workbook) {
CellStyle cellStyle = workbook.createCellStyle();
//居中
cellStyle.setAlignment(HorizontalAlignment.LEFT);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
//设置边框
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
return cellStyle; }
}
整体来看,代码逻辑分工更加清晰,只有标红的拦截器和获取数据以及导出三部分,更加优雅
通过自定义拦截器优雅的导出Excel并标红的重复数据的更多相关文章
- Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解)
不多说,直接上干货! 一.自定义拦截器类型必须是:类全名$内部类名,其实就是内部类名称 如:zhouls.bigdata.MySearchAndReplaceInterceptor$Builder 二 ...
- Mybatis自定义拦截器与插件开发
在Spring中我们经常会使用到拦截器,在登录验证.日志记录.性能监控等场景中,通过使用拦截器允许我们在不改动业务代码的情况下,执行拦截器的方法来增强现有的逻辑.在mybatis中,同样也有这样的业务 ...
- spring mvc <mvc:annotation-driven/> 自定义拦截器不走
<mvc:annotation-driven/> 这个便签会注册2个自定义拦截器,所以导致请求过来就会自己去走注册的这2个拦截器和定义的一堆bean 但是这个便签是必须得定义的 直接贴代码 ...
- 12.Struts2自定义拦截器
12.自定义拦截器 拦截器是Struts2的一个重要特性.因为Struts2的大多数核心功能都是通过拦截器实现的. 拦截器之所以称之为“拦截器”,是因为它可以拦截Action方法的执行, ...
- 【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】
一.struts2文件上传 1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post 2.上传单个文件的时候需要在Act ...
- SpringMVC——自定义拦截器、异常处理以及父子容器配置
自定义拦截器: 一.若想实现自定义拦截器,需要实现 org.springframework.web.servlet.HandlerInterceptor 接口. 二.HandlerIntercepto ...
- Struts2 自定义拦截器
自定义拦截器(权限管理),包含了对ajax和表单请求的拦截 package com.interceptor; import java.io.IOException; import java.io.Pr ...
- Struts2自定义拦截器
1. 需求 自定义拦截器实现,用户登录的访问控制. 2. 定义拦截器类 public class LoginInterceptor extends AbstractInterceptor { @Ove ...
- SpringMvc自定义拦截器
SpringMvc也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义拦截器必须实现HandlerInterceptor接口 -preHandle():这个方法在业务处理器 ...
随机推荐
- 20200726_java爬虫_使用HttpClient模拟浏览器发送请求
浏览器获取数据: 打开浏览器 ==> 输入网址 ==> 回车查询 ==> 返回结果 ==> 浏览器显示结果数据 HttpClient获取数据: 创建HttpClient ==& ...
- ERROR: No matching distribution found for cv2
ImportError: No module named cv2和No matching distribution found for cv2的问题 原因 这个是由于没有导入opencv库导致的 解决 ...
- FloodFill算法详解及应用
啥是 FloodFill 算法呢,最直接的一个应用就是「颜色填充」,就是 Windows 绘画本中那个小油漆桶的标志,可以把一块被圈起来的区域全部染色. 这种算法思想还在许多其他地方有应用.比如说扫雷 ...
- 老大说新项目的结构和 xxx 项目一样就可以了,我 ……(使用 Maven Archetype 快速创建项目)
前言 又要开发新项目了,还是创建新项目,怎么办?老大说按照 xxx 项目的结构创建一个新项目就可以了. 公众号:liuzhihangs,记录工作学习中的技术.开发及源码笔记:时不时分享一些生活中的见闻 ...
- Flink的sink实战之一:初探
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Ros中创建msg和srv遇到的问题
在创建msg和srv文件之后,使用srv和msg文件时候需要对xml文件进行修改,如下: <build_depend>message_generation</build_depend ...
- js 元素添加多个监听
function addListener(element,e,fn){ if(element.addEventListener){ element.addEventListen ...
- 测试php
/** * 测试guzzle * * @return void */ public function index() { $client = new GuzzleHttp\Client(); //12 ...
- php xml转数组
<?php libxml_disable_entity_loader(true); $notify_values = json_decode(json_encode(simplexml_load ...
- python_for_else_return
def login(): # 登录 # 登录 输入用户名密码 # 和self.user_list作比对 while True: username = input('用户名 :') # password ...