EasyExcel导入导出样式、自适应列宽、自适应行高
一、先加依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency>
二、话不多说,直接先看导出样式设置,可以根据自己实际情况调整:
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;public class EasyExcelUtils {/*** 设置excel样式*/public static HorizontalCellStyleStrategy getStyleStrategy() {// 头的策略 样式调整WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 头背景 浅绿headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());WriteFont headWriteFont = new WriteFont();// 头字号headWriteFont.setFontHeightInPoints((short) 12);// 字体样式headWriteFont.setFontName("宋体");headWriteCellStyle.setWriteFont(headWriteFont);// 自动换行headWriteCellStyle.setWrapped(true);// 设置细边框headWriteCellStyle.setBorderBottom(BorderStyle.THIN);headWriteCellStyle.setBorderLeft(BorderStyle.THIN);headWriteCellStyle.setBorderRight(BorderStyle.THIN);headWriteCellStyle.setBorderTop(BorderStyle.THIN);// 设置边框颜色 25灰度headWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());headWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());headWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());headWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());// 水平对齐方式headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 垂直对齐方式headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 内容的策略 宋体WriteCellStyle contentStyle = new WriteCellStyle();// 设置垂直居中contentStyle.setWrapped(true);contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 设置 水平居中
// contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);WriteFont contentWriteFont = new WriteFont();// 内容字号contentWriteFont.setFontHeightInPoints((short) 12);// 字体样式contentWriteFont.setFontName("宋体");contentStyle.setWriteFont(contentWriteFont);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现return new HorizontalCellStyleStrategy(headWriteCellStyle, contentStyle);}
}
三、自适应列宽
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class CustomCellWriteWidthConfig extends AbstractColumnWidthStyleStrategy {private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);if (needSetWidth) {Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());Integer columnWidth = this.dataLength(cellDataList, cell, isHead);// 单元格文本长度大于60换行if (columnWidth >= 0) {if (columnWidth > 60) {columnWidth = 60;}Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());if (maxColumnWidth == null || columnWidth > maxColumnWidth) {maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);Sheet sheet = writeSheetHolder.getSheet();sheet.setColumnWidth(cell.getColumnIndex(), columnWidth * 256);}}}}/*** 计算长度* @param cellDataList* @param cell* @param isHead* @return*/private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {if (isHead) {return cell.getStringCellValue().getBytes().length;} else {CellData<?> cellData = cellDataList.get(0);CellDataTypeEnum type = cellData.getType();if (type == null) {return -1;} else {switch (type) {case STRING:// 换行符(数据需要提前解析好)int index = cellData.getStringValue().indexOf("\n");return index != -1 ?cellData.getStringValue().substring(0, index).getBytes().length + 1 : cellData.getStringValue().getBytes().length + 1;case BOOLEAN:return cellData.getBooleanValue().toString().getBytes().length;case NUMBER:return cellData.getNumberValue().toString().getBytes().length;default:return -1;}}}}
}
四、自适应行高
import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;import java.util.Iterator;public class CustomCellWriteHeightConfig extends AbstractRowHeightStyleStrategy {/*** 默认高度*/private static final Integer DEFAULT_HEIGHT = 300;@Overrideprotected void setHeadColumnHeight(Row row, int relativeRowIndex) {}@Overrideprotected void setContentColumnHeight(Row row, int relativeRowIndex) {Iterator<Cell> cellIterator = row.cellIterator();if (!cellIterator.hasNext()) {return;}// 默认为 1行高度int maxHeight = 1;while (cellIterator.hasNext()) {Cell cell = cellIterator.next();if (cell.getCellTypeEnum() == CellType.STRING) {String value = cell.getStringCellValue();int len = value.length();int num = 0;if (len > 50) {num = len % 50 > 0 ? len / 50 : len / 2 - 1;}if (num > 0) {for (int i = 0; i < num; i++) {value = value.substring(0, (i + 1) * 50 + i) + "\n" + value.substring((i + 1) * 50 + i, len + i);}}if (value.contains("\n")) {int length = value.split("\n").length;maxHeight = Math.max(maxHeight, length) + 1;}}}row.setHeight((short) ((maxHeight) * DEFAULT_HEIGHT));}
}
五、导出
- 先创建导出实体类
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.terton.aisp.ssp.entity.Feedback;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
@ExcelIgnoreUnannotated // 只导出带有ExcelProperty注解的字段
public class ExcelFeedbackVO extends Feedback {/*** 站点ID*/// 设置表头名称 ,索引最好带上,不会出问题。@ExcelProperty(value = "站点id", index = 0)private String siteId;/*** 搜索内容*/@ExcelProperty(value = "搜索内容", index = 1)private String title;/*** 反馈内容*/@ExcelProperty(value = "反馈内容", index = 2)private String content;/*** IP地址*/@ExcelProperty(value = "搜索IP", index = 3)private String ip;}
2、创建一个对外暴露的接口。
@PostMapping("/downloadBack")
public void downloadBack(HttpServletResponse response, String siteId, Integer content) throws TException, IOException {List<Feedback> list = feedbackService.searchBack(siteId, content);setResponse(response, "列表");EasyExcel.write(response.getOutputStream(), ExcelFeedbackVO.class /* 引用需要导出的字段*/).sheet("列表").registerWriteHandler(new CustomCellWriteWidthConfig()) /*自适应列宽*/.registerWriteHandler(new CustomCellWriteHeighConfig()) /*自适应行高(根据自己情况选择使用,我这里没用到)*/.registerWriteHandler(EasyExcelUtils.getStyleStrategy()) /*引用样式*/.doWrite(list); /* 想到导出模板的话,此处给一个空的集合就好*/}
3、设置响应体信息(由于我这个项目导入导出比较多,把此方法变成公共方法)
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;public class SetResponse {/*** 导出设置响应信息** @param response 响应*/public static void setResponse(HttpServletResponse response,String fileName) {// 文件名String sheetName = URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ".xlsx";// contentType 响应内容的类型response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 设置字符response.setCharacterEncoding("utf-8");// 设置文件名response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + sheetName);}}
4、访问接口
模板
![](/assets/blank.gif)
正常导出
![](/assets/blank.gif)
六、导入
1、监听器(关键)
注意事项:监听器里面不能使用注入的形式将service注入进来,所以可以使用构造器
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.terton.aisp.common.enums.ExcelNameModelEnum;
import com.terton.aisp.common.util.PingYinUtil;
import com.terton.aisp.word.entity.MassWord;
import com.terton.aisp.word.enums.UploadBatchCountEnum;
import com.terton.aisp.word.service.IMassWordService;
import com.terton.aisp.word.service.impl.MassWordServiceImpl;
import com.terton.aisp.word.vo.ExcelMassWordModelVO;
import com.terton.framework.util.StringUtil;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class UploadMassWordListener extends AnalysisEventListener<ExcelMassWordModelVO> {private IMassWordService massWordService;private String siteId;private Integer wordLevel;private String userName;private List<ExcelMassWordModelVO> list = new ArrayList<>();private List<String> massWordList = new ArrayList<>();private List<String> massWords = new ArrayList<>();private Integer successNum = 0;private Integer errorNum = 0;/*** 表头校验 此方法里面可进行对导入的excel的格式进行判断,先执行*/@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {// headMap 表头数据,拿出进行判断就好}/*** 每读一行触发一次 ** @param modelVO ”* @param analysisContext “*/@Overridepublic void invoke(ExcelMassWordModelVO modelVO, AnalysisContext analysisContext) {log.info("读取到一条数据:{}",modelVO)// 可以对数据进行判断是否有效。 根据自己的实际业务逻辑判断,// 判断完成的数据可以用一个List来接收// 为了防止数据过多,数据一直存在内存中,这里可以设置一个阈值,当list中的数据超过这个值,就先把这批数据添加到数据库。if (StringUtil.notBlankAndNull(modelVO.getMassWord()) && StringUtil.notBlankAndNull(modelVO.getTargetWord())) {if (!CollectionUtils.isEmpty(massWords) && massWords.contains(modelVO.getMassWord())) {throw new RuntimeException(ExcelNameModelEnum.FailImport.RESULT_FIELD.getText() + modelVO.getMassWord());}massWords.add(modelVO.getMassWord());massWordList.add(modelVO.getMassWord());list.add(modelVO);try {if (list.size() >= UploadBatchCountEnum.MASS_WORD.getCount() /*我这里阈值设置的是500*/) {save();}} catch (Exception e) {throw new RuntimeException(e.getMessage());}}}/*** 完毕触发** @param analysisContext ”*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 写数据库if (!CollectionUtils.isEmpty(list)) {save();}massWords.clear();log.info("成功写入数量:{}", successNum);log.info("失败写入数量:{}", errorNum);successNum = 0;errorNum = 0;}private void save() {try {List<MassWord> recordList = massWordService.getByMasswordsAndSiteId(massWordList, siteId);if (!CollectionUtils.isEmpty(recordList)) {List<String> collect = recordList.stream().map(MassWord::getMassWord).collect(Collectors.toList());if (!CollectionUtils.isEmpty(collect)) {throw new RuntimeException(ExcelNameModelEnum.FailImport.RESULT_FIELD.getText() + collect);}}for (ExcelMassWordModelVO wordModelVO : list) {MassWord newMassWord = getMassWord(wordModelVO);massWordService.save(newMassWord);successNum += 1;}} catch (Exception e) {errorNum += 1;throw new RuntimeException(e.getMessage());}massWordList.clear();list.clear();}private MassWord getMassWord(ExcelMassWordModelVO wordModelVO) {MassWord massWord = new MassWord();massWord.setMassWord(wordModelVO.getMassWord());massWord.setTargetWord(wordModelVO.getTargetWord());massWord.setWordLevel(wordLevel);massWord.setSiteId(siteId);massWord.setAcronym(PingYinUtil.getFirstSpell(wordModelVO.getMassWord()));massWord.setFullPinYin(PingYinUtil.getFullSpell(wordModelVO.getMassWord()));massWord.setCrTime(new Date());massWord.setCrUser(userName);return massWord;}public UploadMassWordListener(MassWordServiceImpl massWordService, String siteId,Integer wordLevel, String userName) {this.massWordService = massWordService;this.siteId = siteId;this.wordLevel = wordLevel;this.userName = userName;}}
2、导入与监听器的使用。
public void upload(MultipartFile file, String siteId, Integer wordLevel,String userName) throws IOException {UploadMassWordListener listener = new UploadMassWordListener(this, siteId, wordLevel, userName);EasyExcel.read(file.getInputStream(), ExcelMassWordModelVO.class, listener).sheet(0).headRowNumber(1).doRead();}
到这里大概就结束了,希望对你有用。
EasyExcel导入导出样式、自适应列宽、自适应行高相关推荐
- EasyExcel自适应列宽、行高、自动换行
一.自定义模版 二.工具类 import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.Cel ...
- easyexcel 列宽、行高、样式
easyexcel 列宽.行高.样式 ********************** 相关注解 HeadRowHeight:标注在类上 @Target({ElementType.TYPE}) @Rete ...
- excel2010设置列宽为像素_使用像素单位设置 EXCEL 列宽或行高
在导出 Excel 的时候, 经常要需要给列设置宽度或给行设置高度, 在使用 NPOI 或 EppPlus 等组件进行操作的时候, 列宽和行高的单位都不是像素, 好像是英寸,具体是啥也说不清. 平常在 ...
- python数字图像的行 宽的不同处 cv2.resize(1389,1500) p1列宽 p2 行高 stop2.shape 得(640,960,3) v1列宽 v2 行高 v3 通道数
python数字图像的行 宽的不同处 cv2.resize(1389,1500) p1列宽 p2 行高 stop2.shape 得(640,960,3) v1列宽 v2 行高 v3 通道数
- 基于tabular包的Latex表格尺寸设置方法(列宽和行高)
基于tabular包的Latex表格尺寸设置方法(列宽和行高) tabel语法的小技巧 设置表格的说明文字时,有的场合要求说明文字在表格下方,有的要求说明文字在表格上方,该怎么调整呢? 只需要把\ca ...
- datagridvie设置行高列宽_DataGridView 列宽和行高自动调整的设定
DataGridView 列宽和行高自动调整的设定 一.设定行高和列宽自动调整 1 .设定包括 Header 和所有单元格的列宽自动调整 DataGridView1.AutoSizeColumnsMo ...
- DataGridView自动设定列宽和行高
这篇文章介绍了DataGridView自动设定列宽和行高的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 设定行高和列宽自动调整 设定包括Header和所有 ...
- 调整Word表格的列宽和行高(转)
调整Word表格的列宽和行高(转) 创建表格时,Word表格的列宽往往采用默认值,我们可以对其进行修改.根据不同的需要,有四种调整方法可供选择使用: 一.利用鼠标左键在分隔线上拖动. 二.利用鼠标左键 ...
- Microsoft Excel 教程:如何在 Excel 中更改列宽或行高?
欢迎观看 Microsoft Excel 教程,小编带大家学习 Microsoft Excel 的使用技巧,了解如何在 Excel 中更改列宽或行高. 可以手动调整列宽或行高,或者自动调整列和行的大小 ...
最新文章
- 集成学习算法之boosting、bagging和随机森林算法原理
- SEO十心要诀 细节决定成败
- codeforces 706B B. Interesting drink(二分)
- linux文件管理系统开发毕业,定稿毕业论文基于Linux的远程管理系统服务器端的实现word文档(范文1)...
- 动态规划:openjudge 2.6-3532 最大上升子序列和 解题心得
- 随机过程及其在金融领域中的应用 第三章 习题 及 答案
- 重读读书笔记的重要性
- 中国酒精炉行业市场供需与战略研究报告
- ROS的学习(十六)用C++写一个简单的服务器(service)和客户端(client)
- POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
- python dlib opencv人脸识别准确度_Dlib+OpenCV深度学习人脸识别
- vue-(prop验证-个人名片)
- 【SmartSvn】分支合并问题
- 数据库恢复时出现诸如“设备激活错误
- 《Charles配置教程之Mac》
- HDU 4435 charge-station (搜索+YY)
- SwapMix: Diagnosing and Regularizing the Over-Reliance on Visual Context in ... ——2022 CVPR 论文笔记
- java实现PDF转图片功能,附实例源码!
- 【北邮国院大二下】产品开发与营销知识点整理 Topic7
- 《西瓜书》阅读笔记——第四章
热门文章
- 微信中打开被链接提示浏览器打开页面下载APP的实现方法与隐藏投诉举报按钮的实现演示
- 比拼多多更变态的模式,邀请6个人就能赚几万,这个点子绝了
- 2 shell 锂基脂_【壳牌爱万利EP2润滑脂/Shell Alvania EP2锂基脂/黄油】价格_厂家 - 中国供应商...
- Python数据清洗之Dataframe中不同分隔符数据的清洗
- vue+elementui 项目 table表格自定义排序规则
- 【shell脚本】沐风晓月跟你聊聊shell脚本中的case实战
- 遨游四维时空 MapGIS 10.6全空间一张图新升级
- word为公式自动插入编号的方法
- Python pandas.DataFrame.tail函数方法的使用
- 2021-09-18多颜色诗词