package com.yanzuoguang.cloud.excel; import com.yanzuoguang.cloud.helper.HttpFileHelper; import com.yanzuoguang.excel.*; import com.yanzuoguang.util.YzgError; 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 YzgError.getRuntimeException("024"); } 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 YzgError.getRuntimeException(e, "045", e.getMessage()); } 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(); } }