其他分享
首页 > 其他分享> > 【easyexcel】1.实时下载导出报表

【easyexcel】1.实时下载导出报表

作者:互联网

 

 

实时下载导出报表

====================================================================================

1.修改总览

 

 

 

 

 

 

1.pom.xml

<!-- 阿里巴巴easyexcel start-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>${easyexcel.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>cglib</groupId>
                    <artifactId>cglib</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <!-- 阿里巴巴easyexcel end-->
View Code

 

 

2.controller

package com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.controller;


import com.alibaba.fastjson.JSON;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.dto.ReportDTO;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.enums.ReportEnum;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.exception.ReportException;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.query.DUQuery;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

@Slf4j
@Validated
@RestController
@RequestMapping("/xlsx/downloadAndUpload")
public class XlsxDownloadAndUploadController {


    @Resource
    private ReportService reportService;

    /**
     * 实时下载  xlsx文件
     * 将根据查询条件实时查询到的数据  通过 xlsx文件导出
     * @param query 导出查询条件
     * @return
     */
    @RequestMapping(value = "/rtDownload", method = {RequestMethod.GET})
    public void rtDownload(HttpServletResponse response, @Valid DUQuery query) {
        OutputStream outputStream = null;
        FileInputStream inputStream =null;
        File file = null;
        try {

            ReportDTO dto = new ReportDTO();
            dto.setReportEnum(ReportEnum.RT_REPORT);
            dto.setRequestParams(JSON.toJSONString(query));
            file = reportService.generateReport(dto);



            response.setContentType("mutipart/form-data");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(file.getName(), "utf-8"));
            outputStream = response.getOutputStream();


            inputStream = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(b)) != -1) {
                outputStream.write(b, 0, length);
            }
            outputStream.flush();


        } catch (Exception e) {
            log.error("导出业务报表发生错误:", e);
            throw new ReportException("导出业务报表发生错误!");
        }finally{
            reportService.close(outputStream,inputStream);
            reportService.delFile(file);
        }
    }

}
View Code

 

3.报表service

package com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.context.ReportGenerateContext;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.dto.ReportDTO;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.enums.ReportEnum;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.exception.ReportException;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.handler.AbstractReportHandler;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.service.ReportService;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.utils.XlsxCellWidthUtil;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.utils.XlsxCellWriteUtil;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.utils.XlsxHeadUtil;
import com.sxd.swapping.utils.serialNum.SerialNumHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

/**
 * 业务报表Service
 *
 * 报表导出的 核心逻辑在这里
 *
 * 1.边读边写 解决FullGC问题
 * 2.集成多种业务报表   不同的报表类型可以在ReportEnum中以不同枚举定义  定义入参class  出参class  报表名称 等关键信息
 * 3.单元格支持超过15位长的纯数字串不会显示成E+问题
 * 4.generateReport()  生成临时File,支持【实时导出】  和 【上传远程服务器得到可直接下载的URL 暂未实现】
 */
@Slf4j
@Service
public class ReportServiceImpl implements ReportService {


    @Resource
    private ReportGenerateContext reportGenerateContext;

    /**
     * 生成报表临时文件
     * @param reportDTO
     * @return
     */
    @Override
    public File generateReport(ReportDTO reportDTO) {
        ReportEnum reportEnum = reportDTO.getReportEnum();
        if (reportEnum == null) {
            throw new ReportException("报表类型必传!");
        }

        if (StringUtils.isBlank(reportDTO.getRequestParams())) {
            throw new ReportException("报表入参数据必传!");
        }



        //1.获取临时文件路径[需定义自定义报表枚举]
        String filePath = getFilePath(reportEnum.getTempFileName());




        //2.初始化xlsx文件对象 [需定义自定义表头工具]
        ExcelWriter excelWriter = EasyExcel
                .write(filePath, reportEnum.getReportClass())
//                .registerWriteHandler(new XlsxCellFontUtil())       //默认情况不用显式设置,除非业务有需求
//                .registerWriteHandler(XlsxCellStyleUtil.getCellStyleStrategy())  //默认情况不用显式设置,除非业务有需求
                .registerWriteHandler(new XlsxCellWidthUtil())      //一般情况下可以不用设置,除非表头没正常生成
                .registerWriteHandler(new XlsxCellWriteUtil())      //如果导出数据中,有超过15位的数字串,则需要设置
                .head(XlsxHeadUtil.getHeadByReportEnum(reportEnum)) //一般情况可以不用设置,除非表头没正常生成
                .build();
        WriteSheet writeSheet = EasyExcel.writerSheet(reportEnum.getDesc()).build();
        reportDTO.setExcelWriter(excelWriter);
        reportDTO.setWriteSheet(writeSheet);



        //3.获取报表handler完成xlsx文件生成[需定义自定义handler并加入上下文]
        AbstractReportHandler reportHandler = reportGenerateContext.getReportHandler(reportEnum);
        reportHandler.generateReport(reportDTO);



        //4.关闭easyxlsx写入器
        excelWriter.finish();


        return new File(filePath);
    }

    /**
     * 根据文件名获取文件路径
     * @param tempFileName
     * @return
     */
    @Override
    public String getFilePath(String tempFileName) {
        Properties properties = System.getProperties();
        String path = properties.getProperty("user.dir");
        if (properties.getProperty("os.name").toLowerCase().contains("win")) {
            path += "\\";
        } else {
            path += "/";
        }
        path += String.format(tempFileName, SerialNumHelper.generateRecordId());

        log.info("DownloadServiceImpl#getFilePath={}" , path);
        return path;
    }

    /**
     * 删除临时文件
     * @param file
     */
    @Override
    public void delFile(File file) {
        if (file != null && file.exists()) {
            try {
                file.delete();
            }catch (Exception e) {
                log.error("删除临时文件失败:", e);
            }
        }
    }

    /**
     * 关闭资源
     * @param outputStream
     * @param inputStream
     */
    @Override
    public void close(OutputStream outputStream, InputStream inputStream) {
        closeOutStream(outputStream);
        cloaseInputStream(inputStream);
    }

    @Override
    public void closeOutStream(OutputStream outputStream) {
        if(outputStream !=null){
            try {
                outputStream.close();
            } catch (IOException e) {
                log.error("关闭输出流失败:", e);
            }
        }
    }

    @Override
    public void cloaseInputStream(InputStream inputStream) {
        if(inputStream != null ){
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error("关闭输入流失败:", e);
            }
        }
    }
}
View Code

 

 

4.报表枚举ReportEnum

package com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.enums;


import com.fasterxml.jackson.annotation.JsonCreator;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.query.DUQuery;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.vo.RTReportVO;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.Objects;

@AllArgsConstructor
@Getter
public enum  ReportEnum {

    /** 枚举项 */
    RT_REPORT(1, "实时导出报表", RTReportVO.class, DUQuery.class,"实时导出报表-%s.xlsx"),

    ;

    /**值*/
    private Integer value;

    /**报表描述*/
    private String desc;

    /**导出模板*/
    private Class reportClass;

    /**业务入参*/
    private Class requestParams;

    /**报表文件名称*/
    private String tempFileName;



    @JsonCreator
    public static ReportEnum valueOf(Integer value) {
        return Arrays.stream(ReportEnum.values())
                .filter(e -> Objects.equals(e.value, value)).findFirst()
                .orElseThrow(() -> new RuntimeException("ReportEnum value=" + value + " not exists!"));
    }
}
View Code

 

5.业务枚举DUStatusEnum

package com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.enums;

import com.fasterxml.jackson.annotation.JsonCreator;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.Objects;

@AllArgsConstructor
@Getter
public enum DUStatusEnum {



    WAIT(0,"等待处理"),

    SUCCESS(1,"成功"),

    FAIL(-1, "失败")
    ;

    /**值*/
    private Integer value;

    /**报表描述*/
    private String desc;


    @JsonCreator
    public static DUStatusEnum valueOf(Integer value) {
        return Arrays.stream(DUStatusEnum.values())
                .filter(e -> Objects.equals(e.value, value)).findFirst()
                .orElseThrow(() -> new RuntimeException("DUStatusEnum value=" + value + " not exists!"));
    }

}
View Code

 

 

6.报表上下文ReportGenerateContext

package com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.context;

import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.enums.ReportEnum;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.handler.AbstractReportHandler;
import com.sxd.swapping.downloadAndUpload.xlsxDownloadAndUpload.handler.RTReportHandler;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

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

/**
 * 报表生成上下文
 */
@Component
public class ReportGenerateContext implements ApplicationContextAware {

    private Map<ReportEnum, AbstractReportHandler> reportHandlerMap;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (reportHandlerMap == null) {
            reportHandlerMap = new HashMap<>();
            reportHandlerMap.put(ReportEnum.RT_REPORT,applicationContext.getBean(RTReportHandler.class));
        }
    }


    public AbstractReportHandler getReportHandler(ReportEnum reportEnum){
        return reportHandlerMap.get(reportEnum);
    }
}
View Code

 

 

 

 

 

 

请求实时下载:

http://localhost:9666/xlsx/downloadAndUpload/rtDownload

 

 

 

生成报表结果展示:

 

标签:downloadAndUpload,sxd,报表,easyexcel,导出,import,com,xlsxDownloadAndUpload,swapping
来源: https://www.cnblogs.com/sxdcgaq8080/p/14823458.html