当前位置:   article > 正文

EasyExcel导入导出样式、自适应列宽、自适应行高_easyexcel设置列宽自适应

easyexcel设置列宽自适应

一、先加依赖

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>easyexcel</artifactId>
  4. <version>3.1.1</version>
  5. </dependency>

、话不多说,直接先看导出样式设置可以根据自己实际情况调整

  1. import com.alibaba.excel.write.metadata.style.WriteCellStyle;
  2. import com.alibaba.excel.write.metadata.style.WriteFont;
  3. import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
  4. import org.apache.poi.ss.usermodel.BorderStyle;
  5. import org.apache.poi.ss.usermodel.HorizontalAlignment;
  6. import org.apache.poi.ss.usermodel.IndexedColors;
  7. import org.apache.poi.ss.usermodel.VerticalAlignment;
  8. public class EasyExcelUtils {
  9. /**
  10. * 设置excel样式
  11. */
  12. public static HorizontalCellStyleStrategy getStyleStrategy() {
  13. // 头的策略 样式调整
  14. WriteCellStyle headWriteCellStyle = new WriteCellStyle();
  15. // 头背景 浅绿
  16. headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
  17. WriteFont headWriteFont = new WriteFont();
  18. // 头字号
  19. headWriteFont.setFontHeightInPoints((short) 12);
  20. // 字体样式
  21. headWriteFont.setFontName("宋体");
  22. headWriteCellStyle.setWriteFont(headWriteFont);
  23. // 自动换行
  24. headWriteCellStyle.setWrapped(true);
  25. // 设置细边框
  26. headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
  27. headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
  28. headWriteCellStyle.setBorderRight(BorderStyle.THIN);
  29. headWriteCellStyle.setBorderTop(BorderStyle.THIN);
  30. // 设置边框颜色 25灰度
  31. headWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
  32. headWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
  33. headWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
  34. headWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
  35. // 水平对齐方式
  36. headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
  37. // 垂直对齐方式
  38. headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  39. // 内容的策略 宋体
  40. WriteCellStyle contentStyle = new WriteCellStyle();
  41. // 设置垂直居中
  42. contentStyle.setWrapped(true);
  43. contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  44. // 设置 水平居中
  45. // contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
  46. WriteFont contentWriteFont = new WriteFont();
  47. // 内容字号
  48. contentWriteFont.setFontHeightInPoints((short) 12);
  49. // 字体样式
  50. contentWriteFont.setFontName("宋体");
  51. contentStyle.setWriteFont(contentWriteFont);
  52. // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
  53. return new HorizontalCellStyleStrategy(headWriteCellStyle, contentStyle);
  54. }
  55. }

 三、自适应列宽

  1. import com.alibaba.excel.enums.CellDataTypeEnum;
  2. import com.alibaba.excel.metadata.Head;
  3. import com.alibaba.excel.metadata.data.CellData;
  4. import com.alibaba.excel.metadata.data.WriteCellData;
  5. import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
  6. import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
  7. import org.apache.commons.collections.CollectionUtils;
  8. import org.apache.poi.ss.usermodel.Cell;
  9. import org.apache.poi.ss.usermodel.Sheet;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. public class CustomCellWriteWidthConfig extends AbstractColumnWidthStyleStrategy {
  14. private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
  15. @Override
  16. protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
  17. boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
  18. if (needSetWidth) {
  19. Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());
  20. Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
  21. // 单元格文本长度大于60换行
  22. if (columnWidth >= 0) {
  23. if (columnWidth > 60) {
  24. columnWidth = 60;
  25. }
  26. Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
  27. if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
  28. maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
  29. Sheet sheet = writeSheetHolder.getSheet();
  30. sheet.setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
  31. }
  32. }
  33. }
  34. }
  35. /**
  36. * 计算长度
  37. * @param cellDataList
  38. * @param cell
  39. * @param isHead
  40. * @return
  41. */
  42. private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
  43. if (isHead) {
  44. return cell.getStringCellValue().getBytes().length;
  45. } else {
  46. CellData<?> cellData = cellDataList.get(0);
  47. CellDataTypeEnum type = cellData.getType();
  48. if (type == null) {
  49. return -1;
  50. } else {
  51. switch (type) {
  52. case STRING:
  53. // 换行符(数据需要提前解析好)
  54. int index = cellData.getStringValue().indexOf("\n");
  55. return index != -1 ?
  56. cellData.getStringValue().substring(0, index).getBytes().length + 1 : cellData.getStringValue().getBytes().length + 1;
  57. case BOOLEAN:
  58. return cellData.getBooleanValue().toString().getBytes().length;
  59. case NUMBER:
  60. return cellData.getNumberValue().toString().getBytes().length;
  61. default:
  62. return -1;
  63. }
  64. }
  65. }
  66. }
  67. }

四、自适应行高

  1. import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
  2. import org.apache.poi.ss.usermodel.Cell;
  3. import org.apache.poi.ss.usermodel.CellType;
  4. import org.apache.poi.ss.usermodel.Row;
  5. import java.util.Iterator;
  6. public class CustomCellWriteHeightConfig extends AbstractRowHeightStyleStrategy {
  7. /**
  8. * 默认高度
  9. */
  10. private static final Integer DEFAULT_HEIGHT = 300;
  11. @Override
  12. protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
  13. }
  14. @Override
  15. protected void setContentColumnHeight(Row row, int relativeRowIndex) {
  16. Iterator<Cell> cellIterator = row.cellIterator();
  17. if (!cellIterator.hasNext()) {
  18. return;
  19. }
  20. // 默认为 1行高度
  21. int maxHeight = 1;
  22. while (cellIterator.hasNext()) {
  23. Cell cell = cellIterator.next();
  24. if (cell.getCellTypeEnum() == CellType.STRING) {
  25. String value = cell.getStringCellValue();
  26. int len = value.length();
  27. int num = 0;
  28. if (len > 50) {
  29. num = len % 50 > 0 ? len / 50 : len / 2 - 1;
  30. }
  31. if (num > 0) {
  32. for (int i = 0; i < num; i++) {
  33. value = value.substring(0, (i + 1) * 50 + i) + "\n" + value.substring((i + 1) * 50 + i, len + i);
  34. }
  35. }
  36. if (value.contains("\n")) {
  37. int length = value.split("\n").length;
  38. maxHeight = Math.max(maxHeight, length) + 1;
  39. }
  40. }
  41. }
  42. row.setHeight((short) ((maxHeight) * DEFAULT_HEIGHT));
  43. }
  44. }

五、导出

  1. 先创建导出实体类
  1. import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  2. import com.alibaba.excel.annotation.ExcelProperty;
  3. import com.terton.aisp.ssp.entity.Feedback;
  4. import lombok.AllArgsConstructor;
  5. import lombok.Data;
  6. import lombok.NoArgsConstructor;
  7. @Data
  8. @AllArgsConstructor
  9. @NoArgsConstructor
  10. @ExcelIgnoreUnannotated // 只导出带有ExcelProperty注解的字段
  11. public class ExcelFeedbackVO extends Feedback {
  12. /**
  13. * 站点ID
  14. */
  15. // 设置表头名称 ,索引最好带上,不会出问题。
  16. @ExcelProperty(value = "站点id", index = 0)
  17. private String siteId;
  18. /**
  19. * 搜索内容
  20. */
  21. @ExcelProperty(value = "搜索内容", index = 1)
  22. private String title;
  23. /**
  24. * 反馈内容
  25. */
  26. @ExcelProperty(value = "反馈内容", index = 2)
  27. private String content;
  28. /**
  29. * IP地址
  30. */
  31. @ExcelProperty(value = "搜索IP", index = 3)
  32. private String ip;
  33. }

        2、创建一个对外暴露的接口。

  1. @PostMapping("/downloadBack")
  2. public void downloadBack(HttpServletResponse response, String siteId, Integer content) throws TException, IOException {
  3. List<Feedback> list = feedbackService.searchBack(siteId, content);
  4. setResponse(response, "列表");
  5. EasyExcel.write(response.getOutputStream(), ExcelFeedbackVO.class /* 引用需要导出的字段*/)
  6. .sheet("列表")
  7. .registerWriteHandler(new CustomCellWriteWidthConfig()) /*自适应列宽*/
  8. .registerWriteHandler(new CustomCellWriteHeighConfig()) /*自适应行高(根据自己情况选择使用,我这里没用到)*/
  9. .registerWriteHandler(EasyExcelUtils.getStyleStrategy()) /*引用样式*/
  10. .doWrite(list); /* 想到导出模板的话,此处给一个空的集合就好*/
  11. }

        3、设置响应体信息(由于我这个项目导入导出比较多,把此方法变成公共方法)

  1. import javax.servlet.http.HttpServletResponse;
  2. import java.net.URLEncoder;
  3. import java.nio.charset.StandardCharsets;
  4. public class SetResponse {
  5. /**
  6. * 导出设置响应信息
  7. *
  8. * @param response 响应
  9. */
  10. public static void setResponse(HttpServletResponse response,String fileName) {
  11. // 文件名
  12. String sheetName = URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ".xlsx";
  13. // contentType 响应内容的类型
  14. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  15. // 设置字符
  16. response.setCharacterEncoding("utf-8");
  17. // 设置文件名
  18. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + sheetName);
  19. }
  20. }

         4、访问接口

                模板

模板

                 正常导出

数据

 六、导入

        1、监听器(关键)

         注意事项:监听器里面不能使用注入的形式将service注入进来,所以可以使用构造器

  1. import com.alibaba.excel.context.AnalysisContext;
  2. import com.alibaba.excel.event.AnalysisEventListener;
  3. import com.terton.aisp.common.enums.ExcelNameModelEnum;
  4. import com.terton.aisp.common.util.PingYinUtil;
  5. import com.terton.aisp.word.entity.MassWord;
  6. import com.terton.aisp.word.enums.UploadBatchCountEnum;
  7. import com.terton.aisp.word.service.IMassWordService;
  8. import com.terton.aisp.word.service.impl.MassWordServiceImpl;
  9. import com.terton.aisp.word.vo.ExcelMassWordModelVO;
  10. import com.terton.framework.util.StringUtil;
  11. import lombok.AllArgsConstructor;
  12. import lombok.NoArgsConstructor;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.springframework.util.CollectionUtils;
  15. import java.util.ArrayList;
  16. import java.util.Date;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.stream.Collectors;
  20. @Slf4j
  21. @AllArgsConstructor
  22. @NoArgsConstructor
  23. public class UploadMassWordListener extends AnalysisEventListener<ExcelMassWordModelVO> {
  24. private IMassWordService massWordService;
  25. private String siteId;
  26. private Integer wordLevel;
  27. private String userName;
  28. private List<ExcelMassWordModelVO> list = new ArrayList<>();
  29. private List<String> massWordList = new ArrayList<>();
  30. private List<String> massWords = new ArrayList<>();
  31. private Integer successNum = 0;
  32. private Integer errorNum = 0;
  33. /**
  34. * 表头校验 此方法里面可进行对导入的excel的格式进行判断,先执行
  35. */
  36. @Override
  37. public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
  38. // headMap 表头数据,拿出进行判断就好
  39. }
  40. /**
  41. * 每读一行触发一次
  42. *
  43. * @param modelVO ”
  44. * @param analysisContext “
  45. */
  46. @Override
  47. public void invoke(ExcelMassWordModelVO modelVO, AnalysisContext analysisContext) {
  48. log.info("读取到一条数据:{}",modelVO)
  49. // 可以对数据进行判断是否有效。 根据自己的实际业务逻辑判断,
  50. // 判断完成的数据可以用一个List来接收
  51. // 为了防止数据过多,数据一直存在内存中,这里可以设置一个阈值,当list中的数据超过这个值,就先把这批数据添加到数据库。
  52. if (StringUtil.notBlankAndNull(modelVO.getMassWord()) && StringUtil.notBlankAndNull(modelVO.getTargetWord())) {
  53. if (!CollectionUtils.isEmpty(massWords) && massWords.contains(modelVO.getMassWord())) {
  54. throw new RuntimeException(ExcelNameModelEnum.FailImport.RESULT_FIELD.getText() + modelVO.getMassWord());
  55. }
  56. massWords.add(modelVO.getMassWord());
  57. massWordList.add(modelVO.getMassWord());
  58. list.add(modelVO);
  59. try {
  60. if (list.size() >= UploadBatchCountEnum.MASS_WORD.getCount() /*我这里阈值设置的是500*/) {
  61. save();
  62. }
  63. } catch (Exception e) {
  64. throw new RuntimeException(e.getMessage());
  65. }
  66. }
  67. }
  68. /**
  69. * 完毕触发
  70. *
  71. * @param analysisContext ”
  72. */
  73. @Override
  74. public void doAfterAllAnalysed(AnalysisContext analysisContext) {
  75. // 写数据库
  76. if (!CollectionUtils.isEmpty(list)) {
  77. save();
  78. }
  79. massWords.clear();
  80. log.info("成功写入数量:{}", successNum);
  81. log.info("失败写入数量:{}", errorNum);
  82. successNum = 0;
  83. errorNum = 0;
  84. }
  85. private void save() {
  86. try {
  87. List<MassWord> recordList = massWordService.getByMasswordsAndSiteId(massWordList, siteId);
  88. if (!CollectionUtils.isEmpty(recordList)) {
  89. List<String> collect = recordList.stream().map(MassWord::getMassWord).collect(Collectors.toList());
  90. if (!CollectionUtils.isEmpty(collect)) {
  91. throw new RuntimeException(ExcelNameModelEnum.FailImport.RESULT_FIELD.getText() + collect);
  92. }
  93. }
  94. for (ExcelMassWordModelVO wordModelVO : list) {
  95. MassWord newMassWord = getMassWord(wordModelVO);
  96. massWordService.save(newMassWord);
  97. successNum += 1;
  98. }
  99. } catch (Exception e) {
  100. errorNum += 1;
  101. throw new RuntimeException(e.getMessage());
  102. }
  103. massWordList.clear();
  104. list.clear();
  105. }
  106. private MassWord getMassWord(ExcelMassWordModelVO wordModelVO) {
  107. MassWord massWord = new MassWord();
  108. massWord.setMassWord(wordModelVO.getMassWord());
  109. massWord.setTargetWord(wordModelVO.getTargetWord());
  110. massWord.setWordLevel(wordLevel);
  111. massWord.setSiteId(siteId);
  112. massWord.setAcronym(PingYinUtil.getFirstSpell(wordModelVO.getMassWord()));
  113. massWord.setFullPinYin(PingYinUtil.getFullSpell(wordModelVO.getMassWord()));
  114. massWord.setCrTime(new Date());
  115. massWord.setCrUser(userName);
  116. return massWord;
  117. }
  118. public UploadMassWordListener(MassWordServiceImpl massWordService, String siteId,Integer wordLevel, String userName) {
  119. this.massWordService = massWordService;
  120. this.siteId = siteId;
  121. this.wordLevel = wordLevel;
  122. this.userName = userName;
  123. }
  124. }

        2、导入与监听器的使用。

  1. public void upload(MultipartFile file, String siteId, Integer wordLevel,String userName) throws IOException {
  2. UploadMassWordListener listener = new UploadMassWordListener(this, siteId, wordLevel, userName);
  3. EasyExcel.read(file.getInputStream(), ExcelMassWordModelVO.class, listener)
  4. .sheet(0)
  5. .headRowNumber(1)
  6. .doRead();
  7. }

到这里大概就结束了,希望对你有用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码吟游诗人/article/detail/61016
推荐阅读
相关标签
  

闽ICP备14008679号