|
|
@@ -16,7 +16,7 @@ import lombok.SneakyThrows;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.apache.poi.ss.usermodel.*;
|
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.apache.poi.xssf.usermodel.*;
|
|
|
import org.jsoup.Jsoup;
|
|
|
import org.jsoup.nodes.Document;
|
|
|
import org.jsoup.nodes.Element;
|
|
|
@@ -633,6 +633,13 @@ public class WbsTreeContractController extends BladeController {
|
|
|
if(originalFileName.startsWith("》")){
|
|
|
originalFileName=originalFileName.substring(1);
|
|
|
}
|
|
|
+ XSSFSheet sheetAt = mainWorkbook.getSheetAt(0);
|
|
|
+ if (sheetAt != null) {
|
|
|
+ XSSFRow row = sheetAt.createRow(0);
|
|
|
+ XSSFCell cell = row.createCell(0);
|
|
|
+ // 设置批注
|
|
|
+ setCommentToFirstCell(mainWorkbook, sheetAt, cell, originalFileName);
|
|
|
+ }
|
|
|
try {
|
|
|
// 1. 先编码所有字符
|
|
|
String fullyEncoded = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name());
|
|
|
@@ -643,25 +650,19 @@ public class WbsTreeContractController extends BladeController {
|
|
|
.replaceAll("%2B", "+") // 解码+号
|
|
|
.replaceAll("%2F", "/") // 解码/号
|
|
|
.replaceAll("%23", "#") // 解码#号
|
|
|
- .replaceAll("%7E", "~") // 解码~号
|
|
|
- // - 号不需要处理,URL编码不会编码-
|
|
|
- ;
|
|
|
+ .replaceAll("%7E", "~"); // 解码~号
|
|
|
|
|
|
// 3. 设置响应头
|
|
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
response.setHeader("Content-Disposition",
|
|
|
- "attachment; filename=\"" + partiallyDecoded + "\"; ");
|
|
|
+ "attachment; filename=\"" + partiallyDecoded + "\"; filename*=UTF-8''" + fullyEncoded);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
- // 备用方案:简单清理
|
|
|
- String safeFileName = originalFileName
|
|
|
- .replaceAll("[\\\\:*?\"<>|]", "_")
|
|
|
- .trim();
|
|
|
+ // 备用方案
|
|
|
+ String safeFileName = originalFileName.replaceAll("[\\\\:*?\"<>|]", "_").trim();
|
|
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
- response.setHeader("Content-Disposition",
|
|
|
- "attachment; filename=\"" + safeFileName + "\"");
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=\"" + safeFileName + "\"");
|
|
|
}
|
|
|
-
|
|
|
// 写入输出流
|
|
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
|
|
mainWorkbook.write(outputStream);
|
|
|
@@ -677,8 +678,27 @@ public class WbsTreeContractController extends BladeController {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
+ public static void setCommentToFirstCell(XSSFWorkbook workbook, XSSFSheet sheet,
|
|
|
+ XSSFCell cell, String commentText) {
|
|
|
+ // 创建绘图对象
|
|
|
+ XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
|
|
+
|
|
|
+ // 创建锚点,定位批注框
|
|
|
+ ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor();
|
|
|
+ anchor.setCol1(cell.getColumnIndex()); // 起始列
|
|
|
+ anchor.setCol2(cell.getColumnIndex() + 3); // 结束列(控制宽度)
|
|
|
+ anchor.setRow1(cell.getRowIndex()); // 起始行
|
|
|
+ anchor.setRow2(cell.getRowIndex() + 2); // 结束行(控制高度)
|
|
|
+
|
|
|
+ // 创建批注
|
|
|
+ Comment comment = drawing.createCellComment(anchor);
|
|
|
+
|
|
|
+ // 设置批注内容
|
|
|
+ comment.setString(new XSSFRichTextString(commentText));
|
|
|
+
|
|
|
+ // 将批注关联到单元格
|
|
|
+ cell.setCellComment(comment);
|
|
|
+ }
|
|
|
private void addDefaultValue(org.apache.poi.ss.usermodel.Workbook singleSheetWorkbook, String initTableName,String htmlContent,Long pId) {
|
|
|
if (singleSheetWorkbook == null || initTableName == null) {
|
|
|
return;
|