package com.nb.easy.easyframe.module.archievs.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * Excel下载工具
 */
@Slf4j
public class EasyExcelUtil {

    /**
     * 集合分割条数
     */
    private static final int MAX_ROWS = 10000;

    /**
     * 获取默认表头内容化样式
     */
    private static HorizontalCellStyleStrategy getDefaultHorizontalCellStyleStrategy(){
        //表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //背景色(浅灰色)
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        //字体大小
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)10);
        headWriteCellStyle.setWriteFont(headWriteFont);
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //内容字体样式(名称,大小)
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontName("宋体");
        contentWriteFont.setFontHeightInPoints((short)10);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        //设置内容垂直居中对齐
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置内容水平居中对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //设置边框样式
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        //头样式和内容样式合并
        return new HorizontalCellStyleStrategy(headWriteCellStyle,contentWriteCellStyle);
    }

    /**
     * 处理输出流
     * @param fileName Excel名称
     * @param response http返回
     * @return OutputStream
     * @throws Exception
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception{
        fileName = URLEncoder.encode(fileName,"UTF-8");
        //.xlsx
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName + ".xlsx");
        return response.getOutputStream();
    }

    /**
     * 集合分割
     * @param list 要分割的集合
     * @param len 每个集合多少条,比如一个集合要1万条, len = 10000
     * @param <T>
     * @return List<List<T>>
     */
    public static<T> List<List<T>> splitList(List<T> list,int len){
        if (list == null || list.isEmpty()){
            return null;
        }
        List<List<T>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i <count; i++){
            List<T> subList = list.subList(i * len,((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

    /**
     * 导出大量数据-支持100万数据量
     * @param response 返回Excel
     * @param data 导出的数据
     * @param fileName excel名称
     * @param clazz 导出集合中的实体类
     * @param <T>
     * @throws Exception
     */
    public static<T> void writeExcel(HttpServletResponse response, List<T> data,String fileName, Class clazz) throws Exception {
        OutputStream output = null;
        ExcelWriter excelWriter = null;
        try {
            output = getOutputStream(fileName,response);
            if (data == null || data.isEmpty()){
                EasyExcel.write(output,clazz)
                        .excelType(ExcelTypeEnum.XLSX).sheet("sheet")
                        .registerWriteHandler(getDefaultHorizontalCellStyleStrategy())
                        .doWrite(data);
            }
            //分割集合
            List<List<T>> lists = splitList(data,MAX_ROWS);

            ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(output,clazz)
                    .excelType(ExcelTypeEnum.XLSX)
                    .registerWriteHandler(getDefaultHorizontalCellStyleStrategy());
            excelWriter = excelWriterBuilder.build();
            ExcelWriterSheetBuilder excelWriterSheetBuilder;
            for (int i = 1; i <= lists.size(); i++){
                WriteSheet writeSheet = new WriteSheet();
                excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
                excelWriterSheetBuilder.sheetNo(i);
                excelWriterSheetBuilder.sheetName("sheet" + i);
                excelWriter.write(lists.get(i - 1),writeSheet);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("导出excel失败:{}",e.getMessage());
        } finally {
            try {
                if (output != null){
                    output.flush();
                    excelWriter.finish();
                    output.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                log.info("关流失败:{}",e.getMessage());
            }
        }
    }


}

/**
* Excel导出,支持100万
* @param request 请求
* @param response 响应
* @throws Exception
*/
@GetMapping("xxx")
@ApiOperation(value = "xxx", notes = "xxx")
public void exportXxx(@Vaild @ModelAttribute PositionExtRequest request,HttpServletResponse response){
	try{
		List<PositionExtResponse> positionExtResponse = positionAppService.queryPositions(request, response);
		EasyExcelUtil.writeExcel(response,positionExtResponse,"position",PositionExtResponse.class);
	}catch(Exception e){
		log.error("xxx:{}",e.getMessage());
	}
}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐