|
|
@@ -612,15 +612,42 @@ public class WbsTreeContractController extends BladeController {
|
|
|
}
|
|
|
|
|
|
String originalFileName = excelName + ".xlsx";
|
|
|
- // 使用UTF-8编码,并替换特殊字符(符合RFC 5987标准)
|
|
|
- String encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name())
|
|
|
- .replaceAll("\\+", "%20") // 空格编码为%20(而非+)
|
|
|
- .replaceAll("%23", "#"); // 保留#不编码(或根据需求调整)
|
|
|
-
|
|
|
- // 设置响应头,采用RFC 5987标准格式(指定字符集)
|
|
|
- response.setHeader("Content-Disposition",
|
|
|
- "attachment; filename*=" + encodedFileName);
|
|
|
- response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 先将/替换为其他可接受字符
|
|
|
+ String sanitizedFileName = originalFileName.replace("/", "∕"); // 使用除号符号(U+2215)
|
|
|
+ // 或者使用其他替代字符:
|
|
|
+ // .replace("/", "/") // 全角斜杠
|
|
|
+ // .replace("/", "-") // 连字符
|
|
|
+ // .replace("/", " or ") // 文字描述
|
|
|
+
|
|
|
+ // 2. 编码其他字符
|
|
|
+ String fullyEncoded = URLEncoder.encode(sanitizedFileName, StandardCharsets.UTF_8.name());
|
|
|
+
|
|
|
+ // 3. 解码我们想要保留的其他特殊字符
|
|
|
+ String partiallyDecoded = fullyEncoded
|
|
|
+ .replaceAll("\\+", "%20") // 空格保持编码为%20
|
|
|
+ .replaceAll("%2B", "+") // 解码+号
|
|
|
+ .replaceAll("%23", "#") // 解码#号
|
|
|
+ .replaceAll("%7E", "~") // 解码~号
|
|
|
+ // / 已经被替换,不需要处理
|
|
|
+ ;
|
|
|
+
|
|
|
+ // 4. 设置响应头
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
+ response.setHeader("Content-Disposition",
|
|
|
+ "attachment; filename=\"" + partiallyDecoded + "\"; " +
|
|
|
+ "filename*=UTF-8''" + partiallyDecoded);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 备用方案
|
|
|
+ String safeFileName = originalFileName
|
|
|
+ .replaceAll("[\\\\/:*?\"<>|]", "_")
|
|
|
+ .trim();
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
+ response.setHeader("Content-Disposition",
|
|
|
+ "attachment; filename=\"" + safeFileName + "\"");
|
|
|
+ }
|
|
|
|
|
|
// 写入输出流
|
|
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|