pom

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.3</version>
        </dependency>

封装统一导出工具类

package com.skybird.iot.base.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.skybird.iot.base.utils.bean.Custemhandler;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

public class EasyExcelUtil {

  /**
   * @param response
   * @param t 导出实体类
   * @param list 数据集合
   * @param name 文件名称
   * @throws IOException
   * @throws IllegalAccessException
   * @throws InstantiationException
   */
  public static void download(
      HttpServletRequest request, HttpServletResponse response, Class t, List list, String name)
      throws IOException, IllegalAccessException, InstantiationException {
    /*兼容IE和其他浏览器导出文件名乱码的问题*/
    name = downloadCommFileName(name, request);

    response.setContentType("application/vnd.ms-excel"); // 设置文本内省
    response.setCharacterEncoding("utf-8"); // 设置字符编码
    response.setHeader("Content-disposition", "attachment;fileName=" + name + ".xlsx"); // 设置响应头

    try (OutputStream outStream = response.getOutputStream()) {
      EasyExcel.write(outStream, t)
          .excelType(ExcelTypeEnum.XLSX)
          .registerWriteHandler(new Custemhandler()) // 设置自动列宽设置
          .registerWriteHandler(getStyleStrategy()) // 设置样式
          .sheet(name)
          .doWrite(list); // 用io流来写入数据
      outStream.flush();
    }
  }

  /*兼容IE和其他浏览器导出文件名乱码的问题*/
  public static String downloadCommFileName(String fileOut, HttpServletRequest request)
      throws IOException {
    String userAgent = request.getHeader("user-agent").toLowerCase();
    if (!StrUtil.contains(userAgent, "chrome")
        && (userAgent.contains("msie") || userAgent.contains("like gecko"))) {
      // win10 ie edge 浏览器 和其他系统的ie
      fileOut = URLEncoder.encode(fileOut, "UTF-8");
    } else {
      // 其他
      fileOut = new String(fileOut.getBytes("utf-8"), "iso-8859-1");
    }
    return fileOut;
  }

  public static HorizontalCellStyleStrategy getStyleStrategy() {
    // 头的策略
    WriteCellStyle headWriteCellStyle = new WriteCellStyle();
    // 背景设置
    headWriteCellStyle.setFillForegroundColor(IndexedColors.AUTOMATIC.getIndex());
    WriteFont headWriteFont = new WriteFont();
    headWriteFont.setFontHeightInPoints((short) 12);
    // 字体样式
    headWriteFont.setFontName("宋体");
    headWriteFont.setBold(false); // 取消加粗
    // 字体设置成红色
    //        headWriteFont.setColor(IndexedColors.RED.getIndex());
    headWriteCellStyle.setWriteFont(headWriteFont);
    // 自动换行
    headWriteCellStyle.setWrapped(false);
    //        headWriteCellStyle.setBorderTop(BorderStyle.SLANTED_DASH_DOT);//右边框
    //        headWriteCellStyle.setBorderBottom(BorderStyle.SLANTED_DASH_DOT);//左
    //        headWriteCellStyle.setBorderLeft(BorderStyle.SLANTED_DASH_DOT);//底
    //        headWriteCellStyle.setBorderRight(BorderStyle.SLANTED_DASH_DOT);
    // 水平对齐方式
    headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
    // 垂直对齐方式
    headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

    // 内容的策略
    WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
    // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了
    // FillPatternType所以可以不指定
    //        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
    // 背景白色
    contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
    WriteFont contentWriteFont = new WriteFont();
    // 字体大小
    contentWriteFont.setFontHeightInPoints((short) 12);
    // 字体样式
    contentWriteFont.setFontName("Calibri");
    contentWriteCellStyle.setWriteFont(contentWriteFont);
    return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
  }
}

自定义列宽

package com.skybird.iot.base.utils.bean;

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.poi.ss.usermodel.Cell;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * EasyExcel导出自动列宽设置
 */
public class Custemhandler extends AbstractColumnWidthStyleStrategy {

    private static final int MAX_COLUMN_WIDTH = 255;
    //因为在自动列宽的过程中,有些设置地方让列宽显得紧凑,所以做出了个判断
    private static final int COLUMN_WIDTH = 20;
    private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap(8);

    public Custemhandler() {
    }

    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
        if (needSetWidth) {
            Map<Integer, Integer> maxColumnWidthMap = (Map) CACHE.get(writeSheetHolder.getSheetNo());
            if (maxColumnWidthMap == null) {
                maxColumnWidthMap = new HashMap(16);
                CACHE.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);
            }

            Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
            if (columnWidth >= 0) {
                if (columnWidth > MAX_COLUMN_WIDTH) {
                    columnWidth = MAX_COLUMN_WIDTH;
                } else {
                    if (columnWidth < COLUMN_WIDTH) {
                        columnWidth = columnWidth * 2;
                    }
                }
                Integer maxColumnWidth = (Integer) ((Map) maxColumnWidthMap).get(cell.getColumnIndex());
                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
                    ((Map) maxColumnWidthMap).put(cell.getColumnIndex(), columnWidth);
                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
                }
            }
        }
    }

    private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
        if (isHead) {
            return cell.getStringCellValue().getBytes().length;
        } else {
            CellData cellData = (CellData) cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();
            if (type == null) {
                return -1;
            } else {
                switch (type) {
                    case STRING:
                        return cellData.getStringValue().getBytes().length;
                    case BOOLEAN:
                        return cellData.getBooleanValue().toString().getBytes().length;
                    case NUMBER:
                        return cellData.getNumberValue().toString().getBytes().length;
                    default:
                        return -1;
                }
            }
        }
    }
}


实体类

package com.skybird.iot.addons.afterSales.maintenanceRecords.backend.jdb;

import com.alibaba.excel.annotation.ExcelProperty;

public class MaintenanceRecordsExcelDao {
    @ExcelProperty("维修单编号")
    private String repairOrderNumber;

    @ExcelProperty("工单状态")
    private String orderWorkStatus;

    @ExcelProperty("是否维修")
    private String appraisalName;

    @ExcelProperty("产品类型")
    private String productType;

    @ExcelProperty("产品编码")
    private String productCode;
    @ExcelProperty("产品名称")
    private String productName;
    @ExcelProperty("SN码")
    private String snCode;
    @ExcelProperty("重贴SN码")
    private String resultsRepairNewSnCode;
    @ExcelProperty("更换机器SN码")
    private String resultsRepairMachine;
    @ExcelProperty("生产厂商")
    private String productManufacturer;
    @ExcelProperty("维修厂商")
    private String serviceTypeName;
    @ExcelProperty("创建时间")
    private String createTime;
    @ExcelProperty("维修完成时间")
    private String completedRepairData;

    public String getRepairOrderNumber() {
        return repairOrderNumber;
    }

    public void setRepairOrderNumber(String repairOrderNumber) {
        this.repairOrderNumber = repairOrderNumber;
    }

    public String getOrderWorkStatus() {
        return orderWorkStatus;
    }

    public void setOrderWorkStatus(String orderWorkStatus) {
        this.orderWorkStatus = orderWorkStatus;
    }

    public String getAppraisalName() {
        return appraisalName;
    }

    public void setAppraisalName(String appraisalName) {
        this.appraisalName = appraisalName;
    }

    public String getProductType() {
        return productType;
    }

    public void setProductType(String productType) {
        this.productType = productType;
    }

    public String getProductCode() {
        return productCode;
    }

    public void setProductCode(String productCode) {
        this.productCode = productCode;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getSnCode() {
        return snCode;
    }

    public void setSnCode(String snCode) {
        this.snCode = snCode;
    }

    public String getResultsRepairNewSnCode() {
        return resultsRepairNewSnCode;
    }

    public void setResultsRepairNewSnCode(String resultsRepairNewSnCode) {
        this.resultsRepairNewSnCode = resultsRepairNewSnCode;
    }

    public String getResultsRepairMachine() {
        return resultsRepairMachine;
    }

    public void setResultsRepairMachine(String resultsRepairMachine) {
        this.resultsRepairMachine = resultsRepairMachine;
    }

    public String getProductManufacturer() {
        return productManufacturer;
    }

    public void setProductManufacturer(String productManufacturer) {
        this.productManufacturer = productManufacturer;
    }

    public String getServiceTypeName() {
        return serviceTypeName;
    }

    public void setServiceTypeName(String serviceTypeName) {
        this.serviceTypeName = serviceTypeName;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getCompletedRepairData() {
        return completedRepairData;
    }

    public void setCompletedRepairData(String completedRepairData) {
        this.completedRepairData = completedRepairData;
    }

    @Override
    public String toString() {
        return "MaintenanceRecordsExcelDao{" +
                "repairOrderNumber='" + repairOrderNumber + '\'' +
                ", orderWorkStatus='" + orderWorkStatus + '\'' +
                ", appraisalName='" + appraisalName + '\'' +
                ", productType='" + productType + '\'' +
                ", productCode='" + productCode + '\'' +
                ", productName='" + productName + '\'' +
                ", snCode='" + snCode + '\'' +
                ", resultsRepairNewSnCode='" + resultsRepairNewSnCode + '\'' +
                ", resultsRepairMachine='" + resultsRepairMachine + '\'' +
                ", productManufacturer='" + productManufacturer + '\'' +
                ", serviceTypeName='" + serviceTypeName + '\'' +
                ", createTime='" + createTime + '\'' +
                ", completedRepairData='" + completedRepairData + '\'' +
                '}';
    }
}

 后端接口

这里用的是mongodb,参数自己根据需求调整

@GetMapping("/excel")
    public void excel(HttpServletRequest request,HttpServletResponse response, @RequestParam("filter") String filters) throws IOException, IllegalAccessException, InstantiationException {
        Document filter = DocuLib.parseDecode(filters);
        Document userDoc = UserUtils.getUser();
        if (UserUtils.isOEMUser()) {
            Document oemDto = userDoc.get("oem", Document.class);
            filter.append("oemCode", oemDto.getString("id"));
        }
        String keyword = filter.getString("keywords");
        //维修单编号、状态、产品类型、产品编码、产品名称、SN码(新旧码一起搜索)、处理方案、创建日期、维修完成日期
        if (StrUtil.isNotEmpty(keyword)) {
            filter.append("$or", Arrays.asList(
                    new Document("repairOrderNumber", new Document("$regex", keyword)),
                    new Document("orderWorkStatus", new Document("$regex", keyword)),
                    new Document("appraisal.service.name", new Document("$regex", keyword)),
                    new Document("product.type", new Document("$regex", keyword)),
                    new Document("product.code", new Document("$regex", keyword)),
                    new Document("product.name", new Document("$regex", keyword)),
                    new Document("snCode", new Document("$regex", keyword)),
                    new Document("resultsRepair.newSnCode", new Document("$regex", keyword)),
                    new Document("resultsRepair.machine", new Document("$regex", keyword))));
        }
        filter.remove("keywords");

        Document dateRange = filter.get("dateRange", Document.class);
        if (Objects.nonNull(dateRange) && dateRange.size() > 0) {
            filter.append("$and", Arrays.asList(
                    new Document("createTime", new Document("$gte", dateRange.getString("start"))),
                    new Document("createTime", new Document("$lte", dateRange.getString("end")))
            ));

        }
        filter.remove("dateRange");

        Document dateRanges = filter.get("dateRanges", Document.class);
        if (Objects.nonNull(dateRanges) && dateRanges.size() > 0) {
            filter.append("$and", Arrays.asList(
                    new Document("completedRepairData", new Document("$gte", dateRanges.getString("start"))),
                    new Document("completedRepairData", new Document("$lte", dateRanges.getString("end")))
            ));
        }
        filter.remove("dateRanges");
        
        //根据条件查询list数据
        List<Document> list = DBUtils.list(MaintenanceRecords.collectionName, filter);

        //封装导出数据
        List<MaintenanceRecordsExcelDao> excelList = new ArrayList<>();
        for (Document item : list) {
            MaintenanceRecordsExcelDao dao = new MaintenanceRecordsExcelDao();
            dao.setRepairOrderNumber(item.getString("repairOrderNumber"));
            dao.setOrderWorkStatus(item.getString("orderWorkStatus"));

            Document appraisal = item.get("appraisal", Document.class);
            if (Objects.nonNull(appraisal)) {
                Document service = appraisal.get("service", Document.class);
                if (Objects.nonNull(service)) {
                    dao.setAppraisalName(service.getString("name"));
                }
            }

            Document product = item.get("product", Document.class);
            if (Objects.nonNull(product)) {
                dao.setProductType(product.getString("type"));
                dao.setProductCode(product.getString("code"));
                dao.setProductName(product.getString("name"));
                dao.setProductManufacturer(product.getString("manufacturer"));
            }

            dao.setSnCode(item.getString("snCode"));

            Document resultsRepair = item.get("resultsRepair", Document.class);
            if (Objects.nonNull(resultsRepair)) {
                dao.setResultsRepairNewSnCode(resultsRepair.getString("newSnCode"));
                dao.setResultsRepairMachine(resultsRepair.getString("machine"));
            }

            Document serviceType = item.get("serviceType", Document.class);
            if (Objects.nonNull(serviceType)) {
                dao.setServiceTypeName(serviceType.getString("name"));
            }

            dao.setCreateTime(item.getString("createTime"));
            dao.setCompletedRepairData(item.getString("completedRepairData"));

            excelList.add(dao);
        }
        
        //使用封装工具类导出execl文档
        EasyExcelUtil.download(request,response, MaintenanceRecordsExcelDao.class, excelList, "维修记录");
    }

前端代码

     //这里因为自研框架封装了请求方法,注意只需要在自己的请求上添加responseType: 'blob'
                getFile: function () {
                    var arr = _.toArray(arguments);
                    arr.unshift({
                        method: "get",
                        responseType: 'blob'
                    });
                    return this.ajax.apply(null, arr);
                }


                //事件触发方法
                export: function () {
                    //后端导出,filter参数用于条件查询使用
                    http.getFile('maintenanceRecords/excel', {
                        filter: ctrl.filter
                    }).then(function (response) {
                        const url = window.URL.createObjectURL(new Blob([response.data]));
                        const link = document.createElement('a');
                        link.href = url;
                        link.setAttribute('download', '维修记录.xlsx');
                        document.body.appendChild(link);
                        link.click();
                    });
                }

导出文档效果

GitHub 加速计划 / ea / easyexcel
31.64 K
7.47 K
下载
快速、简洁、解决大文件内存溢出的java处理Excel工具
最近提交(Master分支:3 个月前 )
c42183df Bugfix 3 个月前
efa7dff6 * 重新加回 `commons-io` 3 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐