|
@@ -15,6 +15,8 @@ import com.hotent.project.model.CostProjectTask;
|
|
|
import com.hotent.project.model.CostProjectTaskMaterial;
|
|
import com.hotent.project.model.CostProjectTaskMaterial;
|
|
|
import com.hotent.surveyinfo.dao.CostSurveyFdTemplateItemsDao;
|
|
import com.hotent.surveyinfo.dao.CostSurveyFdTemplateItemsDao;
|
|
|
import com.hotent.surveyinfo.dao.CostSurveyTemplateItemsDao;
|
|
import com.hotent.surveyinfo.dao.CostSurveyTemplateItemsDao;
|
|
|
|
|
+import com.hotent.surveyinfo.dao.CostVerifyTemplateHeadersDao;
|
|
|
|
|
+import com.hotent.surveyinfo.dao.CostVerifyTemplateItemsDao;
|
|
|
import com.hotent.surveyinfo.manager.*;
|
|
import com.hotent.surveyinfo.manager.*;
|
|
|
import com.hotent.surveyinfo.model.*;
|
|
import com.hotent.surveyinfo.model.*;
|
|
|
import com.hotent.util.ExcelStyleUtil;
|
|
import com.hotent.util.ExcelStyleUtil;
|
|
@@ -79,9 +81,18 @@ public class CostSurveyExcelAsyncService {
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private CellDataQueryService cellDataQueryService;
|
|
private CellDataQueryService cellDataQueryService;
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CostVerifyTemplateManager costVerifyTemplateManager;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CostVerifyTemplateHeadersDao costVerifyTemplateHeadersDao;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CostVerifyTemplateItemsDao costVerifyTemplateItemsDao;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 异步生成Excel文件并保存到文件服务器
|
|
* 异步生成Excel文件并保存到文件服务器
|
|
|
- * @param type 类型:1-成本调查表 2-财务数据表
|
|
|
|
|
|
|
+ * @param type 类型:1-成本调查表 2-财务数据表 3-核定表
|
|
|
* @param surveyTemplateId 模板ID
|
|
* @param surveyTemplateId 模板ID
|
|
|
* @param taskId 任务ID
|
|
* @param taskId 任务ID
|
|
|
* @param refId 关联ID(成本调查表的uploadId或财务数据表的materialId)
|
|
* @param refId 关联ID(成本调查表的uploadId或财务数据表的materialId)
|
|
@@ -118,6 +129,8 @@ public class CostSurveyExcelAsyncService {
|
|
|
fileName = generateCostSurveyExcel(workbook, surveyTemplateId, taskId, refId, auditPeriods);
|
|
fileName = generateCostSurveyExcel(workbook, surveyTemplateId, taskId, refId, auditPeriods);
|
|
|
} else if ("2".equals(type)) {
|
|
} else if ("2".equals(type)) {
|
|
|
fileName = generateFinancialDataExcel(workbook, surveyTemplateId, taskId, refId, auditPeriods);
|
|
fileName = generateFinancialDataExcel(workbook, surveyTemplateId, taskId, refId, auditPeriods);
|
|
|
|
|
+ } else if ("3".equals(type)) {
|
|
|
|
|
+ fileName = generateVerifyExcel(workbook, surveyTemplateId, taskId);
|
|
|
} else {
|
|
} else {
|
|
|
workbook.close();
|
|
workbook.close();
|
|
|
return;
|
|
return;
|
|
@@ -223,10 +236,6 @@ public class CostSurveyExcelAsyncService {
|
|
|
totalColumns += 1;
|
|
totalColumns += 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- boolean needExtraColumns = "2".equals(templateType) || "3".equals(templateType);
|
|
|
|
|
- if (needExtraColumns) {
|
|
|
|
|
- totalColumns += 2;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
Row titleRow = sheet.createRow(0);
|
|
Row titleRow = sheet.createRow(0);
|
|
|
Cell titleCell = titleRow.createCell(0);
|
|
Cell titleCell = titleRow.createCell(0);
|
|
@@ -284,15 +293,18 @@ public class CostSurveyExcelAsyncService {
|
|
|
idx += 1;
|
|
idx += 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- fillExcelData(sheet, itemsList, headerIndexMap, headersList, auditPeriods, templateType, rowIdColIndex, parentIdColIndex, dataStyle, taskId);
|
|
|
|
|
|
|
+ fillExcelData(sheet, itemsList, headerIndexMap, headersList, auditPeriods, templateType, rowIdColIndex, parentIdColIndex, dataStyle, taskId, uploadDataList);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Row headerRowForWidth = sheet.getRow(1);
|
|
Row headerRowForWidth = sheet.getRow(1);
|
|
|
int totalColsForWidth = headerRowForWidth != null ? headerRowForWidth.getLastCellNum() : headersList.size();
|
|
int totalColsForWidth = headerRowForWidth != null ? headerRowForWidth.getLastCellNum() : headersList.size();
|
|
|
for (int i = 0; i < totalColsForWidth; i++) {
|
|
for (int i = 0; i < totalColsForWidth; i++) {
|
|
|
- sheet.autoSizeColumn(i);
|
|
|
|
|
- int autoWidth = sheet.getColumnWidth(i);
|
|
|
|
|
- sheet.setColumnWidth(i, Math.max(autoWidth + 800, 3500));
|
|
|
|
|
|
|
+ Cell cell = headerRowForWidth.getCell(i);
|
|
|
|
|
+ String headerText = cell != null ? cell.getStringCellValue() : "";
|
|
|
|
|
+ int charWidth = ExcelStyleUtil.calculateCharWidth(headerText);
|
|
|
|
|
+ // 每个字符约256单位,再加一些边距
|
|
|
|
|
+ int columnWidth = (charWidth + 4) * 256;
|
|
|
|
|
+ sheet.setColumnWidth(i, Math.max(columnWidth, 3500));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (rowIdColIndex >= 0) sheet.setColumnHidden(rowIdColIndex, true);
|
|
if (rowIdColIndex >= 0) sheet.setColumnHidden(rowIdColIndex, true);
|
|
@@ -351,10 +363,6 @@ public class CostSurveyExcelAsyncService {
|
|
|
totalColumns += 1;
|
|
totalColumns += 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- boolean needExtraColumns = "2".equals(templateType) || "3".equals(templateType);
|
|
|
|
|
- if (needExtraColumns) {
|
|
|
|
|
- totalColumns += 2;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
Row titleRow = sheet.createRow(0);
|
|
Row titleRow = sheet.createRow(0);
|
|
|
Cell titleCell = titleRow.createCell(0);
|
|
Cell titleCell = titleRow.createCell(0);
|
|
@@ -412,15 +420,18 @@ public class CostSurveyExcelAsyncService {
|
|
|
idx += 1;
|
|
idx += 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- fillExcelDataFd(sheet, itemsList, headerIndexMap, headersList, auditPeriods, templateType, rowIdColIndex, parentIdColIndex, dataStyle, taskId);
|
|
|
|
|
|
|
+ fillExcelDataFd(sheet, itemsList, headerIndexMap, headersList, auditPeriods, templateType, rowIdColIndex, parentIdColIndex, dataStyle, taskId, uploadDataList);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Row headerRowForWidth = sheet.getRow(1);
|
|
Row headerRowForWidth = sheet.getRow(1);
|
|
|
int totalColsForWidth = headerRowForWidth != null ? headerRowForWidth.getLastCellNum() : headersList.size();
|
|
int totalColsForWidth = headerRowForWidth != null ? headerRowForWidth.getLastCellNum() : headersList.size();
|
|
|
for (int i = 0; i < totalColsForWidth; i++) {
|
|
for (int i = 0; i < totalColsForWidth; i++) {
|
|
|
- sheet.autoSizeColumn(i);
|
|
|
|
|
- int autoWidth = sheet.getColumnWidth(i);
|
|
|
|
|
- sheet.setColumnWidth(i, Math.max(autoWidth + 800, 3500));
|
|
|
|
|
|
|
+ Cell cell = headerRowForWidth.getCell(i);
|
|
|
|
|
+ String headerText = cell != null ? cell.getStringCellValue() : "";
|
|
|
|
|
+ int charWidth = ExcelStyleUtil.calculateCharWidth(headerText);
|
|
|
|
|
+ // 每个字符约256单位,再加一些边距
|
|
|
|
|
+ int columnWidth = (charWidth + 4) * 256;
|
|
|
|
|
+ sheet.setColumnWidth(i, Math.max(columnWidth, 3500));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (rowIdColIndex >= 0) sheet.setColumnHidden(rowIdColIndex, true);
|
|
if (rowIdColIndex >= 0) sheet.setColumnHidden(rowIdColIndex, true);
|
|
@@ -431,18 +442,22 @@ public class CostSurveyExcelAsyncService {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 合并上传数据到成本调查表模板项
|
|
* 合并上传数据到成本调查表模板项
|
|
|
|
|
+ * uploadData 的 rkey 是字段名(如"项目名称"或"2025年(绑定年限)")
|
|
|
|
|
+ * item 的 rkey 也是字段名,需要用 rowid + rkey 来匹配
|
|
|
*/
|
|
*/
|
|
|
private void mergeUploadDataToItems(List<CostSurveyTemplateItems> itemsList, List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
private void mergeUploadDataToItems(List<CostSurveyTemplateItems> itemsList, List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
|
if (itemsList == null || uploadDataList == null || uploadDataList.isEmpty()) return;
|
|
if (itemsList == null || uploadDataList == null || uploadDataList.isEmpty()) return;
|
|
|
|
|
|
|
|
|
|
+ // 构建 rowid + "_" + rkey -> rvalue 的映射
|
|
|
Map<String, String> uploadDataMap = new HashMap<>();
|
|
Map<String, String> uploadDataMap = new HashMap<>();
|
|
|
for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
|
String key = data.getRowid() + "_" + data.getRkey();
|
|
String key = data.getRowid() + "_" + data.getRkey();
|
|
|
uploadDataMap.put(key, data.getRvalue());
|
|
uploadDataMap.put(key, data.getRvalue());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 用 item 的 rowid + rkey 来匹配
|
|
|
for (CostSurveyTemplateItems item : itemsList) {
|
|
for (CostSurveyTemplateItems item : itemsList) {
|
|
|
- String key = item.getRowid() + "_" + item.getHeadersId();
|
|
|
|
|
|
|
+ String key = item.getRowid() + "_" + item.getRkey();
|
|
|
if (uploadDataMap.containsKey(key)) {
|
|
if (uploadDataMap.containsKey(key)) {
|
|
|
item.setRvalue(uploadDataMap.get(key));
|
|
item.setRvalue(uploadDataMap.get(key));
|
|
|
}
|
|
}
|
|
@@ -451,18 +466,22 @@ public class CostSurveyExcelAsyncService {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 合并上传数据到财务数据表模板项
|
|
* 合并上传数据到财务数据表模板项
|
|
|
|
|
+ * uploadData 的 rkey 是字段名(如"项目名称"或"2025年(绑定年限)")
|
|
|
|
|
+ * item 的 rkey 也是字段名,需要用 rowid + rkey 来匹配
|
|
|
*/
|
|
*/
|
|
|
private void mergeUploadDataToFdItems(List<CostSurveyFdTemplateItems> itemsList, List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
private void mergeUploadDataToFdItems(List<CostSurveyFdTemplateItems> itemsList, List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
|
if (itemsList == null || uploadDataList == null || uploadDataList.isEmpty()) return;
|
|
if (itemsList == null || uploadDataList == null || uploadDataList.isEmpty()) return;
|
|
|
|
|
|
|
|
|
|
+ // 构建 rowid + "_" + rkey -> rvalue 的映射
|
|
|
Map<String, String> uploadDataMap = new HashMap<>();
|
|
Map<String, String> uploadDataMap = new HashMap<>();
|
|
|
for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
|
String key = data.getRowid() + "_" + data.getRkey();
|
|
String key = data.getRowid() + "_" + data.getRkey();
|
|
|
uploadDataMap.put(key, data.getRvalue());
|
|
uploadDataMap.put(key, data.getRvalue());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 用 item 的 rowid + rkey 来匹配
|
|
|
for (CostSurveyFdTemplateItems item : itemsList) {
|
|
for (CostSurveyFdTemplateItems item : itemsList) {
|
|
|
- String key = item.getRowid() + "_" + item.getHeadersId();
|
|
|
|
|
|
|
+ String key = item.getRowid() + "_" + item.getRkey();
|
|
|
if (uploadDataMap.containsKey(key)) {
|
|
if (uploadDataMap.containsKey(key)) {
|
|
|
item.setRvalue(uploadDataMap.get(key));
|
|
item.setRvalue(uploadDataMap.get(key));
|
|
|
}
|
|
}
|
|
@@ -472,10 +491,20 @@ public class CostSurveyExcelAsyncService {
|
|
|
private void fillExcelData(Sheet sheet, List<CostSurveyTemplateItems> itemsList,
|
|
private void fillExcelData(Sheet sheet, List<CostSurveyTemplateItems> itemsList,
|
|
|
Map<String, Integer> headerIndexMap, List<CostSurveyTemplateHeaders> headersList,
|
|
Map<String, Integer> headerIndexMap, List<CostSurveyTemplateHeaders> headersList,
|
|
|
String[] auditPeriods, String templateType,
|
|
String[] auditPeriods, String templateType,
|
|
|
- int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle, String taskId) {
|
|
|
|
|
|
|
+ int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle, String taskId,
|
|
|
|
|
+ List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
|
Map<String, CostSurveyTemplateHeaders> headersMap = headersList.stream()
|
|
Map<String, CostSurveyTemplateHeaders> headersMap = headersList.stream()
|
|
|
.collect(Collectors.toMap(CostSurveyTemplateHeaders::getId, h -> h));
|
|
.collect(Collectors.toMap(CostSurveyTemplateHeaders::getId, h -> h));
|
|
|
|
|
|
|
|
|
|
+ // 构建 rowid + "_" + rkey -> rvalue 的映射,用于获取年限字段的数据
|
|
|
|
|
+ Map<String, String> uploadDataMap = new HashMap<>();
|
|
|
|
|
+ if (uploadDataList != null) {
|
|
|
|
|
+ for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
|
|
|
+ String key = data.getRowid() + "_" + data.getRkey();
|
|
|
|
|
+ uploadDataMap.put(key, data.getRvalue());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if ("1".equals(templateType)) {
|
|
if ("1".equals(templateType)) {
|
|
|
Row dataRow = sheet.createRow(2);
|
|
Row dataRow = sheet.createRow(2);
|
|
|
for (CostSurveyTemplateItems item : itemsList) {
|
|
for (CostSurveyTemplateItems item : itemsList) {
|
|
@@ -483,9 +512,15 @@ public class CostSurveyExcelAsyncService {
|
|
|
if (colIndex != null) {
|
|
if (colIndex != null) {
|
|
|
CostSurveyTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
CostSurveyTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
|
|
|
+ // 绑定监审年限的字段,从 uploadDataMap 中获取数据
|
|
|
|
|
+ String fieldName = header.getFieldName();
|
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
|
- cell.setCellValue("");
|
|
|
|
|
|
|
+ // rkey 格式:年限+字段名,如 "2025年(绑定年限)"
|
|
|
|
|
+ String rkey = auditPeriods[i].trim() + fieldName;
|
|
|
|
|
+ String key = item.getRowid() + "_" + rkey;
|
|
|
|
|
+ String value = uploadDataMap.get(key);
|
|
|
|
|
+ cell.setCellValue(StringUtil.isNotEmpty(value) ? value : "");
|
|
|
cell.setCellStyle(dataStyle);
|
|
cell.setCellStyle(dataStyle);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -521,9 +556,15 @@ public class CostSurveyExcelAsyncService {
|
|
|
if (colIndex != null) {
|
|
if (colIndex != null) {
|
|
|
CostSurveyTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
CostSurveyTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
|
|
|
+ // 绑定监审年限的字段,从 uploadDataMap 中获取数据
|
|
|
|
|
+ String fieldName = header.getFieldName();
|
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
|
- cell.setCellValue("");
|
|
|
|
|
|
|
+ // rkey 格式:年限+字段名,如 "2025年(绑定年限)"
|
|
|
|
|
+ String rkey = auditPeriods[i].trim() + fieldName;
|
|
|
|
|
+ String key = item.getRowid() + "_" + rkey;
|
|
|
|
|
+ String value = uploadDataMap.get(key);
|
|
|
|
|
+ cell.setCellValue(StringUtil.isNotEmpty(value) ? value : "");
|
|
|
cell.setCellStyle(dataStyle);
|
|
cell.setCellStyle(dataStyle);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -629,10 +670,20 @@ public class CostSurveyExcelAsyncService {
|
|
|
private void fillExcelDataFd(Sheet sheet, List<CostSurveyFdTemplateItems> itemsList,
|
|
private void fillExcelDataFd(Sheet sheet, List<CostSurveyFdTemplateItems> itemsList,
|
|
|
Map<String, Integer> headerIndexMap, List<CostSurveyFdTemplateHeaders> headersList,
|
|
Map<String, Integer> headerIndexMap, List<CostSurveyFdTemplateHeaders> headersList,
|
|
|
String[] auditPeriods, String templateType,
|
|
String[] auditPeriods, String templateType,
|
|
|
- int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle, String taskId) {
|
|
|
|
|
|
|
+ int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle, String taskId,
|
|
|
|
|
+ List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
|
Map<String, CostSurveyFdTemplateHeaders> headersMap = headersList.stream()
|
|
Map<String, CostSurveyFdTemplateHeaders> headersMap = headersList.stream()
|
|
|
.collect(Collectors.toMap(CostSurveyFdTemplateHeaders::getId, h -> h));
|
|
.collect(Collectors.toMap(CostSurveyFdTemplateHeaders::getId, h -> h));
|
|
|
|
|
|
|
|
|
|
+ // 构建 rowid + "_" + rkey -> rvalue 的映射,用于获取年限字段的数据
|
|
|
|
|
+ Map<String, String> uploadDataMap = new HashMap<>();
|
|
|
|
|
+ if (uploadDataList != null) {
|
|
|
|
|
+ for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
|
|
|
+ String key = data.getRowid() + "_" + data.getRkey();
|
|
|
|
|
+ uploadDataMap.put(key, data.getRvalue());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if ("1".equals(templateType)) {
|
|
if ("1".equals(templateType)) {
|
|
|
Row dataRow = sheet.createRow(2);
|
|
Row dataRow = sheet.createRow(2);
|
|
|
for (CostSurveyFdTemplateItems item : itemsList) {
|
|
for (CostSurveyFdTemplateItems item : itemsList) {
|
|
@@ -640,9 +691,15 @@ public class CostSurveyExcelAsyncService {
|
|
|
if (colIndex != null) {
|
|
if (colIndex != null) {
|
|
|
CostSurveyFdTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
CostSurveyFdTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
|
|
|
+ // 绑定监审年限的字段,从 uploadDataMap 中获取数据
|
|
|
|
|
+ String fieldName = header.getFieldName();
|
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
|
- cell.setCellValue("");
|
|
|
|
|
|
|
+ // rkey 格式:年限+字段名,如 "2025年(绑定年限)"
|
|
|
|
|
+ String rkey = auditPeriods[i].trim() + fieldName;
|
|
|
|
|
+ String key = item.getRowid() + "_" + rkey;
|
|
|
|
|
+ String value = uploadDataMap.get(key);
|
|
|
|
|
+ cell.setCellValue(StringUtil.isNotEmpty(value) ? value : "");
|
|
|
cell.setCellStyle(dataStyle);
|
|
cell.setCellStyle(dataStyle);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -678,9 +735,15 @@ public class CostSurveyExcelAsyncService {
|
|
|
if (colIndex != null) {
|
|
if (colIndex != null) {
|
|
|
CostSurveyFdTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
CostSurveyFdTemplateHeaders header = headersMap.get(item.getHeadersId());
|
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
if (header != null && "true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
|
|
|
|
|
+ // 绑定监审年限的字段,从 uploadDataMap 中获取数据
|
|
|
|
|
+ String fieldName = header.getFieldName();
|
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
for (int i = 0; i < auditPeriods.length; i++) {
|
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
Cell cell = dataRow.createCell(colIndex + i);
|
|
|
- cell.setCellValue("");
|
|
|
|
|
|
|
+ // rkey 格式:年限+字段名,如 "2025年(绑定年限)"
|
|
|
|
|
+ String rkey = auditPeriods[i].trim() + fieldName;
|
|
|
|
|
+ String key = item.getRowid() + "_" + rkey;
|
|
|
|
|
+ String value = uploadDataMap.get(key);
|
|
|
|
|
+ cell.setCellValue(StringUtil.isNotEmpty(value) ? value : "");
|
|
|
cell.setCellStyle(dataStyle);
|
|
cell.setCellStyle(dataStyle);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -763,4 +826,263 @@ public class CostSurveyExcelAsyncService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 生成核定表Excel
|
|
|
|
|
+ */
|
|
|
|
|
+ private String generateVerifyExcel(Workbook workbook, String surveyTemplateId, String taskId) {
|
|
|
|
|
+ CostVerifyTemplate template = costVerifyTemplateManager.get(surveyTemplateId);
|
|
|
|
|
+ if (template == null) return "核定表";
|
|
|
|
|
+
|
|
|
|
|
+ String templateName = template.getSurveyTemplateName();
|
|
|
|
|
+
|
|
|
|
|
+ // 获取表头列表
|
|
|
|
|
+ QueryWrapper<CostVerifyTemplateHeaders> headersWrapper = new QueryWrapper<>();
|
|
|
|
|
+ headersWrapper.eq("survey_template_id", surveyTemplateId);
|
|
|
|
|
+ List<CostVerifyTemplateHeaders> headersList = costVerifyTemplateHeadersDao.selectList(headersWrapper)
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .filter(h -> StringUtil.isEmpty(h.getShowVisible()) || "1".equals(h.getShowVisible()))
|
|
|
|
|
+ .sorted(Comparator.comparing(h -> {
|
|
|
|
|
+ String orderNum = h.getOrderNum();
|
|
|
|
|
+ if (StringUtil.isEmpty(orderNum)) {
|
|
|
|
|
+ return Integer.MAX_VALUE;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return Integer.parseInt(orderNum.trim());
|
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
|
+ return Integer.MAX_VALUE;
|
|
|
|
|
+ }
|
|
|
|
|
+ }))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ if (headersList.isEmpty()) return templateName;
|
|
|
|
|
+
|
|
|
|
|
+ // 获取模板项列表
|
|
|
|
|
+ List<CostVerifyTemplateItems> itemsList = costVerifyTemplateItemsDao.selectByVerifyTemplateId(surveyTemplateId, null);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取上传数据
|
|
|
|
|
+ QueryWrapper<CostSurveyTemplateUploadData> wrapper = new QueryWrapper<>();
|
|
|
|
|
+ wrapper.eq("task_id", taskId).eq("type", "3").eq("is_deleted", "0");
|
|
|
|
|
+ List<CostSurveyTemplateUploadData> uploadDataList = costSurveyTemplateUploadDataManager.list(wrapper);
|
|
|
|
|
+
|
|
|
|
|
+ // 合并上传数据到模板项
|
|
|
|
|
+ mergeUploadDataToVerifyItems(itemsList, uploadDataList);
|
|
|
|
|
+
|
|
|
|
|
+ Sheet sheet = workbook.createSheet(templateName);
|
|
|
|
|
+ CellStyle titleStyle = ExcelStyleUtil.createTitleStyle(workbook);
|
|
|
|
|
+ CellStyle headerStyle = ExcelStyleUtil.createHeaderStyle(workbook);
|
|
|
|
|
+ CellStyle dataStyle = ExcelStyleUtil.createDataStyle(workbook);
|
|
|
|
|
+
|
|
|
|
|
+ // 从itemsList中获取unit值,按headersId分组取第一个非空的unit
|
|
|
|
|
+ Map<String, String> headersIdToUnitMap = new HashMap<>();
|
|
|
|
|
+ if (itemsList != null) {
|
|
|
|
|
+ for (CostVerifyTemplateItems item : itemsList) {
|
|
|
|
|
+ if (StringUtil.isNotEmpty(item.getHeadersId()) && StringUtil.isNotEmpty(item.getUnit())) {
|
|
|
|
|
+ headersIdToUnitMap.putIfAbsent(item.getHeadersId(), item.getUnit());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int totalColumns = headersList.size();
|
|
|
|
|
+
|
|
|
|
|
+ // 第一行:大标题
|
|
|
|
|
+ Row titleRow = sheet.createRow(0);
|
|
|
|
|
+ Cell titleCell = titleRow.createCell(0);
|
|
|
|
|
+ titleCell.setCellValue(templateName);
|
|
|
|
|
+ titleCell.setCellStyle(titleStyle);
|
|
|
|
|
+ if (totalColumns > 1) {
|
|
|
|
|
+ sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, totalColumns - 1));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 第二行:列表头
|
|
|
|
|
+ Row headerRow = sheet.createRow(1);
|
|
|
|
|
+ int colIndex = 0;
|
|
|
|
|
+ for (CostVerifyTemplateHeaders header : headersList) {
|
|
|
|
|
+ Cell headerCell = headerRow.createCell(colIndex++);
|
|
|
|
|
+ String fieldName = header.getFieldName();
|
|
|
|
|
+ String unit = headersIdToUnitMap.get(header.getId());
|
|
|
|
|
+ String headerValue = StringUtil.isNotEmpty(unit) ? fieldName + "(" + unit + ")" : fieldName;
|
|
|
|
|
+ headerCell.setCellValue(headerValue);
|
|
|
|
|
+ headerCell.setCellStyle(headerStyle);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 填充数据
|
|
|
|
|
+ if (itemsList != null && !itemsList.isEmpty()) {
|
|
|
|
|
+ Map<String, Integer> headerIndexMap = new HashMap<>();
|
|
|
|
|
+ for (int i = 0; i < headersList.size(); i++) {
|
|
|
|
|
+ headerIndexMap.put(headersList.get(i).getId(), i);
|
|
|
|
|
+ }
|
|
|
|
|
+ fillExcelDataVerify(sheet, itemsList, headerIndexMap, dataStyle, uploadDataList);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置列宽
|
|
|
|
|
+ Row headerRowForWidth = sheet.getRow(1);
|
|
|
|
|
+ int totalColsForWidth = headerRowForWidth != null ? headerRowForWidth.getLastCellNum() : headersList.size();
|
|
|
|
|
+ for (int i = 0; i < totalColsForWidth; i++) {
|
|
|
|
|
+ Cell cell = headerRowForWidth.getCell(i);
|
|
|
|
|
+ String headerText = cell != null ? cell.getStringCellValue() : "";
|
|
|
|
|
+ int charWidth = ExcelStyleUtil.calculateCharWidth(headerText);
|
|
|
|
|
+ int columnWidth = (charWidth + 4) * 256;
|
|
|
|
|
+ sheet.setColumnWidth(i, Math.max(columnWidth, 3500));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return templateName;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 合并上传数据到核定表模板项
|
|
|
|
|
+ */
|
|
|
|
|
+ private void mergeUploadDataToVerifyItems(List<CostVerifyTemplateItems> itemsList, List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
|
|
|
+ if (itemsList == null || uploadDataList == null || uploadDataList.isEmpty()) return;
|
|
|
|
|
+
|
|
|
|
|
+ // 构建 rowid + "_" + rkey -> rvalue 的映射
|
|
|
|
|
+ Map<String, String> uploadDataMap = new HashMap<>();
|
|
|
|
|
+ for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
|
|
|
+ String key = data.getRowid() + "_" + data.getRkey();
|
|
|
|
|
+ uploadDataMap.put(key, data.getRvalue());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 用 item 的 rowid + rkey 来匹配
|
|
|
|
|
+ for (CostVerifyTemplateItems item : itemsList) {
|
|
|
|
|
+ String key = item.getRowid() + "_" + item.getRkey();
|
|
|
|
|
+ if (uploadDataMap.containsKey(key)) {
|
|
|
|
|
+ item.setRvalue(uploadDataMap.get(key));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 填充核定表Excel数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private void fillExcelDataVerify(Sheet sheet, List<CostVerifyTemplateItems> itemsList,
|
|
|
|
|
+ Map<String, Integer> headerIndexMap, CellStyle dataStyle,
|
|
|
|
|
+ List<CostSurveyTemplateUploadData> uploadDataList) {
|
|
|
|
|
+ if (itemsList == null || itemsList.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建 rowid + "_" + rkey -> rvalue 的映射
|
|
|
|
|
+ Map<String, String> uploadDataMap = new HashMap<>();
|
|
|
|
|
+ if (uploadDataList != null) {
|
|
|
|
|
+ for (CostSurveyTemplateUploadData data : uploadDataList) {
|
|
|
|
|
+ String key = data.getRowid() + "_" + data.getRkey();
|
|
|
|
|
+ uploadDataMap.put(key, data.getRvalue());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 按 rowid 分组
|
|
|
|
|
+ Map<String, List<CostVerifyTemplateItems>> itemsByRowId = itemsList.stream()
|
|
|
|
|
+ .filter(item -> StringUtil.isNotEmpty(item.getRowid()))
|
|
|
|
|
+ .collect(Collectors.groupingBy(CostVerifyTemplateItems::getRowid));
|
|
|
|
|
+
|
|
|
|
|
+ // 按父子关系排序
|
|
|
|
|
+ List<String> sortedRowIds = sortRowIdsByParentChildVerify(itemsByRowId);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取表头行,计算总列数
|
|
|
|
|
+ Row headerRow = sheet.getRow(1);
|
|
|
|
|
+ int totalColumns = headerRow != null ? headerRow.getLastCellNum() : 0;
|
|
|
|
|
+
|
|
|
|
|
+ int rowNum = 2;
|
|
|
|
|
+ for (String rowId : sortedRowIds) {
|
|
|
|
|
+ List<CostVerifyTemplateItems> rowItems = itemsByRowId.get(rowId);
|
|
|
|
|
+ if (rowItems != null && !rowItems.isEmpty()) {
|
|
|
|
|
+ Row dataRow = sheet.createRow(rowNum++);
|
|
|
|
|
+
|
|
|
|
|
+ // 填充数据列
|
|
|
|
|
+ for (CostVerifyTemplateItems item : rowItems) {
|
|
|
|
|
+ Integer colIndex = headerIndexMap.get(item.getHeadersId());
|
|
|
|
|
+ if (colIndex != null) {
|
|
|
|
|
+ Cell cell = dataRow.createCell(colIndex);
|
|
|
|
|
+ String value = item.getRvalue();
|
|
|
|
|
+ cell.setCellValue(StringUtil.isNotEmpty(value) ? value : "");
|
|
|
|
|
+ cell.setCellStyle(dataStyle);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 为所有剩余列创建空单元格并应用样式
|
|
|
|
|
+ for (int colIdx = 0; colIdx < totalColumns; colIdx++) {
|
|
|
|
|
+ if (dataRow.getCell(colIdx) == null) {
|
|
|
|
|
+ Cell cell = dataRow.createCell(colIdx);
|
|
|
|
|
+ cell.setCellValue("");
|
|
|
|
|
+ cell.setCellStyle(dataStyle);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按父子关系排序rowId(核定表)
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<String> sortRowIdsByParentChildVerify(Map<String, List<CostVerifyTemplateItems>> itemsByRowId) {
|
|
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 构建rowId到parentid的映射
|
|
|
|
|
+ Map<String, String> rowIdToParentId = new HashMap<>();
|
|
|
|
|
+ for (Map.Entry<String, List<CostVerifyTemplateItems>> entry : itemsByRowId.entrySet()) {
|
|
|
|
|
+ String rowId = entry.getKey();
|
|
|
|
|
+ List<CostVerifyTemplateItems> items = entry.getValue();
|
|
|
|
|
+ if (!items.isEmpty()) {
|
|
|
|
|
+ String parentId = items.get(0).getParentid();
|
|
|
|
|
+ rowIdToParentId.put(rowId, parentId);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 找出所有根节点(parentid为空或不存在的),按 orderNum 排序
|
|
|
|
|
+ Set<String> allRowIds = new HashSet<>(itemsByRowId.keySet());
|
|
|
|
|
+ List<String> rootRowIds = allRowIds.stream()
|
|
|
|
|
+ .filter(rowId -> {
|
|
|
|
|
+ String parentId = rowIdToParentId.get(rowId);
|
|
|
|
|
+ return StringUtil.isEmpty(parentId) || !allRowIds.contains(parentId);
|
|
|
|
|
+ })
|
|
|
|
|
+ .sorted((id1, id2) -> {
|
|
|
|
|
+ List<CostVerifyTemplateItems> items1 = itemsByRowId.get(id1);
|
|
|
|
|
+ List<CostVerifyTemplateItems> items2 = itemsByRowId.get(id2);
|
|
|
|
|
+ if (items1 == null || items1.isEmpty()) return 1;
|
|
|
|
|
+ if (items2 == null || items2.isEmpty()) return -1;
|
|
|
|
|
+ Integer order1 = items1.get(0).getOrderNum();
|
|
|
|
|
+ Integer order2 = items2.get(0).getOrderNum();
|
|
|
|
|
+ if (order1 == null) return 1;
|
|
|
|
|
+ if (order2 == null) return -1;
|
|
|
|
|
+ return order1.compareTo(order2);
|
|
|
|
|
+ })
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 递归添加节点及其子节点
|
|
|
|
|
+ for (String rootRowId : rootRowIds) {
|
|
|
|
|
+ addRowIdWithChildrenVerify(rootRowId, rowIdToParentId, allRowIds, result, itemsByRowId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 递归添加rowId及其所有子节点(核定表)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void addRowIdWithChildrenVerify(String rowId, Map<String, String> rowIdToParentId,
|
|
|
|
|
+ Set<String> allRowIds, List<String> result,
|
|
|
|
|
+ Map<String, List<CostVerifyTemplateItems>> itemsByRowId) {
|
|
|
|
|
+ result.add(rowId);
|
|
|
|
|
+
|
|
|
|
|
+ // 找出所有子节点,按 orderNum 排序
|
|
|
|
|
+ List<String> children = allRowIds.stream()
|
|
|
|
|
+ .filter(id -> rowId.equals(rowIdToParentId.get(id)))
|
|
|
|
|
+ .sorted((id1, id2) -> {
|
|
|
|
|
+ List<CostVerifyTemplateItems> items1 = itemsByRowId.get(id1);
|
|
|
|
|
+ List<CostVerifyTemplateItems> items2 = itemsByRowId.get(id2);
|
|
|
|
|
+ if (items1 == null || items1.isEmpty()) return 1;
|
|
|
|
|
+ if (items2 == null || items2.isEmpty()) return -1;
|
|
|
|
|
+ Integer order1 = items1.get(0).getOrderNum();
|
|
|
|
|
+ Integer order2 = items2.get(0).getOrderNum();
|
|
|
|
|
+ if (order1 == null) return 1;
|
|
|
|
|
+ if (order2 == null) return -1;
|
|
|
|
|
+ return order1.compareTo(order2);
|
|
|
|
|
+ })
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 递归处理子节点
|
|
|
|
|
+ for (String childRowId : children) {
|
|
|
|
|
+ addRowIdWithChildrenVerify(childRowId, rowIdToParentId, allRowIds, result, itemsByRowId);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|