当前位置:   article > 正文

easy Exsel导出

easy Exsel导出

目录

一、首先引入依赖

二、然后封装一个VO

三、Controller层

四、Service实现类 

引用样式

自适应列宽  

自适应行高

五、测试

postman

​编辑

 浏览器

异常


分配到这个任务了,写个小demo记录下,具体可参考EasyExcel官方文档

我用的是web上传、下载那块代码

一、首先引入依赖

  1. <!-- easy Excel -->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>easyexcel</artifactId>
  5. <version>3.1.0</version>
  6. <exclusions>
  7. <exclusion>
  8. <artifactId>poi-ooxml-schemas</artifactId>
  9. <groupId>org.apache.poi</groupId>
  10. </exclusion>
  11. </exclusions>
  12. </dependency>

二、然后封装一个VO

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. @EqualsAndHashCode
  5. public class ExportStudentInfoVO implements Serializable {
  6. private static final long serialVersionUID = -3275970951989418695L;
  7. @ExcelIgnore // 忽略导出
  8. private String stuId;
  9. @ExcelProperty("学生姓名")
  10. private String stuName;
  11. @ExcelProperty("学生性别")
  12. private String stuGender;
  13. @ExcelProperty("学生年龄")
  14. private Integer stuAge;
  15. @ExcelProperty("监护人联系方式")
  16. private String guardianPhone;
  17. @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
  18. @ColumnWidth(21) //设置宽度
  19. @ExcelProperty(value = "入学时间")
  20. private Date createDate;
  21. }

三、Controller层

  1. @RestController
  2. @RequestMapping("info")
  3. public class InfoController {
  4. @Resource
  5. private InfoService infoService;
  6. @Operation(summary = "学生信息导出")
  7. @RequestMapping(value = "/excelDownload", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
  8. public void excelOrderContainerDownload(HttpServletResponse response){
  9. infoService.excelDownload(response);
  10. }
  11. }

四、Service实现类 

这里的list,模拟从DB中查到的数据

.registerWriteHandler(new CustomCellWriteWidthConfig()) /*自适应列宽*/
 .registerWriteHandler(new CustomCellWriteHeightConfig()) /*自适应行高*/
.registerWriteHandler(EasyExcelUtils.getStyleStrategy()) /*引用样式*/

以上三个是excel表格进行一个处理,让其看起来更加美观,如果要使用可以往下翻对应的代码复制使用,不加也不影响导出

  1. @Service
  2. @Slf4j
  3. public class InfoServiceImpl implements InfoService {
  4. @Override
  5. public void excelDownload(HttpServletResponse response) {
  6. List<ExportStudentInfoVO> list = new ArrayList<>();
  7. list.add(new ExportStudentInfoVO("001","张三","男",18,"18488789989", new Date()));
  8. list.add(new ExportStudentInfoVO("002","李四","女",21,"15233337777", new Date()));
  9. list.add(new ExportStudentInfoVO("003","王五","男",19,"15623332333", new Date()));
  10. try {
  11. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  12. response.setCharacterEncoding("utf-8");
  13. SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
  14. String currentDate = sdf.format(new Date());
  15. // URLEncoder.encode 可以防止中文乱码
  16. String fileName = URLEncoder.encode("学生信息列表" + currentDate, "UTF-8").replaceAll("\\+", "%20");
  17. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
  18. EasyExcel.write(response.getOutputStream(), ExportStudentInfoVO.class)
  19. .sheet("学生信息")
  20. .registerWriteHandler(new CustomCellWriteWidthConfig()) /*自适应列宽*/
  21. .registerWriteHandler(new CustomCellWriteHeightConfig()) /*自适应行高*/
  22. .registerWriteHandler(EasyExcelUtils.getStyleStrategy()) /*引用样式*/
  23. .doWrite(list);
  24. } catch (Exception e) {
  25. log.error("导出失败~");
  26. e.printStackTrace();
  27. }
  28. }
  29. }

引用样式

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

自适应列宽  

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

自适应行高

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

五、测试

测试的话可以用postman进行测试 ,或者把链接粘在浏览器上

postman

postman测试的时候记得点这个下拉框选择发送并下载

然后弹出这个界面点击保存

然后桌面上就可以看到已经成功的下载下来了,数据也都是没问题的

 浏览器

直接贴链接即可

可以看到数据也是没问题的 

异常

最后讲一下,刚开始我这个小demo没跑起来,编译、运行都没问题,一调接口就报错了

异常是 com.alibaba.excel.exception.ExcelGenerateException: java.lang.NoClassDefFoundError: org/apache/xmlbeans/impl/common/SystemCache

搜了一下是由于缺少了相关的依赖库或者版本不匹配所致,可能需要添加 Apache POI 或者 XMLBeans 这些依赖库,并且确保版本号是兼容的。

然后加上这两个依赖就可以了,不知道你们有没有遇到

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi</artifactId>
  4. <version>4.1.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi-ooxml</artifactId>
  9. <version>4.1.2</version>
  10. </dependency>

好了,分享就到这里,晚安

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

闽ICP备14008679号