优化Excel导出功能,增加费用汇总区域及金额转换为中文大写
This commit is contained in:
parent
3bdf7bdc12
commit
c8f7e94c8e
|
|
@ -246,23 +246,23 @@
|
|||
elem: '#calculation-table',
|
||||
data: details,
|
||||
cols: [[
|
||||
{field: 'machineTypeName', title: '物资名称', width: 180},
|
||||
{field: 'machineModel', title: '规格型号', width: 150},
|
||||
{field: 'machineUnit', title: '单位', width: 100},
|
||||
{field: 'currentCount', title: '未退还数量', width: 120},
|
||||
{field: 'price', title: '单价(元/天)', width: 120, templet: function(d){
|
||||
{field: 'machineTypeName', title: '物资名称', minWidth: 150},
|
||||
{field: 'machineModel', title: '规格型号', minWidth: 120},
|
||||
{field: 'machineUnit', title: '单位', width: 80},
|
||||
{field: 'currentCount', title: '未退还数量', width: 110},
|
||||
{field: 'price', title: '单价(元/天)', width: 110, templet: function(d){
|
||||
return d.price ? d.price.toFixed(2) : '0.00';
|
||||
}},
|
||||
{field: 'firstLeaseTime', title: '首次领料时间', width: 180, templet: function(d){
|
||||
{field: 'firstLeaseTime', title: '首次领料时间', minWidth: 150, templet: function(d){
|
||||
return d.firstLeaseTime || '--';
|
||||
}},
|
||||
{field: 'lastReturnTime', title: '最后退料时间', width: 180, templet: function(d){
|
||||
{field: 'lastReturnTime', title: '最后退料时间', minWidth: 150, templet: function(d){
|
||||
return d.lastReturnTime || '--';
|
||||
}},
|
||||
{field: 'amount', title: '金额(元)', width: 120, style: 'color: #FF5722; font-weight: bold;', templet: function(d){
|
||||
{field: 'amount', title: '金额(元)', width: 110, style: 'color: #FF5722; font-weight: bold;', templet: function(d){
|
||||
return d.amount ? d.amount.toFixed(2) : '0.00';
|
||||
}},
|
||||
{title: '操作', width: 100, templet: function(d){
|
||||
{title: '操作', width: 100, fixed: 'right', templet: function(d){
|
||||
return '<a class="layui-btn layui-btn-xs" lay-event="viewDetail">查看明细</a>';
|
||||
}}
|
||||
]],
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="filter-action">
|
||||
<button class="layui-btn" lay-submit lay-filter="calculation-generate">生成</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="calculation-save">保存</button>
|
||||
<button class="layui-btn" lay-submit lay-filter="calculation-generate">开始计算</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="calculation-save">保存结算单</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -26,7 +26,7 @@
|
|||
LEFT JOIN wf_task_record wtr1 ON wtr1.ID = wtr.SUP_ID
|
||||
LEFT JOIN wf_task_record wtr2 ON wtr2.ID = wtr1.SUP_ID
|
||||
LEFT JOIN wf_collar_apply wca ON wca.APPLY_NUMBER = wtr2.NUMBER
|
||||
LEFT JOIN bm_subcontractors bs ON wca.SUBCONTRACTORS_ID = bs.ID
|
||||
LEFT JOIN bm_subcontractors bs ON wca.SUBCONTRACTORS_ID = bs.ID
|
||||
LEFT JOIN wf_agreement_task wat ON wtr.SUP_ID = wat.TASK_ID
|
||||
LEFT JOIN wf_lease_agreement wla ON wat.AGREEMENT_ID = wla.ID
|
||||
LEFT JOIN mm_type mt ON wir.MODEL_ID = mt.ID
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
LEFT JOIN bm_project bp ON wla.PROJECT = bp.ID
|
||||
LEFT JOIN pm_organization pmo ON pmo.id = wtr.ORG_ID
|
||||
LEFT JOIN wf_ma_outstock wmo ON wir.SUP_ID = wmo.TASK_ID
|
||||
LEFT JOIN pm_user pu ON wmo.OUT_PERSON = pu.ID
|
||||
LEFT JOIN pm_user pu ON wmo.OUT_PERSON = pu.ID
|
||||
LEFT JOIN mm_machines mm ON mm.ID = wir.MA_ID
|
||||
WHERE wir.TYPE = 2
|
||||
and wtr.IS_ACTIVE = 1
|
||||
|
|
@ -43,8 +43,9 @@
|
|||
<if test="param.machineTypeId != null">
|
||||
and wir.MODEL_ID = #{param.machineTypeId}
|
||||
</if>
|
||||
<if test="param.startTime != null and param.endTime != null ">
|
||||
and left(wtr.OPERATION_TIME,10) between #{param.startTime} and #{param.endTime}
|
||||
<if test="param.endTime != null">
|
||||
<!-- 查询所有在统计结束时间之前的领料记录(包括统计期间开始之前的领料) -->
|
||||
and left(wtr.OPERATION_TIME,10) <= #{param.endTime}
|
||||
</if>
|
||||
<if test="param.keyWord != null and param.keyWord != ''">
|
||||
AND(
|
||||
|
|
@ -88,7 +89,10 @@
|
|||
<if test="param.machineTypeId != null">
|
||||
and wir.MODEL_ID = #{param.machineTypeId}
|
||||
</if>
|
||||
and left(wir.TIME,10) BETWEEN #{param.startTime} and #{param.endTime}
|
||||
<if test="param.endTime != null">
|
||||
<!-- 查询所有在统计结束时间之前的退料记录(包括统计期间开始之前的退料) -->
|
||||
and left(wir.TIME,10) <= #{param.endTime}
|
||||
</if>
|
||||
<if test="param.keyWord != null and param.keyWord != ''">
|
||||
and (
|
||||
bu.`NAME` like concat('%',#{param.keyWord},'%') OR
|
||||
|
|
|
|||
|
|
@ -165,6 +165,92 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数字金额转换为中文大写金额
|
||||
*
|
||||
* @param amount 金额数字
|
||||
* @return 中文大写金额字符串
|
||||
*/
|
||||
private String convertToChineseAmount(double amount) {
|
||||
if (amount == 0) {
|
||||
return "零元整";
|
||||
}
|
||||
|
||||
// 中文数字
|
||||
String[] chineseNumbers = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
|
||||
// 中文单位
|
||||
String[] units = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"};
|
||||
|
||||
// 处理负数
|
||||
boolean isNegative = amount < 0;
|
||||
amount = Math.abs(amount);
|
||||
|
||||
// 分离整数和小数部分
|
||||
long integerPart = (long) amount;
|
||||
int decimalPart = (int) Math.round((amount - integerPart) * 100);
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
if (isNegative) {
|
||||
result.append("负");
|
||||
}
|
||||
|
||||
// 处理整数部分
|
||||
if (integerPart == 0) {
|
||||
result.append("零");
|
||||
} else {
|
||||
String integerStr = String.valueOf(integerPart);
|
||||
int length = integerStr.length();
|
||||
boolean hasZero = false; // 标记是否有零
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int digit = integerStr.charAt(i) - '0';
|
||||
int unitIndex = length - i - 1;
|
||||
|
||||
if (digit == 0) {
|
||||
// 遇到0的处理
|
||||
if (unitIndex == 4 || unitIndex == 8) {
|
||||
// 万位或亿位,即使是0也要加单位
|
||||
if (!hasZero) {
|
||||
result.append(units[unitIndex]);
|
||||
}
|
||||
}
|
||||
hasZero = true;
|
||||
} else {
|
||||
// 非0的处理
|
||||
if (hasZero) {
|
||||
result.append(chineseNumbers[0]); // 补零
|
||||
}
|
||||
result.append(chineseNumbers[digit]);
|
||||
result.append(units[unitIndex]);
|
||||
hasZero = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.append("元");
|
||||
|
||||
// 处理小数部分
|
||||
if (decimalPart == 0) {
|
||||
result.append("整");
|
||||
} else {
|
||||
int jiao = decimalPart / 10;
|
||||
int fen = decimalPart % 10;
|
||||
|
||||
if (jiao > 0) {
|
||||
result.append(chineseNumbers[jiao]).append("角");
|
||||
} else if (fen > 0) {
|
||||
result.append("零");
|
||||
}
|
||||
|
||||
if (fen > 0) {
|
||||
result.append(chineseNumbers[fen]).append("分");
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectLeaseCostDetail> queryProjectLeaseDetails(ProjectLeaseCostDetail o) {
|
||||
return projectCostDao.queryProjectLeaseDetails(o);
|
||||
|
|
@ -356,16 +442,87 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
LocalDateTime firstLeaseTime = null;
|
||||
LocalDateTime lastReturnTime = null;
|
||||
|
||||
// 第一步:处理统计期间开始之前的所有操作,计算期初在用数量
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
for (ProjectLeaseCostDetail item : items) {
|
||||
if (item == null || item.getOperateTime() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
LocalDateTime operateTime = LocalDateTime.parse(item.getOperateTime(), formatter);
|
||||
|
||||
// 只处理统计期间开始之前的操作
|
||||
if (operateTime.isBefore(startDate)) {
|
||||
boolean isLease = (item.getOperateType() == null || item.getOperateType() != 2);
|
||||
if (isLease) {
|
||||
int quantity = item.getLeaseNum() != null ? item.getLeaseNum() : 0;
|
||||
currentCount += quantity;
|
||||
System.out.println("期初领料: 物资ID=" + machineTypeId + ", 时间=" + item.getOperateTime() + ", 数量=" + quantity + ", 累计=" + currentCount);
|
||||
} else {
|
||||
int quantity = item.getReturnNum() != null ? item.getReturnNum() : 0;
|
||||
currentCount -= quantity;
|
||||
System.out.println("期初退料: 物资ID=" + machineTypeId + ", 时间=" + item.getOperateTime() + ", 数量=" + quantity + ", 累计=" + currentCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("物资ID=" + machineTypeId + " 期初在用数量: " + currentCount);
|
||||
|
||||
// 如果期初在用数量大于0,需要计算从统计开始时间到第一个操作时间(或统计结束时间)的费用
|
||||
if (currentCount > 0) {
|
||||
// 找到统计期间内的第一个操作时间
|
||||
LocalDateTime firstOperateTimeInPeriod = null;
|
||||
for (ProjectLeaseCostDetail item : items) {
|
||||
if (item == null || item.getOperateTime() == null) {
|
||||
continue;
|
||||
}
|
||||
LocalDateTime operateTime = LocalDateTime.parse(item.getOperateTime(), formatter);
|
||||
if (!operateTime.isBefore(startDate) && !operateTime.isAfter(endDate)) {
|
||||
if (firstOperateTimeInPeriod == null || operateTime.isBefore(firstOperateTimeInPeriod)) {
|
||||
firstOperateTimeInPeriod = operateTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果统计期间内有操作,计算从开始时间到第一个操作时间的费用
|
||||
// 如果统计期间内没有操作,计算从开始时间到结束时间的费用
|
||||
LocalDateTime endTimeForInitialSegment = firstOperateTimeInPeriod != null ? firstOperateTimeInPeriod : endDate;
|
||||
long daysBetween = java.time.Duration.between(startDate, endTimeForInitialSegment).toDays();
|
||||
|
||||
if (daysBetween > 0) {
|
||||
double segmentAmount = currentCount * unitPrice * daysBetween;
|
||||
totalItemAmount += segmentAmount;
|
||||
|
||||
Map<String, Object> segment = new HashMap<>();
|
||||
segment.put("startTime", startDate.toString());
|
||||
segment.put("endTime", endTimeForInitialSegment.toString());
|
||||
segment.put("days", daysBetween);
|
||||
segment.put("count", currentCount);
|
||||
segment.put("amount", segmentAmount);
|
||||
segments.add(segment);
|
||||
|
||||
System.out.println("期初在用费用: 物资ID=" + machineTypeId + ", 时段=" + startDate + " 至 " + endTimeForInitialSegment
|
||||
+ ", 天数=" + daysBetween + ", 数量=" + currentCount + ", 单价=" + unitPrice + ", 段金额=" + segmentAmount);
|
||||
}
|
||||
|
||||
// 如果统计期间内有操作,更新previousTime为第一个操作时间
|
||||
if (firstOperateTimeInPeriod != null) {
|
||||
previousTime = firstOperateTimeInPeriod;
|
||||
} else {
|
||||
// 如果统计期间内没有操作,直接返回结果
|
||||
previousTime = endDate;
|
||||
}
|
||||
}
|
||||
|
||||
// 第二步:处理统计期间内的所有操作
|
||||
for (ProjectLeaseCostDetail item : items) {
|
||||
if (item == null || item.getOperateTime() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalDateTime operateTime = LocalDateTime.parse(item.getOperateTime(), formatter);
|
||||
|
||||
// 如果操作时间超出统计范围,跳过
|
||||
// 只处理统计期间内的操作(包括开始和结束时间)
|
||||
if (operateTime.isBefore(startDate) || operateTime.isAfter(endDate)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -999,9 +1156,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
}
|
||||
}
|
||||
|
||||
// 调用带签名区域的导出方法,传递工程名称和制单时间
|
||||
// 计算总金额
|
||||
double totalAmount = calculation.getTotalAmount() != null ? calculation.getTotalAmount() : 0.0;
|
||||
|
||||
// 调用带签名区域的导出方法,传递工程名称、制单时间和总金额
|
||||
exportSegmentExcelWithSignature(fileName, sheetName, headers, widths, formats, dataList,
|
||||
calculation.getProjectName(), calculation.getCreateTime(), response);
|
||||
calculation.getProjectName(), calculation.getCreateTime(), totalAmount, response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1015,11 +1175,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
* @param dataList 数据列表
|
||||
* @param projectName 工程名称
|
||||
* @param createTime 制单时间
|
||||
* @param totalAmount 总金额
|
||||
* @param response HttpServletResponse对象
|
||||
* @throws Exception 导出异常
|
||||
*/
|
||||
private void exportSegmentExcelWithSignature(String fileName, String sheetName, String[] headers, int[] widths, int[] formats,
|
||||
List<Map<String, Object>> dataList, String projectName, String createTime, javax.servlet.http.HttpServletResponse response) throws Exception {
|
||||
List<Map<String, Object>> dataList, String projectName, String createTime, double totalAmount, javax.servlet.http.HttpServletResponse response) throws Exception {
|
||||
try {
|
||||
// 设置文件名
|
||||
String filename = "";
|
||||
|
|
@ -1229,6 +1390,9 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
}
|
||||
}
|
||||
|
||||
// 添加费用汇总区域(在签名区域之前)
|
||||
currentRowIndex = addSummaryArea(wb, sheet, currentRowIndex, headers.length, totalAmount);
|
||||
|
||||
// 添加签名区域
|
||||
addSignatureArea(wb, sheet, currentRowIndex, headers.length);
|
||||
|
||||
|
|
@ -1242,9 +1406,196 @@ public class ProjectCostServiceImpl implements ProjectCostService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加费用汇总区域到Excel表格(在签名区域之前)
|
||||
*
|
||||
* @param wb 工作簿
|
||||
* @param sheet 工作表
|
||||
* @param startRowIndex 开始行索引
|
||||
* @param totalColumns 总列数
|
||||
* @param totalAmount 总金额
|
||||
* @return 新的行索引
|
||||
*/
|
||||
private int addSummaryArea(HSSFWorkbook wb, HSSFSheet sheet, int startRowIndex, int totalColumns, double totalAmount) {
|
||||
// 创建样式 - 标签样式(居中对齐)
|
||||
HSSFCellStyle summaryStyle = wb.createCellStyle();
|
||||
HSSFFont summaryFont = wb.createFont();
|
||||
summaryFont.setFontName("微软雅黑");
|
||||
summaryFont.setFontHeightInPoints((short) 11);
|
||||
summaryFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
|
||||
summaryStyle.setFont(summaryFont);
|
||||
summaryStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 改为居中对齐
|
||||
summaryStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
|
||||
summaryStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
|
||||
summaryStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
|
||||
summaryStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
|
||||
summaryStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
|
||||
|
||||
// 金额样式(居中对齐)
|
||||
HSSFCellStyle amountStyle = wb.createCellStyle();
|
||||
HSSFFont amountFont = wb.createFont();
|
||||
amountFont.setFontName("微软雅黑");
|
||||
amountFont.setFontHeightInPoints((short) 11);
|
||||
amountStyle.setFont(amountFont);
|
||||
amountStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 改为居中对齐
|
||||
amountStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
|
||||
amountStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
|
||||
amountStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
|
||||
amountStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
|
||||
amountStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
|
||||
amountStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));
|
||||
|
||||
// 空一行
|
||||
startRowIndex += 1;
|
||||
|
||||
// 计算各项费用
|
||||
double transportFee = 0.0; // 运输费
|
||||
double craneFee = 0.0; // 吊车费
|
||||
double compensationFee = 0.0; // 赔偿费
|
||||
double grandTotal = totalAmount + transportFee + craneFee + compensationFee; // 汇总金额
|
||||
|
||||
// 计算列宽分配(左侧标签占30%,右侧金额占70%)
|
||||
int labelColumns = Math.max(1, totalColumns * 3 / 10);
|
||||
|
||||
// 第一行:合计金额
|
||||
HSSFRow row1 = sheet.createRow(startRowIndex);
|
||||
row1.setHeight((short) 450);
|
||||
HSSFCell cell1_1 = row1.createCell(0);
|
||||
cell1_1.setCellValue("合计金额:");
|
||||
cell1_1.setCellStyle(summaryStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, 0, labelColumns - 1));
|
||||
|
||||
HSSFCell cell1_2 = row1.createCell(labelColumns);
|
||||
cell1_2.setCellValue(totalAmount);
|
||||
cell1_2.setCellStyle(amountStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, labelColumns, totalColumns - 1));
|
||||
|
||||
// 填充合并区域的所有单元格
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
if (row1.getCell(i) == null) {
|
||||
row1.createCell(i).setCellStyle(i < labelColumns ? summaryStyle : amountStyle);
|
||||
}
|
||||
}
|
||||
startRowIndex++;
|
||||
|
||||
// 第二行:运输费
|
||||
HSSFRow row2 = sheet.createRow(startRowIndex);
|
||||
row2.setHeight((short) 450);
|
||||
HSSFCell cell2_1 = row2.createCell(0);
|
||||
cell2_1.setCellValue("运输费:");
|
||||
cell2_1.setCellStyle(summaryStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, 0, labelColumns - 1));
|
||||
|
||||
HSSFCell cell2_2 = row2.createCell(labelColumns);
|
||||
cell2_2.setCellValue(transportFee);
|
||||
cell2_2.setCellStyle(amountStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, labelColumns, totalColumns - 1));
|
||||
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
if (row2.getCell(i) == null) {
|
||||
row2.createCell(i).setCellStyle(i < labelColumns ? summaryStyle : amountStyle);
|
||||
}
|
||||
}
|
||||
startRowIndex++;
|
||||
|
||||
// 第三行:吊车费
|
||||
HSSFRow row3 = sheet.createRow(startRowIndex);
|
||||
row3.setHeight((short) 450);
|
||||
HSSFCell cell3_1 = row3.createCell(0);
|
||||
cell3_1.setCellValue("吊车费:");
|
||||
cell3_1.setCellStyle(summaryStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, 0, labelColumns - 1));
|
||||
|
||||
HSSFCell cell3_2 = row3.createCell(labelColumns);
|
||||
cell3_2.setCellValue(craneFee);
|
||||
cell3_2.setCellStyle(amountStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, labelColumns, totalColumns - 1));
|
||||
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
if (row3.getCell(i) == null) {
|
||||
row3.createCell(i).setCellStyle(i < labelColumns ? summaryStyle : amountStyle);
|
||||
}
|
||||
}
|
||||
startRowIndex++;
|
||||
|
||||
// 第四行:赔偿费
|
||||
HSSFRow row4 = sheet.createRow(startRowIndex);
|
||||
row4.setHeight((short) 450);
|
||||
HSSFCell cell4_1 = row4.createCell(0);
|
||||
cell4_1.setCellValue("赔偿费:");
|
||||
cell4_1.setCellStyle(summaryStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, 0, labelColumns - 1));
|
||||
|
||||
HSSFCell cell4_2 = row4.createCell(labelColumns);
|
||||
cell4_2.setCellValue(compensationFee);
|
||||
cell4_2.setCellStyle(amountStyle);
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, labelColumns, totalColumns - 1));
|
||||
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
if (row4.getCell(i) == null) {
|
||||
row4.createCell(i).setCellStyle(i < labelColumns ? summaryStyle : amountStyle);
|
||||
}
|
||||
}
|
||||
startRowIndex++;
|
||||
|
||||
// 第五行:汇总金额(分成4列:大写标签、大写内容、小写标签、小写内容)
|
||||
HSSFRow row5 = sheet.createRow(startRowIndex);
|
||||
row5.setHeight((short) 600); // 稍高一些
|
||||
|
||||
// 计算每列的宽度(平均分成4列)
|
||||
int colWidth = totalColumns / 4;
|
||||
|
||||
// 第1列:汇总金额大写
|
||||
HSSFCell cell5_1 = row5.createCell(0);
|
||||
cell5_1.setCellValue("汇总金额大写:");
|
||||
cell5_1.setCellStyle(summaryStyle);
|
||||
if (colWidth > 1) {
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, 0, colWidth - 1));
|
||||
}
|
||||
|
||||
// 第2列:大写内容
|
||||
String chineseAmount = convertToChineseAmount(grandTotal);
|
||||
HSSFCell cell5_2 = row5.createCell(colWidth);
|
||||
cell5_2.setCellValue(chineseAmount);
|
||||
cell5_2.setCellStyle(amountStyle);
|
||||
if (colWidth > 1) {
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, colWidth, colWidth * 2 - 1));
|
||||
}
|
||||
|
||||
// 第3列:汇总金额小写
|
||||
HSSFCell cell5_3 = row5.createCell(colWidth * 2);
|
||||
cell5_3.setCellValue("汇总金额小写:");
|
||||
cell5_3.setCellStyle(summaryStyle);
|
||||
if (colWidth > 1) {
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, colWidth * 2, colWidth * 3 - 1));
|
||||
}
|
||||
|
||||
// 第4列:小写内容
|
||||
HSSFCell cell5_4 = row5.createCell(colWidth * 3);
|
||||
cell5_4.setCellValue(String.format("%.2f 元", grandTotal));
|
||||
cell5_4.setCellStyle(amountStyle);
|
||||
if (colWidth > 1) {
|
||||
sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(startRowIndex, startRowIndex, colWidth * 3, totalColumns - 1));
|
||||
}
|
||||
|
||||
// 填充合并区域的所有单元格
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
if (row5.getCell(i) == null) {
|
||||
if (i < colWidth || (i >= colWidth * 2 && i < colWidth * 3)) {
|
||||
row5.createCell(i).setCellStyle(summaryStyle); // 标签列
|
||||
} else {
|
||||
row5.createCell(i).setCellStyle(amountStyle); // 内容列
|
||||
}
|
||||
}
|
||||
}
|
||||
startRowIndex++;
|
||||
|
||||
return startRowIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加签名区域到Excel表格
|
||||
*
|
||||
*
|
||||
* @param wb 工作簿
|
||||
* @param sheet 工作表
|
||||
* @param startRowIndex 开始行索引
|
||||
|
|
|
|||
Loading…
Reference in New Issue