|
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.jfinal.aop.Clear;
|
|
import com.jfinal.aop.Clear;
|
|
|
import com.jfinal.kit.HttpKit;
|
|
import com.jfinal.kit.HttpKit;
|
|
|
|
|
+import com.jfinal.kit.PathKit;
|
|
|
import com.jfinal.upload.UploadFile;
|
|
import com.jfinal.upload.UploadFile;
|
|
|
import com.qlm.annotation.RequestUrl;
|
|
import com.qlm.annotation.RequestUrl;
|
|
|
import com.qlm.common.ApiResponse;
|
|
import com.qlm.common.ApiResponse;
|
|
@@ -18,6 +19,8 @@ import com.qlm.view.core.AdminView;
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
+import javax.servlet.ServletOutputStream;
|
|
|
|
|
+import java.io.File;
|
|
|
import java.io.InputStream;
|
|
import java.io.InputStream;
|
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
@@ -146,7 +149,7 @@ public class JxsNewController extends CommonController {
|
|
|
List<JxsImportDto> importList = EasyExcelUtil.getImportData(inputStream, JxsImportDto.class);
|
|
List<JxsImportDto> importList = EasyExcelUtil.getImportData(inputStream, JxsImportDto.class);
|
|
|
inputStream.close();
|
|
inputStream.close();
|
|
|
// 调用Service层导入数据
|
|
// 调用Service层导入数据
|
|
|
- ApiResponse apiResponse = jxsService.importJxs(importList, loginUser.getUsername());
|
|
|
|
|
|
|
+ ApiResponse apiResponse = jxsService.importJxs(importList, loginUser.getUsername(), getRequest().getContextPath());
|
|
|
renderJson(apiResponse);
|
|
renderJson(apiResponse);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
logger.error("导入产线产品关联信息异常:", e);
|
|
logger.error("导入产线产品关联信息异常:", e);
|
|
@@ -155,32 +158,86 @@ public class JxsNewController extends CommonController {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 导出经销商列表
|
|
|
|
|
|
|
+ * 导出经销商列表 - 直接流式下载
|
|
|
*/
|
|
*/
|
|
|
public void exportJxsList() {
|
|
public void exportJxsList() {
|
|
|
- ApiResponse apiResponse = ApiResponse.success();
|
|
|
|
|
- try {
|
|
|
|
|
- // 获取查询条件
|
|
|
|
|
- String jxsName = getPara("jxsName");
|
|
|
|
|
- String code = getPara("code");
|
|
|
|
|
- Integer status = getParaToInt("status");
|
|
|
|
|
-
|
|
|
|
|
- // 调用Service层获取导出数据
|
|
|
|
|
- List<JxsExportDto> dtos = jxsService.exportJxsList(jxsName, code,status);
|
|
|
|
|
-
|
|
|
|
|
- if (CollUtil.isEmpty(dtos)) {
|
|
|
|
|
- renderJson(ApiResponse.error("没有要导出的数据"));
|
|
|
|
|
|
|
+ // 使用 try-with-resources 确保 InputStream 和 OutputStream 都能被正确关闭
|
|
|
|
|
+ try (InputStream inputStream = generateExportInputStream()) {
|
|
|
|
|
+ if (inputStream == null) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- // 使用EasyExcelUtil生成Excel文件流
|
|
|
|
|
- InputStream inputStream = EasyExcelUtil.export(dtos, "经销商列表", JxsExportDto.class);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 设置响应头,告诉浏览器这是一个需要下载的文件
|
|
|
String fileName = URLEncoder.encode("经销商列表.xlsx", "UTF-8");
|
|
String fileName = URLEncoder.encode("经销商列表.xlsx", "UTF-8");
|
|
|
- String ossUrl = OssUtil.upload(inputStream, fileName);
|
|
|
|
|
- apiResponse = ApiResponse.success(ossUrl);
|
|
|
|
|
|
|
+ getResponse().setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 设置文件的MIME类型
|
|
|
|
|
+ getResponse().setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 手动将文件流写入响应的输出流
|
|
|
|
|
+ try (ServletOutputStream sos = getResponse().getOutputStream()) {
|
|
|
|
|
+ byte[] buffer = new byte[1024];
|
|
|
|
|
+ int len;
|
|
|
|
|
+ // 循环读取输入流,并写入到输出流
|
|
|
|
|
+ while ((len = inputStream.read(buffer)) != -1) {
|
|
|
|
|
+ sos.write(buffer, 0, len);
|
|
|
|
|
+ }
|
|
|
|
|
+ sos.flush(); // 确保所有数据都被发送
|
|
|
|
|
+ }
|
|
|
|
|
+ renderNull();
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
logger.error("导出经销商列表异常:", e);
|
|
logger.error("导出经销商列表异常:", e);
|
|
|
- renderJson(ApiResponse.error("导出经销商列表失败:" + e.getMessage()));
|
|
|
|
|
|
|
+ // 确保在异常情况下也返回一个标准的JSON错误
|
|
|
|
|
+ if (!getResponse().isCommitted()) {
|
|
|
|
|
+ renderJson(ApiResponse.error("导出经销商列表失败:" + e.getMessage()));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- renderJson(apiResponse);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 下载导入时生成的错误文件
|
|
|
|
|
+ */
|
|
|
|
|
+ public void downloadErrorFile() {
|
|
|
|
|
+ String fileId = getPara("fileId");
|
|
|
|
|
+
|
|
|
|
|
+ // 安全性检查:防止路径遍历攻击
|
|
|
|
|
+ if (fileId == null || fileId.contains("..") || fileId.contains("/")) {
|
|
|
|
|
+ renderJson(ApiResponse.error("无效的文件ID"));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String tempDir = PathKit.getWebRootPath() + "/import_error_files/";
|
|
|
|
|
+ File file = new File(tempDir + fileId);
|
|
|
|
|
+
|
|
|
|
|
+ if (file.exists() && file.isFile()) {
|
|
|
|
|
+ // 使用 JFinal 的 renderFile 方法直接将文件流式返回给客户端
|
|
|
|
|
+ // 这是 renderFile 最标准的用法
|
|
|
|
|
+ renderFile(file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ renderJson(ApiResponse.error("文件不存在或已被清理"));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 辅助方法:生成导出文件的输入流
|
|
|
|
|
+ * @return 如果有数据则返回InputStream,否则返回null并直接渲染错误信息
|
|
|
|
|
+ */
|
|
|
|
|
+ private InputStream generateExportInputStream() throws Exception {
|
|
|
|
|
+ // 获取查询条件
|
|
|
|
|
+ String jxsName = getPara("jxsName");
|
|
|
|
|
+ String code = getPara("code");
|
|
|
|
|
+ Integer status = getParaToInt("status");
|
|
|
|
|
+
|
|
|
|
|
+ // 调用Service层获取导出数据
|
|
|
|
|
+ List<JxsExportDto> dtos = jxsService.exportJxsList(jxsName, code, status);
|
|
|
|
|
+
|
|
|
|
|
+ if (CollUtil.isEmpty(dtos)) {
|
|
|
|
|
+ renderJson(ApiResponse.error("没有要导出的数据"));
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 使用EasyExcelUtil生成Excel文件流
|
|
|
|
|
+ return EasyExcelUtil.export(dtos, "经销商列表", JxsExportDto.class);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|