表格修改

This commit is contained in:
lzm
2026-04-27 10:20:12 +08:00
parent 2d6bbc1086
commit 7a2260fbf4
2 changed files with 475 additions and 79 deletions

View File

@@ -73,6 +73,7 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
private static final BigDecimal ZERO_AMOUNT = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
private static final BigDecimal ZERO_RATIO = BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP);
private static final BigDecimal DEFAULT_K_VALUE = new BigDecimal("0.4000");
private static final BigDecimal FULL_RATIO = new BigDecimal("1.0000");
private static final String SORT_OUTPUT_DESC = "output_desc";
private static final String SORT_OUTPUT_ASC = "output_asc";
@@ -155,43 +156,21 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
throws IOException {
ProjectPlanningDO anchorPlanning = validateMajorPlanning(reqVO.getPlanningId());
ProjectDO project = validateProjectExists(anchorPlanning.getProjectId());
Integer reportYear = resolveReportYear(anchorPlanning);
List<ProjectPlanningDO> planningList = sortPlanningList(getProjectPlanningScope(anchorPlanning, true));
Integer reportYear = LocalDate.now().getYear();
List<ProjectPlanningDO> planningList = sortPlanningList(projectPlanningMapper.selectListByProjectId(project.getId()));
Map<Long, List<ProjectPlanningQuarterDO>> quarterMap = getQuarterMap(planningList);
Map<Long, ProjectOutputSplitDO> outputSplitMap = getOutputSplitMap(planningList);
Map<Long, ProjectOutputSplitDO> outputSplitMap = getExistingOutputSplitMap(planningList);
ProjectQuarterOutputExcelBuilder.ExportData data = new ProjectQuarterOutputExcelBuilder.ExportData();
data.setProjectCode("");
data.setProjectName(project.getProjectName());
data.setYear(reportYear);
List<ProjectQuarterOutputExcelBuilder.QuarterRow> rows = new ArrayList<>();
for (ProjectPlanningDO planning : planningList) {
QuarterSummary quarterSummary = buildQuarterSummary(planning, quarterMap.get(planning.getId()), reportYear);
ProjectOutputSplitDO outputSplit = outputSplitMap.get(planning.getId());
if (outputSplit == null) {
continue;
}
ProjectQuarterOutputExcelBuilder.QuarterRow row = new ProjectQuarterOutputExcelBuilder.QuarterRow();
row.setOwnershipType(planning.getOwnershipType());
row.setPlanningContent(planning.getPlanningContent());
row.setHistoricalIssuedRatio(quarterSummary.getHistoricalIssuedRatio());
row.setCurrentYearRatio(quarterSummary.getCurrentYearRatio());
row.setPendingRatio(quarterSummary.getPendingRatio());
row.setQuarterOneAmount(quarterSummary.getQuarterOneAmount());
row.setQuarterTwoAmount(quarterSummary.getQuarterTwoAmount());
row.setQuarterThreeAmount(quarterSummary.getQuarterThreeAmount());
row.setQuarterFourAmount(quarterSummary.getQuarterFourAmount());
row.setYearTotalAmount(quarterSummary.getYearTotalAmount());
row.setProjectLeadAmount(multiplyAmount(quarterSummary.getYearTotalAmount(), outputSplit.getProjectLeadRatio()));
row.setOfficeAmount(multiplyAmount(quarterSummary.getYearTotalAmount(), outputSplit.getOfficeRatio()));
row.setSpecialtySummaryText(buildSpecialtySummary(outputSplit, quarterSummary.getYearTotalAmount()));
row.setAssessmentOutputValue(amount(planning.getAssessmentOutputValue()));
rows.add(row);
}
data.setRows(rows);
data.setCenterSignerLabel("设计中心相关负责人(签名):");
data.setProjectSignerLabel("项目经理/工程负责人(签名):");
data.setRows(buildProjectQuarterOutputRows(planningList, quarterMap, outputSplitMap, reportYear));
projectQuarterOutputExcelBuilder.writeWorkbook(response,
buildFileName(project.getProjectName(), "项目级年度季度计取表"),
buildFileName(project.getProjectName(), "专业间项目考核产值年度季度计取表"),
projectQuarterOutputExcelBuilder.build(data));
}
@@ -548,6 +527,179 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
.collect(Collectors.toList());
}
private List<ProjectQuarterOutputExcelBuilder.QuarterRow> buildProjectQuarterOutputRows(
List<ProjectPlanningDO> planningList, Map<Long, List<ProjectPlanningQuarterDO>> quarterMap,
Map<Long, ProjectOutputSplitDO> outputSplitMap, Integer reportYear) {
if (planningList == null || planningList.isEmpty()) {
return Collections.emptyList();
}
List<ProjectQuarterOutputExcelBuilder.QuarterRow> rows = new ArrayList<>();
BigDecimal totalAssessmentOutputValue = ZERO_AMOUNT;
BigDecimal totalQuarterOneAmount = ZERO_AMOUNT;
BigDecimal totalQuarterTwoAmount = ZERO_AMOUNT;
BigDecimal totalQuarterThreeAmount = ZERO_AMOUNT;
BigDecimal totalQuarterFourAmount = ZERO_AMOUNT;
BigDecimal totalYearAmount = ZERO_AMOUNT;
BigDecimal totalProjectLeadAssessment = ZERO_AMOUNT;
BigDecimal totalProjectLeadQuarterOneAmount = ZERO_AMOUNT;
BigDecimal totalProjectLeadQuarterTwoAmount = ZERO_AMOUNT;
BigDecimal totalProjectLeadQuarterThreeAmount = ZERO_AMOUNT;
BigDecimal totalProjectLeadQuarterFourAmount = ZERO_AMOUNT;
BigDecimal totalProjectLeadYearAmount = ZERO_AMOUNT;
BigDecimal totalOfficeAssessment = ZERO_AMOUNT;
BigDecimal totalOfficeQuarterOneAmount = ZERO_AMOUNT;
BigDecimal totalOfficeQuarterTwoAmount = ZERO_AMOUNT;
BigDecimal totalOfficeQuarterThreeAmount = ZERO_AMOUNT;
BigDecimal totalOfficeQuarterFourAmount = ZERO_AMOUNT;
BigDecimal totalOfficeYearAmount = ZERO_AMOUNT;
BigDecimal totalArchAssessment = ZERO_AMOUNT;
BigDecimal totalDecorAssessment = ZERO_AMOUNT;
BigDecimal totalStructAssessment = ZERO_AMOUNT;
BigDecimal totalWaterAssessment = ZERO_AMOUNT;
BigDecimal totalHvacAssessment = ZERO_AMOUNT;
BigDecimal totalElecAssessment = ZERO_AMOUNT;
int serialNo = 1;
for (ProjectPlanningDO planning : planningList) {
QuarterSummary quarterSummary = buildQuarterSummary(planning, quarterMap.get(planning.getId()), reportYear);
ProjectOutputSplitDO outputSplit = resolveQuarterOutputSplit(planning, outputSplitMap);
BigDecimal assessmentOutputValue = amount(planning.getAssessmentOutputValue());
BigDecimal quarterOneAmount = amount(quarterSummary.getQuarterOneAmount());
BigDecimal quarterTwoAmount = amount(quarterSummary.getQuarterTwoAmount());
BigDecimal quarterThreeAmount = amount(quarterSummary.getQuarterThreeAmount());
BigDecimal quarterFourAmount = amount(quarterSummary.getQuarterFourAmount());
BigDecimal yearTotalAmount = amount(quarterSummary.getYearTotalAmount());
BigDecimal projectLeadRatio = ratio(outputSplit.getProjectLeadRatio());
BigDecimal officeRatio = ratio(outputSplit.getOfficeRatio());
BigDecimal projectLeadAssessment = multiplyAmount(assessmentOutputValue, projectLeadRatio);
BigDecimal projectLeadQuarterOneAmount = multiplyAmount(quarterOneAmount, projectLeadRatio);
BigDecimal projectLeadQuarterTwoAmount = multiplyAmount(quarterTwoAmount, projectLeadRatio);
BigDecimal projectLeadQuarterThreeAmount = multiplyAmount(quarterThreeAmount, projectLeadRatio);
BigDecimal projectLeadQuarterFourAmount = multiplyAmount(quarterFourAmount, projectLeadRatio);
BigDecimal projectLeadYearAmount = multiplyAmount(yearTotalAmount, projectLeadRatio);
BigDecimal officeAssessment = multiplyAmount(assessmentOutputValue, officeRatio);
BigDecimal officeQuarterOneAmount = multiplyAmount(quarterOneAmount, officeRatio);
BigDecimal officeQuarterTwoAmount = multiplyAmount(quarterTwoAmount, officeRatio);
BigDecimal officeQuarterThreeAmount = multiplyAmount(quarterThreeAmount, officeRatio);
BigDecimal officeQuarterFourAmount = multiplyAmount(quarterFourAmount, officeRatio);
BigDecimal officeYearAmount = multiplyAmount(yearTotalAmount, officeRatio);
BigDecimal archRatio = ratio(outputSplit.getArchRatio());
BigDecimal decorRatio = ratio(outputSplit.getDecorRatio());
BigDecimal structRatio = ratio(outputSplit.getStructRatio());
BigDecimal waterRatio = ratio(outputSplit.getWaterRatio());
BigDecimal hvacRatio = ratio(outputSplit.getHvacRatio());
BigDecimal elecRatio = ratio(outputSplit.getElecRatio());
BigDecimal archAssessment = multiplyAmount(officeAssessment, archRatio);
BigDecimal decorAssessment = multiplyAmount(officeAssessment, decorRatio);
BigDecimal structAssessment = multiplyAmount(officeAssessment, structRatio);
BigDecimal waterAssessment = multiplyAmount(officeAssessment, waterRatio);
BigDecimal hvacAssessment = multiplyAmount(officeAssessment, hvacRatio);
BigDecimal elecAssessment = multiplyAmount(officeAssessment, elecRatio);
ProjectQuarterOutputExcelBuilder.QuarterRow row = new ProjectQuarterOutputExcelBuilder.QuarterRow();
row.setSerialNo(serialNo++);
row.setOutputType(resolveBudgetCategoryLabel(planning.getOwnershipType()));
row.setDesignContent(defaultString(planning.getPlanningContent()));
row.setQuarterOneAmountWan(amountToWan(quarterOneAmount));
row.setQuarterTwoAmountWan(amountToWan(quarterTwoAmount));
row.setQuarterThreeAmountWan(amountToWan(quarterThreeAmount));
row.setQuarterFourAmountWan(amountToWan(quarterFourAmount));
row.setYearTotalAmountWan(amountToWan(yearTotalAmount));
row.setProjectLeadRatio(projectLeadRatio);
row.setProjectLeadAssessmentOutputWan(amountToWan(projectLeadAssessment));
row.setProjectLeadQuarterOneAmountWan(amountToWan(projectLeadQuarterOneAmount));
row.setProjectLeadQuarterTwoAmountWan(amountToWan(projectLeadQuarterTwoAmount));
row.setProjectLeadQuarterThreeAmountWan(amountToWan(projectLeadQuarterThreeAmount));
row.setProjectLeadQuarterFourAmountWan(amountToWan(projectLeadQuarterFourAmount));
row.setProjectLeadYearTotalAmountWan(amountToWan(projectLeadYearAmount));
row.setOfficeRatio(officeRatio);
row.setOfficeAssessmentOutputWan(amountToWan(officeAssessment));
row.setOfficeQuarterOneAmountWan(amountToWan(officeQuarterOneAmount));
row.setOfficeQuarterTwoAmountWan(amountToWan(officeQuarterTwoAmount));
row.setOfficeQuarterThreeAmountWan(amountToWan(officeQuarterThreeAmount));
row.setOfficeQuarterFourAmountWan(amountToWan(officeQuarterFourAmount));
row.setOfficeYearTotalAmountWan(amountToWan(officeYearAmount));
row.setArchRatio(archRatio);
row.setDecorRatio(decorRatio);
row.setStructRatio(structRatio);
row.setWaterRatio(waterRatio);
row.setHvacRatio(hvacRatio);
row.setElecRatio(elecRatio);
row.setArchAssessmentOutputWan(amountToWan(archAssessment));
row.setDecorAssessmentOutputWan(amountToWan(decorAssessment));
row.setStructAssessmentOutputWan(amountToWan(structAssessment));
row.setWaterAssessmentOutputWan(amountToWan(waterAssessment));
row.setHvacAssessmentOutputWan(amountToWan(hvacAssessment));
row.setElecAssessmentOutputWan(amountToWan(elecAssessment));
rows.add(row);
totalAssessmentOutputValue = totalAssessmentOutputValue.add(assessmentOutputValue).setScale(2, RoundingMode.HALF_UP);
totalQuarterOneAmount = totalQuarterOneAmount.add(quarterOneAmount).setScale(2, RoundingMode.HALF_UP);
totalQuarterTwoAmount = totalQuarterTwoAmount.add(quarterTwoAmount).setScale(2, RoundingMode.HALF_UP);
totalQuarterThreeAmount = totalQuarterThreeAmount.add(quarterThreeAmount).setScale(2, RoundingMode.HALF_UP);
totalQuarterFourAmount = totalQuarterFourAmount.add(quarterFourAmount).setScale(2, RoundingMode.HALF_UP);
totalYearAmount = totalYearAmount.add(yearTotalAmount).setScale(2, RoundingMode.HALF_UP);
totalProjectLeadAssessment = totalProjectLeadAssessment.add(projectLeadAssessment).setScale(2, RoundingMode.HALF_UP);
totalProjectLeadQuarterOneAmount = totalProjectLeadQuarterOneAmount.add(projectLeadQuarterOneAmount)
.setScale(2, RoundingMode.HALF_UP);
totalProjectLeadQuarterTwoAmount = totalProjectLeadQuarterTwoAmount.add(projectLeadQuarterTwoAmount)
.setScale(2, RoundingMode.HALF_UP);
totalProjectLeadQuarterThreeAmount = totalProjectLeadQuarterThreeAmount.add(projectLeadQuarterThreeAmount)
.setScale(2, RoundingMode.HALF_UP);
totalProjectLeadQuarterFourAmount = totalProjectLeadQuarterFourAmount.add(projectLeadQuarterFourAmount)
.setScale(2, RoundingMode.HALF_UP);
totalProjectLeadYearAmount = totalProjectLeadYearAmount.add(projectLeadYearAmount).setScale(2, RoundingMode.HALF_UP);
totalOfficeAssessment = totalOfficeAssessment.add(officeAssessment).setScale(2, RoundingMode.HALF_UP);
totalOfficeQuarterOneAmount = totalOfficeQuarterOneAmount.add(officeQuarterOneAmount).setScale(2, RoundingMode.HALF_UP);
totalOfficeQuarterTwoAmount = totalOfficeQuarterTwoAmount.add(officeQuarterTwoAmount).setScale(2, RoundingMode.HALF_UP);
totalOfficeQuarterThreeAmount = totalOfficeQuarterThreeAmount.add(officeQuarterThreeAmount)
.setScale(2, RoundingMode.HALF_UP);
totalOfficeQuarterFourAmount = totalOfficeQuarterFourAmount.add(officeQuarterFourAmount)
.setScale(2, RoundingMode.HALF_UP);
totalOfficeYearAmount = totalOfficeYearAmount.add(officeYearAmount).setScale(2, RoundingMode.HALF_UP);
totalArchAssessment = totalArchAssessment.add(archAssessment).setScale(2, RoundingMode.HALF_UP);
totalDecorAssessment = totalDecorAssessment.add(decorAssessment).setScale(2, RoundingMode.HALF_UP);
totalStructAssessment = totalStructAssessment.add(structAssessment).setScale(2, RoundingMode.HALF_UP);
totalWaterAssessment = totalWaterAssessment.add(waterAssessment).setScale(2, RoundingMode.HALF_UP);
totalHvacAssessment = totalHvacAssessment.add(hvacAssessment).setScale(2, RoundingMode.HALF_UP);
totalElecAssessment = totalElecAssessment.add(elecAssessment).setScale(2, RoundingMode.HALF_UP);
}
ProjectQuarterOutputExcelBuilder.QuarterRow totalRow = new ProjectQuarterOutputExcelBuilder.QuarterRow();
totalRow.setTotalRow(true);
totalRow.setQuarterOneAmountWan(amountToWan(totalQuarterOneAmount));
totalRow.setQuarterTwoAmountWan(amountToWan(totalQuarterTwoAmount));
totalRow.setQuarterThreeAmountWan(amountToWan(totalQuarterThreeAmount));
totalRow.setQuarterFourAmountWan(amountToWan(totalQuarterFourAmount));
totalRow.setYearTotalAmountWan(amountToWan(totalYearAmount));
totalRow.setProjectLeadRatio(divideAmountRatio(totalProjectLeadAssessment, totalAssessmentOutputValue));
totalRow.setProjectLeadAssessmentOutputWan(amountToWan(totalProjectLeadAssessment));
totalRow.setProjectLeadQuarterOneAmountWan(amountToWan(totalProjectLeadQuarterOneAmount));
totalRow.setProjectLeadQuarterTwoAmountWan(amountToWan(totalProjectLeadQuarterTwoAmount));
totalRow.setProjectLeadQuarterThreeAmountWan(amountToWan(totalProjectLeadQuarterThreeAmount));
totalRow.setProjectLeadQuarterFourAmountWan(amountToWan(totalProjectLeadQuarterFourAmount));
totalRow.setProjectLeadYearTotalAmountWan(amountToWan(totalProjectLeadYearAmount));
totalRow.setOfficeRatio(divideAmountRatio(totalOfficeAssessment, totalAssessmentOutputValue));
totalRow.setOfficeAssessmentOutputWan(amountToWan(totalOfficeAssessment));
totalRow.setOfficeQuarterOneAmountWan(amountToWan(totalOfficeQuarterOneAmount));
totalRow.setOfficeQuarterTwoAmountWan(amountToWan(totalOfficeQuarterTwoAmount));
totalRow.setOfficeQuarterThreeAmountWan(amountToWan(totalOfficeQuarterThreeAmount));
totalRow.setOfficeQuarterFourAmountWan(amountToWan(totalOfficeQuarterFourAmount));
totalRow.setOfficeYearTotalAmountWan(amountToWan(totalOfficeYearAmount));
totalRow.setArchAssessmentOutputWan(amountToWan(totalArchAssessment));
totalRow.setDecorAssessmentOutputWan(amountToWan(totalDecorAssessment));
totalRow.setStructAssessmentOutputWan(amountToWan(totalStructAssessment));
totalRow.setWaterAssessmentOutputWan(amountToWan(totalWaterAssessment));
totalRow.setHvacAssessmentOutputWan(amountToWan(totalHvacAssessment));
totalRow.setElecAssessmentOutputWan(amountToWan(totalElecAssessment));
rows.add(totalRow);
return rows;
}
private List<ProjectBudgetExcelBuilder.BudgetRow> buildProjectBudgetRows(List<ProjectPlanningDO> planningList) {
if (planningList == null || planningList.isEmpty()) {
return Collections.emptyList();
@@ -795,6 +947,38 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
.collect(Collectors.toList());
}
private ProjectOutputSplitDO resolveQuarterOutputSplit(ProjectPlanningDO planning,
Map<Long, ProjectOutputSplitDO> outputSplitMap) {
if (planning == null) {
return buildQuarterOutputDefaultSplit(null);
}
ProjectOutputSplitDO outputSplit = outputSplitMap == null ? null : outputSplitMap.get(planning.getId());
if (outputSplit != null) {
return outputSplit;
}
return buildQuarterOutputDefaultSplit(planning);
}
private ProjectOutputSplitDO buildQuarterOutputDefaultSplit(ProjectPlanningDO planning) {
ProjectOutputSplitDO outputSplit = new ProjectOutputSplitDO();
if (planning != null) {
outputSplit.setProjectId(planning.getProjectId());
outputSplit.setPlanningId(planning.getId());
outputSplit.setYear(resolveReportYear(planning));
}
outputSplit.setProjectLeadRatio(ZERO_RATIO);
boolean majorPlanning = planning != null && ProjectPlanningBizTypeConstants.isMajor(planning.getOwnershipType());
outputSplit.setOfficeRatio(majorPlanning ? FULL_RATIO : ZERO_RATIO);
outputSplit.setArchRatio(majorPlanning ? FULL_RATIO : ZERO_RATIO);
outputSplit.setDecorRatio(ZERO_RATIO);
outputSplit.setStructRatio(ZERO_RATIO);
outputSplit.setWaterRatio(ZERO_RATIO);
outputSplit.setElecRatio(ZERO_RATIO);
outputSplit.setHvacRatio(ZERO_RATIO);
outputSplit.setDigitalRatio(ZERO_RATIO);
return outputSplit;
}
private int designPartOrder(String designPart) {
if (Objects.equals(designPart, ProjectPlanningBizTypeConstants.DESIGN_PART_REAL_ESTATE)) {
return 1;
@@ -847,6 +1031,14 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
return map;
}
private Map<Long, ProjectOutputSplitDO> getExistingOutputSplitMap(Collection<ProjectPlanningDO> planningList) {
if (planningList == null || planningList.isEmpty()) {
return Collections.emptyMap();
}
List<Long> planningIds = planningList.stream().map(ProjectPlanningDO::getId).collect(Collectors.toList());
return projectOutputSplitService.getProjectOutputSplitMap(planningIds);
}
private Map<Long, List<SpecialtyRoleSplitRespVO>> getRoleSplitMap(Collection<ProjectPlanningDO> planningList) {
if (planningList == null || planningList.isEmpty()) {
return Collections.emptyMap();
@@ -1199,6 +1391,14 @@ public class ProjectOutputReportServiceImpl implements ProjectOutputReportServic
return ratio(left).add(ratio(right)).setScale(4, RoundingMode.HALF_UP);
}
private BigDecimal divideAmountRatio(BigDecimal numerator, BigDecimal denominator) {
BigDecimal denominatorAmount = amount(denominator);
if (denominatorAmount.compareTo(BigDecimal.ZERO) == 0) {
return ZERO_RATIO;
}
return amount(numerator).divide(denominatorAmount, 4, RoundingMode.HALF_UP);
}
private String percentText(BigDecimal value) {
return ratio(value).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%";
}

View File

@@ -2,86 +2,282 @@ package cn.iocoder.lyzsys.module.tjt.service.report.builder;
import lombok.Data;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
@Component
public class ProjectQuarterOutputExcelBuilder extends AbstractProjectOutputExcelBuilder {
private static final String SHEET_NAME = "专业间项目考核产值年度季度计取表";
private static final String SHEET_FALLBACK_NAME = "项目级年度季度计取";
private static final String SHEET_TITLE = "专业间项目考核产值年度/季度计取表";
private static final String TOTAL_LABEL = "合计";
private static final String SUMMARY_PLACEHOLDER = "/";
public Workbook build(ExportData data) {
Workbook workbook = createWorkbook();
Sheet sheet = createSheet(workbook, "年度季度计取", "年度季度计取");
setColumnWidths(sheet, 8, 24, 12, 22, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12);
Sheet sheet = createSheet(workbook, SHEET_NAME, SHEET_FALLBACK_NAME);
setColumnWidths(sheet,
10, 24, 16, 20, 12, 12, 12, 12, 14,
10, 14, 12, 12, 12, 12, 14,
10, 14, 12, 12, 12, 12, 14,
10, 10, 10, 10, 10, 10,
12, 12, 12, 12, 12, 12);
CellStyle titleStyle = createTitleStyle(workbook);
CellStyle infoStyle = createInfoStyle(workbook);
CellStyle headerStyle = createHeaderStyle(workbook);
CellStyle cellStyle = createCellStyle(workbook);
CellStyle baseHeaderStyle = createHeaderStyle(workbook);
CellStyle headerStyle = createDerivedStyle(workbook, baseHeaderStyle,
IndexedColors.LEMON_CHIFFON, HorizontalAlignment.CENTER, true, (short) 10);
CellStyle cellStyle = createDerivedStyle(workbook, createCellStyle(workbook),
null, HorizontalAlignment.CENTER, false, (short) 10);
CellStyle leftCellStyle = createDerivedStyle(workbook, cellStyle,
null, HorizontalAlignment.LEFT, false, (short) 10);
CellStyle totalStyle = createDerivedStyle(workbook, baseHeaderStyle,
IndexedColors.GOLD, HorizontalAlignment.CENTER, true, (short) 10);
CellStyle totalLeftStyle = createDerivedStyle(workbook, totalStyle,
IndexedColors.GOLD, HorizontalAlignment.LEFT, true, (short) 10);
CellStyle signatureStyle = createDerivedStyle(workbook, createInfoStyle(workbook),
null, HorizontalAlignment.LEFT, false, (short) 10);
int rowIndex = 0;
rowIndex = writeMergedTitleRow(sheet, rowIndex, "项目考核产值年度/季度计取表", titleStyle, 15);
rowIndex = writeMergedTitleRow(sheet, rowIndex, SHEET_TITLE, titleStyle, 34);
rowIndex = buildHeader(sheet, rowIndex, data, headerStyle, cellStyle);
Row infoRow = sheet.createRow(rowIndex++);
writeLabelValue(infoRow, 0, 1, "项目名称", data.getProjectName(), infoStyle);
writeLabelValue(infoRow, 4, 5, "年度", data.getYear(), infoStyle);
rowIndex = writeRow(sheet, rowIndex, headerStyle, (Object[]) new String[]{
"序号", "项目名称", "归属类型", "规划内容", "往年已发放比例", "本年度发放比例",
"未发放比例", "一季度", "二季度", "三季度", "四季度", "本年度小计",
"项目经理/项目负责人", "专业所合计", "专业分配说明", "考核产值"
});
int serialNo = 1;
for (QuarterRow rowData : data.getRows()) {
Row row = sheet.createRow(rowIndex++);
setText(row, 0, serialNo++, cellStyle);
setText(row, 1, data.getProjectName(), cellStyle);
setText(row, 2, rowData.getOwnershipType(), cellStyle);
setText(row, 3, rowData.getPlanningContent(), cellStyle);
setText(row, 4, percentText(rowData.getHistoricalIssuedRatio()), cellStyle);
setText(row, 5, percentText(rowData.getCurrentYearRatio()), cellStyle);
setText(row, 6, percentText(rowData.getPendingRatio()), cellStyle);
setText(row, 7, text(rowData.getQuarterOneAmount()), cellStyle);
setText(row, 8, text(rowData.getQuarterTwoAmount()), cellStyle);
setText(row, 9, text(rowData.getQuarterThreeAmount()), cellStyle);
setText(row, 10, text(rowData.getQuarterFourAmount()), cellStyle);
setText(row, 11, text(rowData.getYearTotalAmount()), cellStyle);
setText(row, 12, text(rowData.getProjectLeadAmount()), cellStyle);
setText(row, 13, text(rowData.getOfficeAmount()), cellStyle);
setText(row, 14, rowData.getSpecialtySummaryText(), cellStyle);
setText(row, 15, text(rowData.getAssessmentOutputValue()), cellStyle);
if (data.getRows() != null) {
for (QuarterRow rowData : data.getRows()) {
if (rowData == null) {
continue;
}
if (rowData.isTotalRow()) {
writeTotalRow(sheet, rowIndex++, data, rowData, totalStyle, totalLeftStyle);
continue;
}
writeDetailRow(sheet, rowIndex++, data, rowData, cellStyle, leftCellStyle);
}
}
writeSignatureRow(sheet, rowIndex, data, signatureStyle);
return workbook;
}
private int buildHeader(Sheet sheet, int rowIndex, ExportData data,
CellStyle headerStyle, CellStyle valueStyle) {
int firstRow = rowIndex;
sheet.createRow(firstRow);
sheet.createRow(firstRow + 1);
sheet.createRow(firstRow + 2);
setMergedRegionText(sheet, firstRow, firstRow + 1, 0, 0, "工程编号", headerStyle);
setMergedRegionText(sheet, firstRow, firstRow + 1, 1, 1, safeText(data.getProjectCode()), valueStyle);
setText(sheet.getRow(firstRow + 2), 0, "序号", headerStyle);
setText(sheet.getRow(firstRow + 2), 1, "项目名称", headerStyle);
setMergedRegionText(sheet, firstRow, firstRow + 1, 2, 3, "类别", headerStyle);
setText(sheet.getRow(firstRow + 2), 2, "产值类型", headerStyle);
setText(sheet.getRow(firstRow + 2), 3, "设计内容", headerStyle);
setMergedRegionText(sheet, firstRow, firstRow + 1, 4, 8, "本年度项目考核产值(万元)", headerStyle);
setText(sheet.getRow(firstRow + 2), 4, "一季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 5, "二季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 6, "三季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 7, "四季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 8, "本年度小计", headerStyle);
setMergedRegionText(sheet, firstRow, firstRow, 9, 15, "项目经理 / 工程负责人年度 / 季度项目考核产值", headerStyle);
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 9, 10, "项总 / 工程负责人", headerStyle);
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 11, 15, "考核产值(万元)", headerStyle);
setText(sheet.getRow(firstRow + 2), 9, "占比", headerStyle);
setText(sheet.getRow(firstRow + 2), 10, "总考核产值", headerStyle);
setText(sheet.getRow(firstRow + 2), 11, "一季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 12, "二季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 13, "三季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 14, "四季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 15, "本年度总计", headerStyle);
setMergedRegionText(sheet, firstRow, firstRow, 16, 22, "六大专业年度 / 季度项目考核产值合计", headerStyle);
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 16, 17, "六大专业", headerStyle);
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 18, 22, "考核产值(万元)", headerStyle);
setText(sheet.getRow(firstRow + 2), 16, "占比", headerStyle);
setText(sheet.getRow(firstRow + 2), 17, "总考核产值", headerStyle);
setText(sheet.getRow(firstRow + 2), 18, "一季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 19, "二季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 20, "三季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 21, "四季度", headerStyle);
setText(sheet.getRow(firstRow + 2), 22, "本年度总计", headerStyle);
setMergedRegionText(sheet, firstRow, firstRow, 23, 34, "各专业年度 / 季度项目考核产值", headerStyle);
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 23, 28, "各专业考核产值占比", headerStyle);
setMergedRegionText(sheet, firstRow + 1, firstRow + 1, 29, 34, "各专业考核产值", headerStyle);
setText(sheet.getRow(firstRow + 2), 23, "建筑", headerStyle);
setText(sheet.getRow(firstRow + 2), 24, "精装", headerStyle);
setText(sheet.getRow(firstRow + 2), 25, "结构", headerStyle);
setText(sheet.getRow(firstRow + 2), 26, "给排水", headerStyle);
setText(sheet.getRow(firstRow + 2), 27, "暖通", headerStyle);
setText(sheet.getRow(firstRow + 2), 28, "电气", headerStyle);
setText(sheet.getRow(firstRow + 2), 29, "建筑", headerStyle);
setText(sheet.getRow(firstRow + 2), 30, "精装", headerStyle);
setText(sheet.getRow(firstRow + 2), 31, "结构", headerStyle);
setText(sheet.getRow(firstRow + 2), 32, "给排水", headerStyle);
setText(sheet.getRow(firstRow + 2), 33, "暖通", headerStyle);
setText(sheet.getRow(firstRow + 2), 34, "电气", headerStyle);
return rowIndex + 3;
}
private void writeDetailRow(Sheet sheet, int rowIndex, ExportData data, QuarterRow rowData,
CellStyle cellStyle, CellStyle leftCellStyle) {
Row row = sheet.createRow(rowIndex);
setText(row, 0, rowData.getSerialNo(), cellStyle);
setText(row, 1, safeText(data.getProjectName()), cellStyle);
setText(row, 2, safeText(rowData.getOutputType()), cellStyle);
setText(row, 3, safeText(rowData.getDesignContent()), leftCellStyle);
setText(row, 4, textOrBlank(rowData.getQuarterOneAmountWan()), cellStyle);
setText(row, 5, textOrBlank(rowData.getQuarterTwoAmountWan()), cellStyle);
setText(row, 6, textOrBlank(rowData.getQuarterThreeAmountWan()), cellStyle);
setText(row, 7, textOrBlank(rowData.getQuarterFourAmountWan()), cellStyle);
setText(row, 8, textOrBlank(rowData.getYearTotalAmountWan()), cellStyle);
setText(row, 9, percentTextOrBlank(rowData.getProjectLeadRatio()), cellStyle);
setText(row, 10, textOrBlank(rowData.getProjectLeadAssessmentOutputWan()), cellStyle);
setText(row, 11, textOrBlank(rowData.getProjectLeadQuarterOneAmountWan()), cellStyle);
setText(row, 12, textOrBlank(rowData.getProjectLeadQuarterTwoAmountWan()), cellStyle);
setText(row, 13, textOrBlank(rowData.getProjectLeadQuarterThreeAmountWan()), cellStyle);
setText(row, 14, textOrBlank(rowData.getProjectLeadQuarterFourAmountWan()), cellStyle);
setText(row, 15, textOrBlank(rowData.getProjectLeadYearTotalAmountWan()), cellStyle);
setText(row, 16, percentTextOrBlank(rowData.getOfficeRatio()), cellStyle);
setText(row, 17, textOrBlank(rowData.getOfficeAssessmentOutputWan()), cellStyle);
setText(row, 18, textOrBlank(rowData.getOfficeQuarterOneAmountWan()), cellStyle);
setText(row, 19, textOrBlank(rowData.getOfficeQuarterTwoAmountWan()), cellStyle);
setText(row, 20, textOrBlank(rowData.getOfficeQuarterThreeAmountWan()), cellStyle);
setText(row, 21, textOrBlank(rowData.getOfficeQuarterFourAmountWan()), cellStyle);
setText(row, 22, textOrBlank(rowData.getOfficeYearTotalAmountWan()), cellStyle);
setText(row, 23, percentTextOrBlank(rowData.getArchRatio()), cellStyle);
setText(row, 24, percentTextOrBlank(rowData.getDecorRatio()), cellStyle);
setText(row, 25, percentTextOrBlank(rowData.getStructRatio()), cellStyle);
setText(row, 26, percentTextOrBlank(rowData.getWaterRatio()), cellStyle);
setText(row, 27, percentTextOrBlank(rowData.getHvacRatio()), cellStyle);
setText(row, 28, percentTextOrBlank(rowData.getElecRatio()), cellStyle);
setText(row, 29, textOrBlank(rowData.getArchAssessmentOutputWan()), cellStyle);
setText(row, 30, textOrBlank(rowData.getDecorAssessmentOutputWan()), cellStyle);
setText(row, 31, textOrBlank(rowData.getStructAssessmentOutputWan()), cellStyle);
setText(row, 32, textOrBlank(rowData.getWaterAssessmentOutputWan()), cellStyle);
setText(row, 33, textOrBlank(rowData.getHvacAssessmentOutputWan()), cellStyle);
setText(row, 34, textOrBlank(rowData.getElecAssessmentOutputWan()), cellStyle);
}
private void writeTotalRow(Sheet sheet, int rowIndex, ExportData data, QuarterRow rowData,
CellStyle totalStyle, CellStyle totalLeftStyle) {
Row row = sheet.createRow(rowIndex);
setText(row, 0, "", totalStyle);
setText(row, 1, safeText(data.getProjectName()), totalStyle);
setMergedRegionText(sheet, rowIndex, rowIndex, 2, 3, TOTAL_LABEL, totalStyle);
setText(row, 4, textOrBlank(rowData.getQuarterOneAmountWan()), totalStyle);
setText(row, 5, textOrBlank(rowData.getQuarterTwoAmountWan()), totalStyle);
setText(row, 6, textOrBlank(rowData.getQuarterThreeAmountWan()), totalStyle);
setText(row, 7, textOrBlank(rowData.getQuarterFourAmountWan()), totalStyle);
setText(row, 8, textOrBlank(rowData.getYearTotalAmountWan()), totalStyle);
setText(row, 9, percentTextOrBlank(rowData.getProjectLeadRatio()), totalStyle);
setText(row, 10, textOrBlank(rowData.getProjectLeadAssessmentOutputWan()), totalStyle);
setText(row, 11, textOrBlank(rowData.getProjectLeadQuarterOneAmountWan()), totalStyle);
setText(row, 12, textOrBlank(rowData.getProjectLeadQuarterTwoAmountWan()), totalStyle);
setText(row, 13, textOrBlank(rowData.getProjectLeadQuarterThreeAmountWan()), totalStyle);
setText(row, 14, textOrBlank(rowData.getProjectLeadQuarterFourAmountWan()), totalStyle);
setText(row, 15, textOrBlank(rowData.getProjectLeadYearTotalAmountWan()), totalStyle);
setText(row, 16, percentTextOrBlank(rowData.getOfficeRatio()), totalStyle);
setText(row, 17, textOrBlank(rowData.getOfficeAssessmentOutputWan()), totalStyle);
setText(row, 18, textOrBlank(rowData.getOfficeQuarterOneAmountWan()), totalStyle);
setText(row, 19, textOrBlank(rowData.getOfficeQuarterTwoAmountWan()), totalStyle);
setText(row, 20, textOrBlank(rowData.getOfficeQuarterThreeAmountWan()), totalStyle);
setText(row, 21, textOrBlank(rowData.getOfficeQuarterFourAmountWan()), totalStyle);
setText(row, 22, textOrBlank(rowData.getOfficeYearTotalAmountWan()), totalStyle);
setMergedRegionText(sheet, rowIndex, rowIndex, 23, 28, SUMMARY_PLACEHOLDER, totalLeftStyle);
setText(row, 29, textOrBlank(rowData.getArchAssessmentOutputWan()), totalStyle);
setText(row, 30, textOrBlank(rowData.getDecorAssessmentOutputWan()), totalStyle);
setText(row, 31, textOrBlank(rowData.getStructAssessmentOutputWan()), totalStyle);
setText(row, 32, textOrBlank(rowData.getWaterAssessmentOutputWan()), totalStyle);
setText(row, 33, textOrBlank(rowData.getHvacAssessmentOutputWan()), totalStyle);
setText(row, 34, textOrBlank(rowData.getElecAssessmentOutputWan()), totalStyle);
}
private void writeSignatureRow(Sheet sheet, int rowIndex, ExportData data, CellStyle signatureStyle) {
Row row = sheet.createRow(rowIndex);
setMergedRegionText(sheet, rowIndex, rowIndex, 0, 16,
safeText(defaultSignatureLabel(data.getCenterSignerLabel(), "设计中心相关负责人(签名):")),
signatureStyle);
setMergedRegionText(sheet, rowIndex, rowIndex, 17, 34,
safeText(defaultSignatureLabel(data.getProjectSignerLabel(), "项目经理/工程负责人(签名):")),
signatureStyle);
}
private String defaultSignatureLabel(String value, String fallback) {
String text = safeText(value);
return text.isEmpty() ? fallback : text;
}
private String textOrBlank(BigDecimal value) {
if (value == null) {
return "";
}
return value.setScale(2, RoundingMode.HALF_UP).toPlainString();
}
private String percentTextOrBlank(BigDecimal value) {
return value == null ? "" : percentText(value);
}
@Data
public static class ExportData {
private String projectCode;
private String projectName;
private Integer year;
private String centerSignerLabel;
private String projectSignerLabel;
private List<QuarterRow> rows;
}
@Data
public static class QuarterRow {
private String ownershipType;
private String planningContent;
private BigDecimal historicalIssuedRatio;
private BigDecimal currentYearRatio;
private BigDecimal pendingRatio;
private BigDecimal quarterOneAmount;
private BigDecimal quarterTwoAmount;
private BigDecimal quarterThreeAmount;
private BigDecimal quarterFourAmount;
private BigDecimal yearTotalAmount;
private BigDecimal projectLeadAmount;
private BigDecimal officeAmount;
private String specialtySummaryText;
private BigDecimal assessmentOutputValue;
private Integer serialNo;
private boolean totalRow;
private String outputType;
private String designContent;
private BigDecimal quarterOneAmountWan;
private BigDecimal quarterTwoAmountWan;
private BigDecimal quarterThreeAmountWan;
private BigDecimal quarterFourAmountWan;
private BigDecimal yearTotalAmountWan;
private BigDecimal projectLeadRatio;
private BigDecimal projectLeadAssessmentOutputWan;
private BigDecimal projectLeadQuarterOneAmountWan;
private BigDecimal projectLeadQuarterTwoAmountWan;
private BigDecimal projectLeadQuarterThreeAmountWan;
private BigDecimal projectLeadQuarterFourAmountWan;
private BigDecimal projectLeadYearTotalAmountWan;
private BigDecimal officeRatio;
private BigDecimal officeAssessmentOutputWan;
private BigDecimal officeQuarterOneAmountWan;
private BigDecimal officeQuarterTwoAmountWan;
private BigDecimal officeQuarterThreeAmountWan;
private BigDecimal officeQuarterFourAmountWan;
private BigDecimal officeYearTotalAmountWan;
private BigDecimal archRatio;
private BigDecimal decorRatio;
private BigDecimal structRatio;
private BigDecimal waterRatio;
private BigDecimal hvacRatio;
private BigDecimal elecRatio;
private BigDecimal archAssessmentOutputWan;
private BigDecimal decorAssessmentOutputWan;
private BigDecimal structAssessmentOutputWan;
private BigDecimal waterAssessmentOutputWan;
private BigDecimal hvacAssessmentOutputWan;
private BigDecimal elecAssessmentOutputWan;
}
}