|
@@ -8,10 +8,12 @@ import com.usky.common.core.exception.BusinessException;
|
|
|
import com.usky.common.security.utils.SecurityUtils;
|
|
import com.usky.common.security.utils.SecurityUtils;
|
|
|
import com.usky.vpp.domain.VppCustomer;
|
|
import com.usky.vpp.domain.VppCustomer;
|
|
|
import com.usky.vpp.domain.VppEnergyReadingMonthly;
|
|
import com.usky.vpp.domain.VppEnergyReadingMonthly;
|
|
|
-import com.usky.vpp.domain.VppResourcePoint;
|
|
|
|
|
|
|
+import com.usky.vpp.domain.VppSettlementBill;
|
|
|
|
|
+import com.usky.vpp.domain.VppSite;
|
|
|
import com.usky.vpp.mapper.VppCustomerMapper;
|
|
import com.usky.vpp.mapper.VppCustomerMapper;
|
|
|
import com.usky.vpp.mapper.VppEnergyReadingMonthlyMapper;
|
|
import com.usky.vpp.mapper.VppEnergyReadingMonthlyMapper;
|
|
|
-import com.usky.vpp.mapper.VppResourcePointMapper;
|
|
|
|
|
|
|
+import com.usky.vpp.mapper.VppSettlementBillMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppSiteMapper;
|
|
|
import com.usky.vpp.service.VppSettlementService;
|
|
import com.usky.vpp.service.VppSettlementService;
|
|
|
import com.usky.vpp.util.VppAuditHelper;
|
|
import com.usky.vpp.util.VppAuditHelper;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
@@ -20,6 +22,8 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
@@ -40,7 +44,9 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private VppEnergyReadingMonthlyMapper energyReadingMonthlyMapper;
|
|
private VppEnergyReadingMonthlyMapper energyReadingMonthlyMapper;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
- private VppResourcePointMapper resourcePointMapper;
|
|
|
|
|
|
|
+ private VppSiteMapper siteMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppSettlementBillMapper settlementBillMapper;
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public CommonPage<VppEnergyReadingMonthly> pageReading(Long id, String customerName, String calcCycle,
|
|
public CommonPage<VppEnergyReadingMonthly> pageReading(Long id, String customerName, String calcCycle,
|
|
@@ -53,7 +59,7 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
page = energyReadingMonthlyMapper.selectPage(page, wrapper);
|
|
page = energyReadingMonthlyMapper.selectPage(page, wrapper);
|
|
|
List<VppEnergyReadingMonthly> records = page.getRecords();
|
|
List<VppEnergyReadingMonthly> records = page.getRecords();
|
|
|
fillCustomerNames(records);
|
|
fillCustomerNames(records);
|
|
|
- fillResourceNames(records);
|
|
|
|
|
|
|
+ fillSiteNames(records);
|
|
|
return new CommonPage<>(records, page.getTotal(), size, current);
|
|
return new CommonPage<>(records, page.getTotal(), size, current);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -105,10 +111,76 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
readingList = Collections.emptyList();
|
|
readingList = Collections.emptyList();
|
|
|
}
|
|
}
|
|
|
fillCustomerNames(readingList);
|
|
fillCustomerNames(readingList);
|
|
|
- fillResourceNames(readingList);
|
|
|
|
|
|
|
+ fillSiteNames(readingList);
|
|
|
writeReadingExcel(fileName, readingList, response);
|
|
writeReadingExcel(fileName, readingList, response);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CommonPage<VppSettlementBill> pageBill(Long id, String customerName, Integer current, Integer size) {
|
|
|
|
|
+ IPage<VppSettlementBill> page = new Page<>(current, size);
|
|
|
|
|
+ LambdaQueryWrapper<VppSettlementBill> wrapper = buildBillQueryWrapper(id, customerName);
|
|
|
|
|
+ if (wrapper == null) {
|
|
|
|
|
+ return new CommonPage<>(Collections.emptyList(), 0L, size, current);
|
|
|
|
|
+ }
|
|
|
|
|
+ page = settlementBillMapper.selectPage(page, wrapper);
|
|
|
|
|
+ List<VppSettlementBill> records = page.getRecords();
|
|
|
|
|
+ fillBillCustomerNames(records);
|
|
|
|
|
+ fillBillSiteNames(records);
|
|
|
|
|
+ fillBillContractPrice(records);
|
|
|
|
|
+ return new CommonPage<>(records, page.getTotal(), size, current);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void exportBill(String scope, String fileName, Long id, String customerName,
|
|
|
|
|
+ Integer current, Integer size, HttpServletResponse response) {
|
|
|
|
|
+ List<VppSettlementBill> billList;
|
|
|
|
|
+
|
|
|
|
|
+ switch (scope) {
|
|
|
|
|
+ case "current":
|
|
|
|
|
+ if (current == null || size == null) {
|
|
|
|
|
+ throw new BusinessException("current 模式下分页参数 current 和 size 不能为空!");
|
|
|
|
|
+ }
|
|
|
|
|
+ IPage<VppSettlementBill> page = new Page<>(current, size);
|
|
|
|
|
+ LambdaQueryWrapper<VppSettlementBill> currWrapper = baseBillQueryWrapper();
|
|
|
|
|
+ currWrapper.orderByDesc(VppSettlementBill::getSettleYear)
|
|
|
|
|
+ .orderByDesc(VppSettlementBill::getSettleMonth);
|
|
|
|
|
+ page = settlementBillMapper.selectPage(page, currWrapper);
|
|
|
|
|
+ billList = page.getRecords();
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case "all":
|
|
|
|
|
+ LambdaQueryWrapper<VppSettlementBill> allWrapper = baseBillQueryWrapper();
|
|
|
|
|
+ allWrapper.orderByDesc(VppSettlementBill::getSettleYear)
|
|
|
|
|
+ .orderByDesc(VppSettlementBill::getSettleMonth);
|
|
|
|
|
+ billList = settlementBillMapper.selectList(allWrapper);
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case "filtered":
|
|
|
|
|
+ boolean hasFilter = id != null || StringUtils.isNotBlank(customerName);
|
|
|
|
|
+ if (!hasFilter) {
|
|
|
|
|
+ throw new BusinessException("filtered 模式下请至少提供一个筛选条件(id / customerName)!");
|
|
|
|
|
+ }
|
|
|
|
|
+ LambdaQueryWrapper<VppSettlementBill> filteredWrapper = buildBillQueryWrapper(id, customerName);
|
|
|
|
|
+ if (filteredWrapper == null) {
|
|
|
|
|
+ billList = Collections.emptyList();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ billList = settlementBillMapper.selectList(filteredWrapper);
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ default:
|
|
|
|
|
+ throw new BusinessException("不支持的导出范围:" + scope + ",请使用 current / all / filtered");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (billList == null) {
|
|
|
|
|
+ billList = Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ fillBillCustomerNames(billList);
|
|
|
|
|
+ fillBillSiteNames(billList);
|
|
|
|
|
+ fillBillContractPrice(billList);
|
|
|
|
|
+ writeBillExcel(fileName, billList, response);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private LambdaQueryWrapper<VppEnergyReadingMonthly> baseReadingQueryWrapper() {
|
|
private LambdaQueryWrapper<VppEnergyReadingMonthly> baseReadingQueryWrapper() {
|
|
|
return new LambdaQueryWrapper<VppEnergyReadingMonthly>()
|
|
return new LambdaQueryWrapper<VppEnergyReadingMonthly>()
|
|
|
.eq(VppEnergyReadingMonthly::getTenantId, SecurityUtils.getTenantId())
|
|
.eq(VppEnergyReadingMonthly::getTenantId, SecurityUtils.getTenantId())
|
|
@@ -139,6 +211,25 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
.orderByDesc(VppEnergyReadingMonthly::getSettleMonth);
|
|
.orderByDesc(VppEnergyReadingMonthly::getSettleMonth);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private LambdaQueryWrapper<VppSettlementBill> baseBillQueryWrapper() {
|
|
|
|
|
+ return new LambdaQueryWrapper<VppSettlementBill>()
|
|
|
|
|
+ .eq(VppSettlementBill::getTenantId, SecurityUtils.getTenantId())
|
|
|
|
|
+ .eq(VppSettlementBill::getDeleteFlag, VppAuditHelper.NOT_DELETED);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private LambdaQueryWrapper<VppSettlementBill> buildBillQueryWrapper(Long customerId, String customerName) {
|
|
|
|
|
+ Map<Long, String> customerNameMap = resolveCustomerNameMap(customerName);
|
|
|
|
|
+ if (StringUtils.isNotBlank(customerName) && customerNameMap.isEmpty()) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return baseBillQueryWrapper()
|
|
|
|
|
+ .eq(customerId != null, VppSettlementBill::getCustomerId, customerId)
|
|
|
|
|
+ .in(StringUtils.isNotBlank(customerName), VppSettlementBill::getCustomerId, customerNameMap.keySet())
|
|
|
|
|
+ .orderByDesc(VppSettlementBill::getSettleYear)
|
|
|
|
|
+ .orderByDesc(VppSettlementBill::getSettleMonth);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private Map<Long, String> resolveCustomerNameMap(String customerName) {
|
|
private Map<Long, String> resolveCustomerNameMap(String customerName) {
|
|
|
LambdaQueryWrapper<VppCustomer> customerQueryWrapper = new LambdaQueryWrapper<VppCustomer>()
|
|
LambdaQueryWrapper<VppCustomer> customerQueryWrapper = new LambdaQueryWrapper<VppCustomer>()
|
|
|
.eq(VppCustomer::getTenantId, SecurityUtils.getTenantId())
|
|
.eq(VppCustomer::getTenantId, SecurityUtils.getTenantId())
|
|
@@ -165,25 +256,72 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
records.forEach(reading -> reading.setCustomerName(customerNameMap.get(reading.getCustomerId())));
|
|
records.forEach(reading -> reading.setCustomerName(customerNameMap.get(reading.getCustomerId())));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void fillResourceNames(List<VppEnergyReadingMonthly> records) {
|
|
|
|
|
|
|
+ private void fillSiteNames(List<VppEnergyReadingMonthly> records) {
|
|
|
|
|
+ if (records == null || records.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<Long, String> siteNameMap = loadSiteNameMap(records.stream()
|
|
|
|
|
+ .map(VppEnergyReadingMonthly::getSiteId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet()));
|
|
|
|
|
+ records.forEach(reading -> reading.setSiteName(resolveSiteName(reading.getSiteId(), siteNameMap)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fillBillSiteNames(List<VppSettlementBill> records) {
|
|
|
if (records == null || records.isEmpty()) {
|
|
if (records == null || records.isEmpty()) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- Set<Long> resourceIds = records.stream()
|
|
|
|
|
- .map(VppEnergyReadingMonthly::getResourceId)
|
|
|
|
|
|
|
+ Map<Long, String> siteNameMap = loadSiteNameMap(records.stream()
|
|
|
|
|
+ .map(VppSettlementBill::getSiteId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet()));
|
|
|
|
|
+ records.forEach(bill -> bill.setSiteName(resolveSiteName(bill.getSiteId(), siteNameMap)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private Map<Long, String> loadSiteNameMap(Set<Long> siteIds) {
|
|
|
|
|
+ if (siteIds == null || siteIds.isEmpty()) {
|
|
|
|
|
+ return Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+ return siteMapper.selectBatchIds(siteIds).stream()
|
|
|
|
|
+ .collect(Collectors.toMap(VppSite::getId, VppSite::getSiteName, (a, b) -> a));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String resolveSiteName(Long siteId, Map<Long, String> siteNameMap) {
|
|
|
|
|
+ if (siteId == null) {
|
|
|
|
|
+ return "户号级";
|
|
|
|
|
+ }
|
|
|
|
|
+ return siteNameMap.get(siteId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fillBillCustomerNames(List<VppSettlementBill> records) {
|
|
|
|
|
+ if (records == null || records.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Set<Long> customerIds = records.stream()
|
|
|
|
|
+ .map(VppSettlementBill::getCustomerId)
|
|
|
.filter(Objects::nonNull)
|
|
.filter(Objects::nonNull)
|
|
|
.collect(Collectors.toSet());
|
|
.collect(Collectors.toSet());
|
|
|
- Map<Long, String> resourceNameMap = resourceIds.isEmpty()
|
|
|
|
|
- ? Collections.emptyMap()
|
|
|
|
|
- : resourcePointMapper.selectBatchIds(resourceIds).stream()
|
|
|
|
|
- .collect(Collectors.toMap(VppResourcePoint::getId, VppResourcePoint::getResourceName, (a, b) -> a));
|
|
|
|
|
- records.forEach(reading -> {
|
|
|
|
|
- if (reading.getResourceId() == null) {
|
|
|
|
|
- reading.setResourceName("户号级");
|
|
|
|
|
- } else {
|
|
|
|
|
- reading.setResourceName(resourceNameMap.get(reading.getResourceId()));
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ if (customerIds.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<Long, String> customerNameMap = vppCustomerMapper.selectBatchIds(customerIds).stream()
|
|
|
|
|
+ .collect(Collectors.toMap(VppCustomer::getId, VppCustomer::getCustomerName, (a, b) -> a));
|
|
|
|
|
+ records.forEach(bill -> bill.setCustomerName(customerNameMap.get(bill.getCustomerId())));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fillBillContractPrice(List<VppSettlementBill> records) {
|
|
|
|
|
+ if (records == null || records.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ records.forEach(bill -> bill.setContractPrice(calcContractPrice(bill.getTotalEnergyKwh(), bill.getTotalAmount())));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private BigDecimal calcContractPrice(BigDecimal totalEnergyKwh, BigDecimal totalAmount) {
|
|
|
|
|
+ if (totalEnergyKwh == null || totalAmount == null
|
|
|
|
|
+ || totalEnergyKwh.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return totalAmount.divide(totalEnergyKwh, 4, RoundingMode.HALF_UP);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private Map<String, Object> resolveCalcCycle(String calcCycle) {
|
|
private Map<String, Object> resolveCalcCycle(String calcCycle) {
|
|
@@ -211,7 +349,7 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
headerStyle.setFont(headerFont);
|
|
headerStyle.setFont(headerFont);
|
|
|
|
|
|
|
|
String[] headers = {
|
|
String[] headers = {
|
|
|
- "序号", "客户名称", "资源点", "结算年", "结算月",
|
|
|
|
|
|
|
+ "序号", "客户名称", "站点名称", "核算周期",
|
|
|
"总用电量(kWh)", "峰电量(kWh)", "平电量(kWh)", "谷电量(kWh)", "尖电量(kWh)",
|
|
"总用电量(kWh)", "峰电量(kWh)", "平电量(kWh)", "谷电量(kWh)", "尖电量(kWh)",
|
|
|
"发电量(kWh)", "核算状态", "核算时间", "创建时间"
|
|
"发电量(kWh)", "核算状态", "核算时间", "创建时间"
|
|
|
};
|
|
};
|
|
@@ -227,18 +365,17 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
org.apache.poi.xssf.usermodel.XSSFRow row = sheet.createRow(rowIdx++);
|
|
org.apache.poi.xssf.usermodel.XSSFRow row = sheet.createRow(rowIdx++);
|
|
|
setCell(row, 0, rowIdx - 1);
|
|
setCell(row, 0, rowIdx - 1);
|
|
|
setCell(row, 1, reading.getCustomerName());
|
|
setCell(row, 1, reading.getCustomerName());
|
|
|
- setCell(row, 2, reading.getResourceName());
|
|
|
|
|
- setCell(row, 3, reading.getSettleYear());
|
|
|
|
|
- setCell(row, 4, reading.getSettleMonth());
|
|
|
|
|
- setCell(row, 5, numberStr(reading.getTotalEnergyKwh()));
|
|
|
|
|
- setCell(row, 6, numberStr(reading.getPeakEnergyKwh()));
|
|
|
|
|
- setCell(row, 7, numberStr(reading.getFlatEnergyKwh()));
|
|
|
|
|
- setCell(row, 8, numberStr(reading.getValleyEnergyKwh()));
|
|
|
|
|
- setCell(row, 9, numberStr(reading.getSharpEnergyKwh()));
|
|
|
|
|
- setCell(row, 10, numberStr(reading.getGenEnergyKwh()));
|
|
|
|
|
- setCell(row, 11, calcStatusLabel(reading.getCalcStatus()));
|
|
|
|
|
- setCell(row, 12, dateTimeStr(reading.getCalcAt()));
|
|
|
|
|
- setCell(row, 13, dateTimeStr(reading.getCreateTime()));
|
|
|
|
|
|
|
+ setCell(row, 2, reading.getSiteName());
|
|
|
|
|
+ setCell(row, 3, settleCycleLabel(reading.getSettleYear(), reading.getSettleMonth()));
|
|
|
|
|
+ setCell(row, 4, numberStr(reading.getTotalEnergyKwh()));
|
|
|
|
|
+ setCell(row, 5, numberStr(reading.getPeakEnergyKwh()));
|
|
|
|
|
+ setCell(row, 6, numberStr(reading.getFlatEnergyKwh()));
|
|
|
|
|
+ setCell(row, 7, numberStr(reading.getValleyEnergyKwh()));
|
|
|
|
|
+ setCell(row, 8, numberStr(reading.getSharpEnergyKwh()));
|
|
|
|
|
+ setCell(row, 9, numberStr(reading.getGenEnergyKwh()));
|
|
|
|
|
+ setCell(row, 10, calcStatusLabel(reading.getCalcStatus()));
|
|
|
|
|
+ setCell(row, 11, dateTimeStr(reading.getCalcAt()));
|
|
|
|
|
+ setCell(row, 12, dateTimeStr(reading.getCreateTime()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < headers.length; i++) {
|
|
for (int i = 0; i < headers.length; i++) {
|
|
@@ -249,19 +386,73 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- String encodedFileName = java.net.URLEncoder.encode(fileName + ".xlsx", StandardCharsets.UTF_8.name())
|
|
|
|
|
- .replace("+", "%20");
|
|
|
|
|
- response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
|
|
- response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
|
|
|
|
- response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName
|
|
|
|
|
- + "; filename*=UTF-8''" + encodedFileName);
|
|
|
|
|
- workbook.write(response.getOutputStream());
|
|
|
|
|
- response.getOutputStream().flush();
|
|
|
|
|
|
|
+ writeExcelResponse(fileName, workbook, response);
|
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
|
throw new BusinessException("导出月度电量核算数据失败: " + e.getMessage());
|
|
throw new BusinessException("导出月度电量核算数据失败: " + e.getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private void writeBillExcel(String fileName, List<VppSettlementBill> billList, HttpServletResponse response) {
|
|
|
|
|
+ try (org.apache.poi.xssf.usermodel.XSSFWorkbook workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook()) {
|
|
|
|
|
+ org.apache.poi.xssf.usermodel.XSSFSheet sheet = workbook.createSheet("电费账单");
|
|
|
|
|
+
|
|
|
|
|
+ org.apache.poi.xssf.usermodel.XSSFCellStyle headerStyle = workbook.createCellStyle();
|
|
|
|
|
+ headerStyle.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.GREY_25_PERCENT.getIndex());
|
|
|
|
|
+ headerStyle.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
+ org.apache.poi.xssf.usermodel.XSSFFont headerFont = workbook.createFont();
|
|
|
|
|
+ headerFont.setBold(true);
|
|
|
|
|
+ headerStyle.setFont(headerFont);
|
|
|
|
|
+
|
|
|
|
|
+ String[] headers = {
|
|
|
|
|
+ "序号", "客户名称", "站点名称", "结算周期", "用电量(kWh)", "合同电价(元/kWh)",
|
|
|
|
|
+ "电费(元)", "结算时间"
|
|
|
|
|
+ };
|
|
|
|
|
+ org.apache.poi.xssf.usermodel.XSSFRow headerRow = sheet.createRow(0);
|
|
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
|
|
+ org.apache.poi.xssf.usermodel.XSSFCell cell = headerRow.createCell(i);
|
|
|
|
|
+ cell.setCellValue(headers[i]);
|
|
|
|
|
+ cell.setCellStyle(headerStyle);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int rowIdx = 1;
|
|
|
|
|
+ for (VppSettlementBill bill : billList) {
|
|
|
|
|
+ org.apache.poi.xssf.usermodel.XSSFRow row = sheet.createRow(rowIdx++);
|
|
|
|
|
+ setCell(row, 0, rowIdx - 1);
|
|
|
|
|
+ setCell(row, 1, bill.getCustomerName());
|
|
|
|
|
+ setCell(row, 2, bill.getSiteName());
|
|
|
|
|
+ setCell(row, 3, settleCycleLabel(bill.getSettleYear(), bill.getSettleMonth()));
|
|
|
|
|
+ setCell(row, 4, numberStr(bill.getTotalEnergyKwh()));
|
|
|
|
|
+ setCell(row, 5, numberStr(bill.getContractPrice()));
|
|
|
|
|
+ setCell(row, 6, numberStr(bill.getTotalAmount()));
|
|
|
|
|
+ setCell(row, 7, dateTimeStr(bill.getGeneratedAt()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
|
|
+ sheet.autoSizeColumn(i);
|
|
|
|
|
+ int width = sheet.getColumnWidth(i);
|
|
|
|
|
+ if (width > 15000) {
|
|
|
|
|
+ sheet.setColumnWidth(i, 15000);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ writeExcelResponse(fileName, workbook, response);
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ throw new BusinessException("导出电费账单数据失败: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void writeExcelResponse(String fileName, org.apache.poi.xssf.usermodel.XSSFWorkbook workbook,
|
|
|
|
|
+ HttpServletResponse response) throws IOException {
|
|
|
|
|
+ String encodedFileName = java.net.URLEncoder.encode(fileName + ".xlsx", StandardCharsets.UTF_8.name())
|
|
|
|
|
+ .replace("+", "%20");
|
|
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
|
|
+ response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
|
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName
|
|
|
|
|
+ + "; filename*=UTF-8''" + encodedFileName);
|
|
|
|
|
+ workbook.write(response.getOutputStream());
|
|
|
|
|
+ response.getOutputStream().flush();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private static void setCell(org.apache.poi.xssf.usermodel.XSSFRow row, int col, Object value) {
|
|
private static void setCell(org.apache.poi.xssf.usermodel.XSSFRow row, int col, Object value) {
|
|
|
if (value != null) {
|
|
if (value != null) {
|
|
|
row.createCell(col).setCellValue(String.valueOf(value));
|
|
row.createCell(col).setCellValue(String.valueOf(value));
|
|
@@ -278,6 +469,13 @@ public class VppSettlementServiceImpl implements VppSettlementService {
|
|
|
return value == null ? "" : value.toString();
|
|
return value == null ? "" : value.toString();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private static String settleCycleLabel(String settleYear, Integer settleMonth) {
|
|
|
|
|
+ if (StringUtils.isBlank(settleYear) || settleMonth == null) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ return settleYear + "-" + String.format("%02d", settleMonth);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private static String calcStatusLabel(Integer calcStatus) {
|
|
private static String calcStatusLabel(Integer calcStatus) {
|
|
|
if (calcStatus == null) {
|
|
if (calcStatus == null) {
|
|
|
return "";
|
|
return "";
|