当前位置:   article > 正文

Springboot + EasyExcel + Vue 实现excel下载功能_customcellwritewidthconfig

customcellwritewidthconfig

一、添加EasyExcel依赖

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

二、后端代码示例

controller:

  1. @GetMapping("/download")
  2. public void download(HttpServletResponse response) throws IOException {
  3. String dataFormat = new SimpleDateFormat("yyyyMMdd").format(new Date());
  4. //xlsx格式:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xls格式:application/vnd.ms-excelExport
  5. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  6. response.setCharacterEncoding("utf-8");
  7. String fileName = URLEncoder.encode("满意度调查信息导出表" + dataFormat, "UTF-8").replaceAll("\\+", "%20");
  8. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
  9. EasyExcel
  10. .write(response.getOutputStream(), ScorePsnExcelDTO.class)
  11. .registerWriteHandler(EasyExcelUtils.getStyle())//引用样式
  12. .registerWriteHandler(new CustomCellWriteWidthConfig())//自适应列宽
  13. .registerWriteHandler(new CustomCellWriteHeightConfig())//自适应行高
  14. .sheet("调查表")
  15. .doWrite(data());//业务数据
  16. }

DTO(模板数据):

  1. package cn.hsa.pss.pw.web.thirdinterface.excelExport.dto;
  2. import com.alibaba.excel.annotation.ExcelProperty;
  3. import lombok.Data;
  4. /**
  5. * 医疗机构评价 -评价人DTO
  6. *
  7. * @Author
  8. * @Date:2024-01-23 16:46
  9. * @Description
  10. */
  11. @Data
  12. public class ScorePsnExcelDTO {
  13. @ExcelProperty(value = "序号", index = 0)
  14. private Integer no;
  15. //定点统筹区(参保人统筹区
  16. @ExcelProperty(value = "定点统筹区", index = 1)
  17. private String areaCode;
  18. //医药机构编码
  19. @ExcelProperty(value = "医药机构编码", index = 2)
  20. private String medInsCode;
  21. //医药机构名称
  22. @ExcelProperty(value = "医药机构名称", index = 3)
  23. private String medInsName;
  24. //医药机构类型
  25. @ExcelProperty(value = "医药机构类型", index = 4)
  26. private String medInsType;
  27. //医疗类别
  28. @ExcelProperty(value = "医疗类别", index = 5)
  29. private String medType;
  30. //就医人次
  31. @ExcelProperty(value = "就医人次", index = 6)
  32. private Integer medNum;
  33. //参与调查人次
  34. @ExcelProperty(value = "参与调查人次", index = 7)
  35. private Integer scoreNum;
  36. //很不满意
  37. @ExcelProperty(value = {"评价分布", "很不满意"}, index = 8)
  38. private Integer scoreOne;
  39. //不满意
  40. @ExcelProperty(value = {"评价分布", "不满意"}, index = 9)
  41. private Integer scoreTwo;
  42. //一般
  43. @ExcelProperty(value = {"评价分布", "一般"}, index = 10)
  44. private Integer scoreThree;
  45. //比较满意
  46. @ExcelProperty(value = {"评价分布", "比较满意"}, index = 11)
  47. private Integer scoreFour;
  48. //很满意
  49. @ExcelProperty(value = {"评价分布", "很满意"}, index = 12)
  50. private Integer scoreFive;
  51. //参与调查率
  52. @ExcelProperty(value = "参与调查率", index = 13)
  53. private Double scoreRate;
  54. //满意度
  55. @ExcelProperty(value = "满意度", index = 14)
  56. private String goodRate;
  57. }

关键点1:响应头设置

  1. //如果前端接收xlsx格式,则
  2. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  3. //如果前端接收xls格式,则
  4. response.setContentType("application/vnd.ms-excelExport");

关键点2:ScorePsnExcelDTO 

1、 @ExcelProperty(value = "序号", index = 0) 

value对应的导出excel的列名,index代表顺序

2、如果涉及到单元格合并,可以这么写:

@ExcelProperty(value = {"评价分布", "很不满意"}, index = 8)

 @ExcelProperty(value = {"评价分布", "一般"}, index = 10)

效果如下:

关键点3:

要使用get方法

自适应行高:

  1. package cn.hsa.pss.pw.web.thirdinterface.excelExport.config;
  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. /**
  8. * 自适应行高
  9. *
  10. * @Author
  11. * @Date:2024-02-01 14:00
  12. * @Description
  13. */
  14. public class CustomCellWriteHeightConfig extends AbstractRowHeightStyleStrategy {
  15. /**
  16. * 默认高度
  17. */
  18. private static final Integer DEFAULT_HEIGHT = 300;
  19. @Override
  20. protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
  21. }
  22. @Override
  23. protected void setContentColumnHeight(Row row, int relativeRowIndex) {
  24. Iterator<Cell> cellIterator = row.cellIterator();
  25. if (!cellIterator.hasNext()) {
  26. return;
  27. }
  28. // 默认为 1行高度
  29. int maxHeight = 1;
  30. while (cellIterator.hasNext()) {
  31. Cell cell = cellIterator.next();
  32. if (cell.getCellTypeEnum() == CellType.STRING) {
  33. String value = cell.getStringCellValue();
  34. int len = value.length();
  35. int num = 0;
  36. if (len > 50) {
  37. num = len % 50 > 0 ? len / 50 : len / 2 - 1;
  38. }
  39. if (num > 0) {
  40. for (int i = 0; i < num; i++) {
  41. value = value.substring(0, (i + 1) * 50 + i) + "\n" + value.substring((i + 1) * 50 + i, len + i);
  42. }
  43. }
  44. if (value.contains("\n")) {
  45. int length = value.split("\n").length;
  46. maxHeight = Math.max(maxHeight, length) + 1;
  47. }
  48. }
  49. }
  50. row.setHeight((short) ((maxHeight) * DEFAULT_HEIGHT));
  51. }
  52. }

自适应列宽:

  1. package cn.hsa.pss.pw.web.thirdinterface.excelExport.config;
  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. /**
  15. * 自适应列宽
  16. *
  17. * @Author
  18. * @Date:2024-02-01 13:38
  19. * @Description
  20. */
  21. public class CustomCellWriteWidthConfig extends AbstractColumnWidthStyleStrategy {
  22. private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
  23. protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
  24. boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
  25. if (needSetWidth) {
  26. Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());
  27. Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
  28. // 单元格文本长度大于60换行
  29. if (columnWidth >= 0) {
  30. if (columnWidth > 60) {
  31. columnWidth = 60;
  32. }
  33. Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
  34. if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
  35. maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
  36. Sheet sheet = writeSheetHolder.getSheet();
  37. sheet.setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
  38. }
  39. }
  40. }
  41. }
  42. /**
  43. * 计算长度
  44. *
  45. * @param cellDataList
  46. * @param cell
  47. * @param isHead
  48. * @return
  49. */
  50. private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
  51. if (isHead) {
  52. return cell.getStringCellValue().getBytes().length;
  53. } else {
  54. CellData<?> cellData = cellDataList.get(0);
  55. CellDataTypeEnum type = cellData.getType();
  56. if (type == null) {
  57. return -1;
  58. } else {
  59. switch (type) {
  60. case STRING:
  61. // 换行符(数据需要提前解析好)
  62. int index = cellData.getStringValue().indexOf("\n");
  63. return index != -1 ?
  64. cellData.getStringValue().substring(0, index).getBytes().length + 1 : cellData.getStringValue().getBytes().length + 1;
  65. case BOOLEAN:
  66. return cellData.getBooleanValue().toString().getBytes().length;
  67. case NUMBER:
  68. return cellData.getNumberValue().toString().getBytes().length;
  69. default:
  70. return -1;
  71. }
  72. }
  73. }
  74. }
  75. }

字体样式工具类:

  1. package cn.hsa.pss.pw.web.thirdinterface.excelExport.utils;
  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 java.util.ArrayList;
  9. /**
  10. * 设置excel工具类
  11. *
  12. * @Author:wangguangxing
  13. * @Date:2024-02-01 14:18
  14. * @Description
  15. */
  16. public class EasyExcelUtils {
  17. public static HorizontalCellStyleStrategy getStyle() {
  18. //自定义表头样式 浅橙色 居中
  19. WriteCellStyle headCellStyle = new WriteCellStyle();
  20. headCellStyle.setFillForegroundColor(IndexedColors.TAN.getIndex()); //表头颜色
  21. headCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); //文本居中
  22. //字体
  23. WriteFont writeFont = new WriteFont();
  24. writeFont.setFontName("微软雅黑"); //字体
  25. writeFont.setFontHeightInPoints((short) 10); //字体大小
  26. headCellStyle.setWriteFont(writeFont);
  27. // 自动换行
  28. headCellStyle.setWrapped(true);
  29. //内容样式
  30. WriteCellStyle contentCellStyle = new WriteCellStyle();
  31. contentCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); //文本居中
  32. contentCellStyle.setWriteFont(writeFont);
  33. //设置边框
  34. contentCellStyle.setBorderLeft(BorderStyle.THIN); //左边框线
  35. contentCellStyle.setBorderTop(BorderStyle.THIN); //顶部框线
  36. contentCellStyle.setBorderRight(BorderStyle.THIN); //右边框线
  37. contentCellStyle.setBorderBottom(BorderStyle.THIN); //底部框线
  38. ArrayList<WriteCellStyle> contentCells = new ArrayList<>();
  39. contentCells.add(contentCellStyle);
  40. //样式策略
  41. HorizontalCellStyleStrategy handler = new HorizontalCellStyleStrategy();
  42. handler.setHeadWriteCellStyle(headCellStyle); //表头样式
  43. handler.setContentWriteCellStyleList(contentCells); //内容样式
  44. return new HorizontalCellStyleStrategy(headCellStyle, contentCells);
  45. }
  46. }

三、前端代码示例

  1. 1
  2. exportFile() {
  3. this.downLoading = true
  4. exportScoreList().then((res) => {
  5. this.downLoading = false
  6. const str = res.headers["content-disposition"]
  7. const fileName = decodeURI(str.substr(str.indexOf("%")))
  8. this.downloadFile(res.data, fileName)
  9. }).catch((err) => {
  10. this.downLoading = false
  11. })
  12. }
  13. 2
  14. downloadFile(res, fileName) {
  15. let blob = new Blob([res], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
  16. if (!fileName) {
  17. fileName = res.headers['content-disposition'].split('filename=').pop();
  18. }
  19. if ('msSaveOrOpenBlob' in navigator) {
  20. window.navigator.msSaveOrOpenBlob(blob, fileName);
  21. } else {
  22. const elink = document.createElement('a');
  23. elink.download = fileName;
  24. elink.style.display = 'none';
  25. elink.href = window.URL.createObjectURL(blob);
  26. document.body.appendChild(elink);
  27. elink.setAttribute('href', elink.href)
  28. elink.click();
  29. document.body.removeChild(elink);
  30. window.URL.revokeObjectURL(elink.href);
  31. }
  32. }
  33. 3
  34. export function exportScoreList() {
  35. return axios({
  36. url: `${path}/excel/download`,
  37. method: "get",
  38. responseType: "blob"
  39. });
  40. }

关键点1:

responseType: "blob"    method: "get",

关键点2:

 let blob = new Blob([res], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}) 

要与后台响应头类型对应上。

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

闽ICP备14008679号