效果预览

设置表头的行高有0.1的误差,按理说我设置的应该是17.7,但是实际出来excel中是17.8代码效果图

准备工作

  • 项目结构
    在这里插入图片描述

  • 导入easyExcel的依赖

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

具体代码实现

  • controller层

为了方便,我把需要导的包也放进来了

package com.easyexcel.test.controller;

import com.easyexcel.test.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
public class TestController {

    @Autowired
    private TestService testService;
    @GetMapping("/download")
    public void windowsClientDownload(HttpServletResponse response, Long procedureId) {
        testService.doDownload(response);
    }
}

  • service层
ipackage com.easyexcel.test.service;

import javax.servlet.http.HttpServletResponse;

public interface TestService {
    void doDownload(HttpServletResponse response);
}
  • service实现类
package com.easyexcel.test.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.easyexcel.test.service.TestService;
import com.easyexcel.test.strategy.CellRowHeightStyleStrategy;
import com.easyexcel.test.strategy.CellStyleStrategy;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class TestServiceImpl implements TestService {

    @Override
    public void doDownload(HttpServletResponse response) {
        //设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        //中文文件名编码
        String fileName = null;
        try {
            //中文文件名编码要用URLEncoder.encode编码
            fileName = URLEncoder.encode("模板", "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".xlsx");
        try {
            //主标题和副标题在excel中分别是是第0和第1行
            List<Integer> columnIndexes = Arrays.asList(0,1);
            //自定义标题和内容策略(具体定义在下文)
            CellStyleStrategy cellStyleStrategy =
                    new CellStyleStrategy(columnIndexes,new WriteCellStyle(), new WriteCellStyle());

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                    .registerWriteHandler(new CellRowHeightStyleStrategy())   //设置行高的策略
                    .registerWriteHandler(cellStyleStrategy)        //设置表头和内容的策略
                    .build();

            //填入数据
            writeData(excelWriter);
            // 千万别忘记关闭流
            excelWriter.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    /**
     * 写入数据
     * @param excelWriter excelWriter
     */
    private void writeData(ExcelWriter excelWriter){

        WriteSheet writeSheet = new WriteSheet();
        //设置写到第几个sheet
        writeSheet.setSheetNo(0);
        writeSheet.setSheetName("测试");
        //造数据
        List<List<Object>> list = ListUtils.newArrayList();
        for (int i = 0; i < 10; i++) {
            List<Object> data = ListUtils.newArrayList();
            data.add("字符串" + i);
            data.add(new Date());
            data.add(0.56);
            list.add(data);
        }
        //设置表头
        List<List<String>> headList = new ArrayList<>();
        String name = "********表";
        headList.add(Arrays.asList(name,"序号"));
        headList.add(Arrays.asList(name,"名称"));
        for (int i = 1; i <3 ; i++) {
            headList.add(Arrays.asList(name,"单位"+i));
        }
        writeSheet.setHead(headList);

        //(设置数据)
        //第一列序号从1开始增加
        AtomicInteger orderNumber = new AtomicInteger(1);
        ArrayList<List<Object>> dataList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            List<Object> data = ListUtils.newArrayList();
            data.add(String.valueOf(orderNumber.getAndIncrement()));
            data.add("名称" + i);
            data.add("单元"+i);
            data.add(0.56);
            dataList.add(data);
        }
        excelWriter.write(dataList, writeSheet);
    }
}
  • 设置表头和填充内容的样式
package com.easyexcel.test.strategy;

import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
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.BorderStyle;
import org.apache.poi.ss.usermodel.IndexedColors;

import java.util.List;

/**
 - 设置表头和填充内容的样式
 */
public class CellStyleStrategy extends HorizontalCellStyleStrategy {

    private final WriteCellStyle headWriteCellStyle;
    private final WriteCellStyle contentWriteCellStyle;

    /**
     * 操作列
     */
    private final List<Integer> columnIndexes;

    public CellStyleStrategy(List<Integer> columnIndexes,WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
        this.columnIndexes = columnIndexes;
        this.headWriteCellStyle = headWriteCellStyle;
        this.contentWriteCellStyle = contentWriteCellStyle;
    }

	//设置头样式
    @Override
    protected void setHeadCellStyle( CellWriteHandlerContext context) {
        // 获取字体实例
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("宋体");
        if (columnIndexes.get(0).equals(context.getRowIndex())) {
            headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            headWriteFont.setFontHeightInPoints((short) 14);
            headWriteFont.setBold(true);
        }else{
            headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            headWriteFont.setFontHeightInPoints((short) 11);
            headWriteFont.setBold(false);
        }
        headWriteCellStyle.setWriteFont(headWriteFont);
        if (stopProcessing(context)) {
            return;
        }
        WriteCellData<?> cellData = context.getFirstCellData();
        WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle());
    }

	//设置填充数据样式
    @Override
    protected void setContentCellStyle(CellWriteHandlerContext context) {
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontName("宋体");
        contentWriteFont.setFontHeightInPoints((short) 11);
        //设置数据填充后的实线边框
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        WriteCellData<?> cellData = context.getFirstCellData();
        WriteCellStyle.merge(contentWriteCellStyle, cellData.getOrCreateStyle());
    }
}
  • 设置表头行高策略

如果excel需要显示行高为15,那这里就要设置为15*20=300

package com.easyexcel.test.strategy;

import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
import org.apache.poi.ss.usermodel.Row;

/**
 * 设置表头的自动调整行高策略
 */
public class CellRowHeightStyleStrategy extends AbstractRowHeightStyleStrategy {

    @Override
    protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
        //设置主标题行高为17.7
        if(relativeRowIndex == 0){
        	//如果excel需要显示行高为15,那这里就要设置为15*20=300
            row.setHeight((short) (354));
        }
    }

    @Override
    protected void setContentColumnHeight(Row row, int relativeRowIndex) {
    }
}

访问

启动项目后访问 http://localhost:8411/download 开始下载文件 (8411是我自己在application.yml中设置的项目启动端口)

写在最后

如果有什么不对的可以评论交流

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐