Easyexcel excel导出工具包 (正常导出、大数据导出)

package cn.hsa.zjhsb.bpgj.common.utils;

import cn.hsa.hsaf.core.framework.web.WrapperResponse;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.commons.collections.CollectionUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Stream;

/**
 * @author 
 * @version 1.0
 * @date 2022/06/28
 */
public class ExcelUtil {

    private static final String CHARACTER = "UTF-8";

    private static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    private static final String CONTENT_DISPOSITION = "Content-Disposition";

    private static final String CACHE_CONTROL = "Cache-Control";

    private static final String NO_STORE = "no-store";

    private static final String MAX_AGE = "max-age=0";


    public static <T, E> void export(HttpServletResponse response, String title, List<T> list, Class<E> tClass) throws IOException {
        export(response, title, list, tClass, null);
    }

    public static <T, E> void export(HttpServletResponse response, String title, List<T> list, Class<E> tClass, Set<String> excludeColumnFiledNames) throws IOException {

        response.setContentType(CONTENT_TYPE);
        response.setCharacterEncoding(CHARACTER);

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(title, CHARACTER).replaceAll("\\+", "%20");
        response.setHeader(CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + fileName + ".xlsx");
        Map<String, PropertyDescriptor> map = BeanUtil.getPropertyDescriptorMap(tClass, false);
        // 根据用户传入字段
        Set<String> includeColumnFiledNames = map.keySet();
        ExcelWriterSheetBuilder builder = EasyExcel.write(response.getOutputStream(), tClass)
                //自动列宽
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .includeColumnFiledNames(includeColumnFiledNames)
                .autoCloseStream(Boolean.FALSE)
                .sheet(title);
        if (CollectionUtils.isNotEmpty(includeColumnFiledNames)) {
            builder.excludeColumnFiledNames(excludeColumnFiledNames);
        }
        builder.doWrite(list);
    }

    public static void writeError(HttpServletResponse response, WrapperResponse<?> resp) throws IOException {
        // 重置response
        response.reset();
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        response.getWriter().println(resp.getClass());
    }

    /**
     * 大数据导出
     * 分页写入到excel
     *
     * @param biFunction 分页遍历时的回调函数
     * @param response   HttpServletResponse
     * @param sheetName  标题
     * @param pojoClass  导出类型
     * @param pageSize   每页大小
     * @param total      总数
     * @param <R>        导出类型
     * @param <U>        查询结果类型
     * @throws IOException IOException
     */
    public static <R, U> void exportPageExcel(BiFunction<Integer, Integer, List<U>> biFunction, HttpServletResponse response, String sheetName, Class<R> pojoClass, int pageSize, int total) throws IOException {
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(sheetName, CHARACTER).replaceAll("\\+", "%20");

        ServletOutputStream out = response.getOutputStream();
        //设置字符集为utf-8
        response.setCharacterEncoding(CHARACTER);
        response.setContentType(CONTENT_TYPE);
        //通知浏览器服务器发送的数据格式
        response.setHeader(CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + fileName + ".xlsx");

        //发送一个报头,告诉浏览器当前页面不进行缓存,每次访问的时间必须从服务器上读取最新的数据
        response.setHeader(CACHE_CONTROL, NO_STORE);
        response.addHeader(CACHE_CONTROL, MAX_AGE);
        // 这里 需要指定写用哪个class去写
        Map<String, PropertyDescriptor> map = BeanUtil.getPropertyDescriptorMap(pojoClass, false);
        Set<String> includeColumnFiledNames = map.keySet();
        ExcelWriter excelWriter = EasyExcel.write(out, pojoClass).includeColumnFiledNames(includeColumnFiledNames).build();
        // 这里注意 如果同一个sheet只要创建一次
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();

        //总页数
        int pageAll = total / pageSize + (total % pageSize != 0 ? 1 : 0);

        //通过parallel 并行 遍历1到pageAll
        Stream.iterate(1, item -> item + 1).limit(pageAll).parallel()
                .map(pageNo -> biFunction.apply(pageNo, pageSize))
                .forEachOrdered(excelList -> {
                    //forEachOrdered 按照原始数据的顺序遍历excelList,
                    //将每个excelList 依次写入excel
                    excelWriter.write(excelList, writeSheet);
                });
        // 千万别忘记finish 会帮忙关闭流
        excelWriter.finish();
        out.flush();
    }


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值