diff --git a/src/main/java/com/bonus/aqgqj/business/backstage/controller/PurchaseController.java b/src/main/java/com/bonus/aqgqj/business/backstage/controller/PurchaseController.java index 2c9ec30..87fb691 100644 --- a/src/main/java/com/bonus/aqgqj/business/backstage/controller/PurchaseController.java +++ b/src/main/java/com/bonus/aqgqj/business/backstage/controller/PurchaseController.java @@ -39,6 +39,7 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; +import java.io.IOException; import java.io.OutputStream; import java.net.URLEncoder; import java.util.ArrayList; @@ -416,127 +417,165 @@ public class PurchaseController { CellStyle headerStyle = ExcelStyleUtil.getHeaderStyle(wb); CellStyle commonStyle = ExcelStyleUtil.getCommonStyle(wb); - int itemNum = 0; - int rows = 0; - int xh = 1; + int itemNum = 0; // 数据项计数 + int rows = 0; // 行号(从0开始) + int xh = 1; // 序号(从1开始) + + // 第一步:先创建表头(只创建一次,移出循环) + rows = createHead(sheet, headerStyle); + + // 第二步:遍历所有数据(包括第一条) for (OutPlanVoDetails details : list) { - if (itemNum == 0) { - //创建表头 - rows = createHead(sheet, headerStyle); - } else { - List supInfoList = details.getSupList(); - //创建数据 - boolean isFalst = true; - int size = supInfoList.size(); - for (OutPlanVoSupInfo sup : supInfoList) { - if (isFalst) { - isFalst = false; + List supInfoList = details.getSupList(); + // 空数据防护:避免supInfoList为null导致空指针 + if (supInfoList == null || supInfoList.isEmpty()) { + itemNum++; + xh++; + continue; + } + + // 创建数据行(所有数据项都处理,包括第一条) + boolean isFirstSup = true; + int size = supInfoList.size(); + for (OutPlanVoSupInfo sup : supInfoList) { + if (isFirstSup) { + isFirstSup = false; + // 合并单元格:只在第一个供应商行处理合并逻辑 + // 校验合并范围有效性(避免Merged region必须包含2+单元格的错误) + if (size > 1) { CellRangeAddress cellRangeAddress = new CellRangeAddress(rows, rows + size - 1, 0, 0); sheet.addMergedRegion(cellRangeAddress); - // 行、列(0开始) CellRangeAddress cellRangeAddress2 = new CellRangeAddress(rows, rows + size - 1, 1, 1); sheet.addMergedRegion(cellRangeAddress2); - CellRangeAddress cellRangeAddress3 = new CellRangeAddress(rows, rows + size - 1, 2, 2); sheet.addMergedRegion(cellRangeAddress3); - CellRangeAddress cellRangeAddress4 = new CellRangeAddress(rows, rows + size - 1, 3, 3); sheet.addMergedRegion(cellRangeAddress4); - CellRangeAddress cellRangeAddress5 = new CellRangeAddress(rows, rows + size - 1, 4, 4); sheet.addMergedRegion(cellRangeAddress5); - - - Row row = sheet.createRow(rows); - Cell cell = row.createCell(0); - cell.setCellValue(xh - 1); - cell.setCellStyle(commonStyle); - Cell cell1 = row.createCell(1); - cell1.setCellValue(details.getName()); - cell1.setCellStyle(commonStyle); - Cell cell3 = row.createCell(2); - cell3.setCellValue(details.getModel()); - cell3.setCellStyle(commonStyle); - Cell cell4 = row.createCell(3); - cell4.setCellValue(details.getUnit()); - cell4.setCellStyle(commonStyle); - Cell cell5 = row.createCell(4); - cell5.setCellValue(details.getNeedNum()); - cell5.setCellStyle(commonStyle); - Cell cell6 = row.createCell(5); - cell6.setCellValue(sup.getPrice()); - cell6.setCellStyle(commonStyle); - Cell cell7 = row.createCell(6); - cell7.setCellValue(sup.getCgNum()); - cell7.setCellStyle(commonStyle); - Cell cell8 = row.createCell(7); - cell8.setCellValue(sup.getLkNum()); - cell8.setCellStyle(commonStyle); - Cell cell9 = row.createCell(8); - cell9.setCellValue(sup.getSupName()); - cell9.setCellStyle(commonStyle); - Cell cell10 = row.createCell(9); - cell10.setCellValue(sup.getCcDay()); - cell10.setCellStyle(commonStyle); - Cell cell11 = row.createCell(10); - cell11.setCellValue(sup.getJyDay()); - cell11.setCellStyle(commonStyle); - Cell cell12 = row.createCell(11); - cell12.setCellValue(sup.getRemark()); - cell12.setCellStyle(commonStyle); - } else { - Row row = sheet.createRow(rows); - Cell cell = row.createCell(0); - cell.setCellStyle(commonStyle); - Cell cell1 = row.createCell(1); - cell1.setCellStyle(commonStyle); - Cell cell3 = row.createCell(2); - cell3.setCellStyle(commonStyle); - Cell cell4 = row.createCell(3); - cell4.setCellStyle(commonStyle); - Cell cell5 = row.createCell(4); - cell5.setCellStyle(commonStyle); - Cell cell6 = row.createCell(5); - cell6.setCellValue(sup.getPrice()); - cell6.setCellStyle(commonStyle); - Cell cell7 = row.createCell(6); - cell7.setCellValue(sup.getCgNum()); - cell7.setCellStyle(commonStyle); - Cell cell8 = row.createCell(7); - cell8.setCellValue(sup.getLkNum()); - cell8.setCellStyle(commonStyle); - Cell cell9 = row.createCell(8); - cell9.setCellValue(sup.getSupName()); - cell9.setCellStyle(commonStyle); - Cell cell10 = row.createCell(9); - cell10.setCellValue(sup.getCcDay()); - cell10.setCellStyle(commonStyle); - Cell cell11 = row.createCell(10); - cell11.setCellValue(sup.getJyDay()); - cell11.setCellStyle(commonStyle); - Cell cell12 = row.createCell(11); - cell12.setCellValue(sup.getRemark()); - cell12.setCellStyle(commonStyle); } - rows++; + + // 第一行数据(合并单元格的行) + Row row = sheet.createRow(rows); + // 修复序号:直接用xh(原代码xh-1会导致第一条序号为0) + Cell cell = row.createCell(0); + cell.setCellValue(xh); + cell.setCellStyle(commonStyle); + + Cell cell1 = row.createCell(1); + cell1.setCellValue(details.getName() == null ? "" : details.getName()); + cell1.setCellStyle(commonStyle); + + Cell cell3 = row.createCell(2); + cell3.setCellValue(details.getModel() == null ? "" : details.getModel()); + cell3.setCellStyle(commonStyle); + + Cell cell4 = row.createCell(3); + cell4.setCellValue(details.getUnit() == null ? "" : details.getUnit()); + cell4.setCellStyle(commonStyle); + + Cell cell5 = row.createCell(4); + cell5.setCellValue(details.getNeedNum() == null ? "" : details.getNeedNum()); + cell5.setCellStyle(commonStyle); + + Cell cell6 = row.createCell(5); + cell6.setCellValue(sup.getPrice() == null ? "" : sup.getPrice()); + cell6.setCellStyle(commonStyle); + + Cell cell7 = row.createCell(6); + cell7.setCellValue(sup.getCgNum()); + cell7.setCellStyle(commonStyle); + + Cell cell8 = row.createCell(7); + cell8.setCellValue(sup.getLkNum()); + cell8.setCellStyle(commonStyle); + + Cell cell9 = row.createCell(8); + cell9.setCellValue(sup.getSupName() == null ? "" : sup.getSupName()); + cell9.setCellStyle(commonStyle); + + Cell cell10 = row.createCell(9); + cell10.setCellValue(sup.getCcDay() == null ? "" : sup.getCcDay()); + cell10.setCellStyle(commonStyle); + + Cell cell11 = row.createCell(10); + cell11.setCellValue(sup.getJyDay() == null ? "" : sup.getJyDay()); + cell11.setCellStyle(commonStyle); + + Cell cell12 = row.createCell(11); + cell12.setCellValue(sup.getRemark() == null ? "" : sup.getRemark()); + cell12.setCellStyle(commonStyle); + } else { + // 非第一个供应商行(不需要合并的行) + Row row = sheet.createRow(rows); + // 空单元格保持样式统一 + Cell cell = row.createCell(0); + cell.setCellStyle(commonStyle); + Cell cell1 = row.createCell(1); + cell1.setCellStyle(commonStyle); + Cell cell3 = row.createCell(2); + cell3.setCellStyle(commonStyle); + Cell cell4 = row.createCell(3); + cell4.setCellStyle(commonStyle); + Cell cell5 = row.createCell(4); + cell5.setCellStyle(commonStyle); + + Cell cell6 = row.createCell(5); + cell6.setCellValue(sup.getPrice() == null ? "" : sup.getPrice()); + cell6.setCellStyle(commonStyle); + + Cell cell7 = row.createCell(6); + cell7.setCellValue(sup.getCgNum()); + cell7.setCellStyle(commonStyle); + + Cell cell8 = row.createCell(7); + cell8.setCellValue(sup.getLkNum()); + cell8.setCellStyle(commonStyle); + + Cell cell9 = row.createCell(8); + cell9.setCellValue(sup.getSupName() == null ? "" : sup.getSupName()); + cell9.setCellStyle(commonStyle); + + Cell cell10 = row.createCell(9); + cell10.setCellValue(sup.getCcDay() == null ? "" : sup.getCcDay()); + cell10.setCellStyle(commonStyle); + + Cell cell11 = row.createCell(10); + cell11.setCellValue(sup.getJyDay() == null ? "" : sup.getJyDay()); + cell11.setCellStyle(commonStyle); + + Cell cell12 = row.createCell(11); + cell12.setCellValue(sup.getRemark() == null ? "" : sup.getRemark()); + cell12.setCellStyle(commonStyle); } - + rows++; // 行号递增 } - xh++; - itemNum++; - + xh++; // 序号递增 + itemNum++; // 数据项计数递增 } - //导出 - response.setContentType("application/vnd.ms-excel"); - String fileName = "采购发货明细.xlsx"; + + // 导出Excel(增加空值防护) + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("UTF-8"); + String fileName = URLEncoder.encode("采购发货明细.xlsx", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=\"" + fileName + "\""); OutputStream stream = response.getOutputStream(); - if (wb != null && stream != null) { + if (wb != null) { wb.write(stream); + stream.flush(); + stream.close(); + wb.close(); } } catch (Exception e) { - log.error(e.toString(), e); + log.error("导出采购发货明细异常", e); + // 可选:添加响应异常提示 + try { + response.setContentType("text/plain;charset=UTF-8"); + response.getWriter().write("导出失败:" + e.getMessage()); + } catch (IOException ioException) { + log.error("响应异常信息失败", ioException); + } } }