浏览代码

批量导入Excel导入模板

cr 6 天之前
父节点
当前提交
cec10a8f21

+ 64 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java

@@ -444,6 +444,45 @@ public class WbsTreeContractController extends BladeController {
         if (ObjectUtil.isEmpty(formList)) {
             throw new ServiceException("该节点下没有找到对应的表单数据");
         }
+        // 对formList进行排序:主表优先,复制表按数字顺序排列
+        formList.sort((contract1, contract2) -> {
+            String name1 = contract1.getNodeName().replaceAll("\\s+", "");
+            String name2 = contract2.getNodeName().replaceAll("\\s+", "");
+
+            boolean isCopy1 = name1.contains("__");
+            boolean isCopy2 = name2.contains("__");
+
+            // 如果一个是主表,一个是复制表,主表排在前面
+            if (isCopy1 != isCopy2) {
+                return isCopy1 ? 1 : -1;
+            }
+
+            // 如果都是主表或都是复制表
+            if (!isCopy1 && !isCopy2) {
+                // 都是主表,按字母顺序排序
+                return name1.compareTo(name2);
+            } else {
+                // 都是复制表,按主表名称和数字排序
+                String[] parts1 = name1.split("__", 2);
+                String[] parts2 = name2.split("__", 2);
+
+                // 先比较主表名称
+                int mainNameCompare = parts1[0].compareTo(parts2[0]);
+                if (mainNameCompare != 0) {
+                    return mainNameCompare;
+                }
+
+                // 主表名称相同,比较数字部分
+                try {
+                    int num1 = Integer.parseInt(parts1[1]);
+                    int num2 = Integer.parseInt(parts2[1]);
+                    return Integer.compare(num1, num2);
+                } catch (NumberFormatException e) {
+                    // 如果解析数字失败,按字符串比较
+                    return parts1[1].compareTo(parts2[1]);
+                }
+            }
+        });
 
         // 获取节点及祖先节点信息用于构建文件名
         WbsTreeContract node = wbsTreeContractServiceImpl.getById(nodeId);
@@ -514,11 +553,21 @@ public class WbsTreeContractController extends BladeController {
                 throw new ServiceException("所有表单均无法生成有效Excel内容");
             }
 
-            // 设置响应头
-            String encodedFileName = URLEncoder.encode(excelName + ".xlsx", "UTF-8")
-                    .replaceAll("\\+", " ")
-                    .replaceAll("%2B", "+");
-            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
+            // 处理包含特殊符号的文件名(如#、空格、中文等)
+             String originalFileName = excelName + ".xlsx";
+              // 使用UTF-8编码,并替换特殊字符(符合RFC 5987标准)
+            String encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name())
+                    .replaceAll("\\+", "%20") // 空格编码为%20(而非+)
+                    .replaceAll("%23", "#")
+                    .replaceAll("%26", "&"); // 保留#不编码(或根据需求调整)
+
+              // 设置响应头,采用RFC 5987标准格式(指定字符集)
+              // 双格式响应头:同时支持旧版和新版浏览器
+             response.setHeader("Content-Disposition",
+                    "attachment; " +
+                            "filename=\"" + encodedFileName + "\"; " +  // 旧格式(部分浏览器依赖)
+                            "filename*=UTF-8''" + encodedFileName       // 新标准格式
+             );
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
 
             // 写入输出流
@@ -780,6 +829,15 @@ public class WbsTreeContractController extends BladeController {
                     continue;
                 }
                 Map<String, String> dataMap = getDataMap(sheetResult);
+                // 对所有value中的单引号进行转义处理
+                for (Map.Entry<String, String> entry : dataMap.entrySet()) {
+                    String value = entry.getValue();
+                    if (value != null && value.contains("'")) {
+                        // 将单引号转义为 \'
+                        value = value.replace("'", "\\'");
+                        entry.setValue(value);
+                    }
+                }
                 String delSql = "delete from " + matchedContract.getInitTableName() + " where p_key_id=" + matchedContract.getPKeyId();
                 dataMap.put("p_key_id", matchedContract.getPKeyId()+"");
                 String  sqlInfo = buildMTableInsertSql(matchedContract.getInitTableName(), dataMap, SnowFlakeUtil.getId(), null, null).toString();
@@ -901,7 +959,7 @@ public class WbsTreeContractController extends BladeController {
             } catch (Exception e) {
                 e.printStackTrace();
             }
-            valSql.append(", '").append(data).append("'");
+            valSql.append(", ").append(data).append("'");
         }
         sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
         return sql;