ExcelHttp.java 5.24 KB
package com.yanzuoguang.cloud.excel;


import com.yanzuoguang.cloud.helper.HttpFileHelper;
import com.yanzuoguang.excel.*;
import com.yanzuoguang.util.helper.FileHelper;
import com.yanzuoguang.util.helper.JsonHelper;
import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.thread.ThreadHelper;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

/**
 * HTTP方式下载Excel文件
 *
 * @param <T> 行数据的类型
 * @author 颜佐光
 */
public class ExcelHttp<T extends Object> extends ExcelConsole<T> {

    /**
     * 导出成Excel
     *
     * @param exportData 导出信息
     */
    public ExcelHttp(ExportData exportData) {
        super(exportData);
    }

    /**
     * 导出成Excel
     *
     * @param config    导出信息
     * @param rowHandle 导出下载信息
     */
    public ExcelHttp(ExportData config, ExcelRow<T> rowHandle) {
        super(config, rowHandle);
    }

    /**
     * 下载文件
     *
     * @param response 输出流
     */
    public boolean down(HttpServletResponse response) throws IOException {
        return this.down(response, StringHelper.EMPTY);
    }

    /**
     * 下载文件
     *
     * @param response     输出流
     * @param downFileName 下载文件名
     */
    public boolean down(HttpServletResponse response, String downFileName) throws IOException {
        ExportData config = this.getConfig();
        if (StringHelper.isEmpty(downFileName)) {
            downFileName = config.getDownFileName();
        }
        if (StringHelper.isEmpty(downFileName)) {
            downFileName = config.getFileName();
        }
        // 正式文件
        String fileName = this.getFileName();
        File file = new File(fileName);
        // 临时文件
        String fileNameTemp = this.getFileNameTemp();
        File fileTemp = new File(fileNameTemp);
        // 临时文件行数
        String fileNameRow = this.getFileNameRow();
        File fileRow = new File(fileNameRow);

        boolean ok = file.exists();
        boolean isDown = ok && config.getExportType() != ExportData.EXPORT_TYPE_WAIT;
        if (isDown) {
            // 下载文件
            HttpFileHelper.localToDown(this.getFileName(), downFileName, response);
        } else {
            // 返回文件名和生成的文件大小
            // 假如连续1分钟返回文件大小为0,则说明性能存在问题,或者是其他线程已经删除文件
            ExportTempRes res = new ExportTempRes();
            res.setFileName(config.getFileName());
            res.setSize(fileTemp.length());
            res.setRow(StringHelper.toLong(FileHelper.readFile(fileRow, "utf-8")));
            res.setOk(ok);
            // 输出结果
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().print(JsonHelper.serialize(res));
        }
        return isDown;
    }

    /**
     * 导出数据
     *
     * @param req      请求对接
     * @param response 输出结果
     * @param excelDao dao层实现接口
     */
    public static <T extends Object, M extends Object> void export(ExportBase<T> req, HttpServletResponse response, ExcelDao<T, M> excelDao) {
        ExportData config = req.getConfig();
        if (config == null) {
            throw new RuntimeException("导出时请传入配置信息");
        }
        if (StringHelper.isEmpty(config.getServerPath())) {
            config.setServerPath("/home/cache/");
        }
        boolean isEmptyFile = StringHelper.isEmpty(config.getFileName());
        if (isEmptyFile) {
            config.setFileName(String.format("%s.xlsx", StringHelper.getNewID()));
        }
        if (StringHelper.isEmpty(config.getDownFileName())) {
            config.setDownFileName(String.format("%s-%s.xlsx", config.getTitle(), config.getSubTitle()));
        }
        ExcelHttp<M> excel = new ExcelHttp<>(config);
        boolean isDown = false;
        try {
            int type = StringHelper.toInt(config.getExportType());
            if (type == ExportData.EXPORT_TYPE_COMMON) {
                // 普通模式生成文件并下载
                releaseExcel(req, excelDao, excel);
            } else if (isEmptyFile) {
                // 等待下载模式,开启线程生成文件
                ThreadHelper.runThread(new Runnable() {
                    @Override
                    public void run() {
                        releaseExcel(req, excelDao, excel);
                    }
                });
            }
            // 等待下载模式,下载文件
            isDown = excel.down(response);
        } catch (IOException e) {
            isDown = true;
            e.printStackTrace();
            throw new RuntimeException("下载失败", e);
        } finally {
            if (isDown) {
                // 删除生成的临时文件
                excel.remove();
            }
        }
    }

    private static <T, M> void releaseExcel(ExportBase<T> req, ExcelDao<T, M> excelDao, ExcelHttp<M> excel) {
        excel.open();
        excelDao.export(excel, req.getCond());
        if (excelDao instanceof ExcelDaoFinish) {
            ((ExcelDaoFinish<T, M>) excelDao).finish(excel);
        }
        excel.save();
    }
}