话不多说直接上代码。。。。。

依赖,最新的poi放前面(最短路径优先原则),这样可以同时使用poi和easyexcel两种方式导入导出

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <!--easyexcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.8</version>
        </dependency>

vue页面

    /** 导出按钮操作 */
    exportClick() {
      this.$confirm('是否确认导出所有离寝情况?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.exportLoading = true;
        axios.request({
          method: 'post',
          url: process.env.VUE_APP_BASE_API +`/modules/room/exportOnlineLeave`,
          data: this.dataForm,
          headers: {
            Authorization: "Bearer " + getToken(),
          },
          responseType: 'blob'
        }).then(res => {
          const blob = new Blob([res.data], {type: 'application/vnd.ms-excel'})
          let filename = '实时离寝情况报表.xlsx'
          // 创建一个超链接,将文件流赋进去,然后实现这个超链接的单击事件
          const elink = document.createElement('a')
          elink.download = filename
          elink.style.display = 'none'
          elink.href = URL.createObjectURL(blob)
          document.body.appendChild(elink)
          elink.click()
          URL.revokeObjectURL(elink.href) // 释放URL 对象
          document.body.removeChild(elink)
          this.exportLoading = false;
        }).catch(() => {
        });
      })
    },

后端controller

    /**
     * 导出学生实时在寝情况报表
     */
    @PreAuthorize("@ss.hasPermi('modules:room:export')")
    @PostMapping("/exportOnlineReturn")
    public void exportDetailReturn(@RequestBody Map<String, Object> params, HttpServletResponse response) {
        params.remove("pageSize");
        List<BedExcelTemplateVo> list = faceBedService.selectBedOnlineBy(params);
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;");
        // 标题所占列数,数字取决于表头数量
        String[] header = new String[5];
        String fileName = "实时在寝情况报表";
        try {
            EasyExcel.write(response.getOutputStream(), BedExcelTemplateVo.class)
                    // 表头、内容样式设置
                    .registerWriteHandler(EasyExcelUtil.STYLE_STRATEGY)
                    // 行高,列宽
                    .registerWriteHandler(new CustomCellWriteHandler())
                    // 第一行标题样式设置
                    .registerWriteHandler(new FirstCellWriteHandler(fileName, header))
                    //设置写入表头信息开始的行数,0行为标题所占行数,因此从1行开始
                    .relativeHeadRowIndex(1)
                    .sheet(fileName)
                    .doWrite(list);
        }catch (Exception e) {
            throw new RuntimeException("下载报表异常");
        }
    }

三个拦截器: CustomCellWriteHandler,EasyExcelUtil,FirstCellWriteHandler

第一个设置表头、内容的行高、列宽样式,CustomCellWriteHandler

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.AbstractCellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;

import java.util.List;

public class CustomCellWriteHandler extends AbstractCellWriteHandler {
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
        if (row.getRowNum() == 1) {
            row.setHeight((short) 500);
        }else {
            short height = 400;
            row.setHeight(height);
        }
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        int cellIndex = cell.getColumnIndex();
            int columnWidth = 25;
            writeSheetHolder.getSheet().setColumnWidth(cellIndex, columnWidth * 256);
    }
}

第二个设置标题样式,FirstCellWriteHandler

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;


public class FirstCellWriteHandler implements SheetWriteHandler {

    private final String title;
    private final String[] header;

    public FirstCellWriteHandler(String title, String[] header) {
        this.title = title;
        this.header = header;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        Sheet sheet = workbook.getSheetAt(0);
        //设置标题
        Row row1 = sheet.createRow(0);
        row1.setHeight((short) 600);
        Cell cell = row1.createCell(0);
        //设置单元格内容
        cell.setCellValue(title);
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontHeight((short) 300);
        cellStyle.setFont(font);
        cell.setCellStyle(cellStyle);
        // 第一行大标题占位设置
        sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, header.length-1));
    }
}

第三个设置表头、内容的样式,EasyExcelUtil

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.*;

import java.util.LinkedList;
import java.util.List;

public class EasyExcelUtil {

	// 样式策略封装
    public final static HorizontalCellStyleStrategy STYLE_STRATEGY;

    static {
        STYLE_STRATEGY = new HorizontalCellStyleStrategy(getHeadStyle(),getContentStyle());
    }

    /**动态头传入,设置标题,难以自定义标题样式与表头样式不同*/
    public static List<List<String>> head(String[] header, String bigTitle) {
        List<String> head0 = null;
        List<List<String>> list = new LinkedList<List<String>>();
        for (String h : header) {
            head0 = new LinkedList<>();
            head0.add(bigTitle);
            head0.add(h);
            list.add(head0);
        }
        return list;
    }

    /**动态头传入,不设置标题, 标题另外拦截处理*/
    public static List<List<String>> head2(String[] header) {
        List<String> head0 = null;
        List<List<String>> list = new LinkedList<List<String>>();
        for (String h : header) {
            head0 = new LinkedList<>();
            head0.add(h);
            list.add(head0);
        }
        return list;
    }

    /**
     * 简单样式,合并定义
     */
    public static HorizontalCellStyleStrategy styleWrite() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //背景设置为白色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)20);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)20);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    /**
     * 分开定义,表头样式
     */
    public static WriteCellStyle getHeadStyle(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 字体
        WriteFont headWriteFont = new WriteFont();
        //设置字体名字
        headWriteFont.setFontName("黑体");
        //设置字体大小
        headWriteFont.setFontHeightInPoints((short)12);
        //字体加粗
        headWriteFont.setBold(true);
        //在样式用应用设置的字体;
        headWriteCellStyle.setWriteFont(headWriteFont);
        //样式  设置底边框;
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        //设置底边框颜色;
        headWriteCellStyle.setBottomBorderColor((short) 0);
        //设置左边框;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        //设置左边框颜色;
        headWriteCellStyle.setLeftBorderColor((short) 0);
        //设置右边框;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);
        //设置右边框颜色;
        headWriteCellStyle.setRightBorderColor((short) 0);
        //设置顶边框;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);
        //设置顶边框颜色;
        headWriteCellStyle.setTopBorderColor((short) 0);
        //设置自动换行;
        headWriteCellStyle.setWrapped(true);
        //设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //设置垂直对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
        return headWriteCellStyle;
    }

    /**
     * 分开定义,内容样式
     */
    public static WriteCellStyle getContentStyle(){
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 背景绿色
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 设置字体
        WriteFont contentWriteFont = new WriteFont();
        //设置字体大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        //设置字体名字
        contentWriteFont.setFontName("宋体");
        //在样式用应用设置的字体;
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        //样式  设置底边框;
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        //设置底边框颜色;
        contentWriteCellStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        //设置左边框;
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        //设置左边框颜色;
        contentWriteCellStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        //设置右边框;
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        //设置右边框颜色;
        contentWriteCellStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        //设置顶边框;
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        ///设置顶边框颜色;
        contentWriteCellStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
        // 水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置自动换行;
        contentWriteCellStyle.setWrapped(true);
        //设置单元格格式是:文本格式,方式长数字文本科学计数法
        contentWriteCellStyle.setDataFormat((short)49);
        // contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
        return contentWriteCellStyle;
    }
}

ps:除了自定义拦截器CustomCellWriteHandler(适用于不封装实体类,动态表头)更改行高列宽外,行高也可以通过@HeadRowHeight(xx)和@ContentRowHeight(xx)注解实现,列宽可以通过@ColumnWidth(xx)实现,前提都要封装实体类。这里最好自定义一个vo类(一种实体类类型)——视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。作为导出模板,BedExcelTemplateVo就不贴出来了,就是简单的实体类。不搞个实体类封装真的很头疼,搞动态头之类的东西浪费时间(除非真的需要动态字段)

最后上个效果图
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐