|
|
|
@ -7,9 +7,24 @@ import com.gaotao.modules.inboundNotification.entity.vo.InboundNotificationHeadV |
|
|
|
import com.gaotao.modules.inboundNotification.service.InboundNotificationService; |
|
|
|
import com.gaotao.modules.sys.controller.AbstractController; |
|
|
|
import com.gaotao.modules.trans.entity.TransDetailSub; |
|
|
|
import org.apache.poi.ss.usermodel.*; |
|
|
|
import org.apache.poi.xssf.usermodel.XSSFCellStyle; |
|
|
|
import org.apache.poi.xssf.usermodel.XSSFColor; |
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.core.io.ClassPathResource; |
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.ResponseEntity; |
|
|
|
import org.springframework.web.bind.annotation.*; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
@ -431,6 +446,223 @@ public class InboundNotificationController extends AbstractController { |
|
|
|
return R.ok().put("rows", list); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 标签导入 |
|
|
|
* 将Excel数据插入临时表,然后调用存储过程处理 |
|
|
|
*/ |
|
|
|
@PostMapping("/labelImport") |
|
|
|
public R labelImport(@RequestParam("file") MultipartFile file, |
|
|
|
@RequestParam("site") String site, |
|
|
|
@RequestParam("buNo") String buNo, |
|
|
|
@RequestParam("orderNo") String orderNo, |
|
|
|
@RequestParam("orderType") String orderType, |
|
|
|
@RequestParam("orderStatus") String orderStatus, |
|
|
|
@RequestParam("relatedOrderNo") String relatedOrderNo, |
|
|
|
@RequestParam("relatedOrderLineNo") String relatedOrderLineNo, |
|
|
|
@RequestParam("partNo") String partNo) { |
|
|
|
try { |
|
|
|
if (file.isEmpty()) { |
|
|
|
return R.error("请选择文件上传"); |
|
|
|
} |
|
|
|
|
|
|
|
// 检查文件格式 |
|
|
|
String fileName = file.getOriginalFilename(); |
|
|
|
if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) { |
|
|
|
return R.error("请上传xlsx或xls格式的文件"); |
|
|
|
} |
|
|
|
|
|
|
|
// 解析Excel文件 |
|
|
|
List<Map<String, Object>> dataList = new ArrayList<>(); |
|
|
|
try (InputStream inputStream = file.getInputStream(); |
|
|
|
Workbook workbook = WorkbookFactory.create(inputStream)) { |
|
|
|
|
|
|
|
Sheet sheet = workbook.getSheetAt(0); |
|
|
|
int lastRowNum = sheet.getLastRowNum(); |
|
|
|
|
|
|
|
// 从第二行开始读取数据(第一行是表头) |
|
|
|
for (int i = 1; i <= lastRowNum; i++) { |
|
|
|
Row row = sheet.getRow(i); |
|
|
|
if (row == null) continue; |
|
|
|
|
|
|
|
Map<String, Object> rowData = new HashMap<>(); |
|
|
|
rowData.put("site", site); |
|
|
|
rowData.put("buNo", buNo); |
|
|
|
rowData.put("orderNo", orderNo); |
|
|
|
rowData.put("orderType", orderType); |
|
|
|
rowData.put("relatedOrderNo", relatedOrderNo); |
|
|
|
rowData.put("relatedOrderLineNo", relatedOrderLineNo); |
|
|
|
rowData.put("partNo", partNo); |
|
|
|
|
|
|
|
// 标签号(第一列) |
|
|
|
Cell rollNoCell = row.getCell(0); |
|
|
|
String rollNo = getCellValueAsString(rollNoCell); |
|
|
|
if (rollNo == null || rollNo.trim().isEmpty()) { |
|
|
|
continue; // 跳过空行 |
|
|
|
} |
|
|
|
rowData.put("rollNo", rollNo.trim()); |
|
|
|
|
|
|
|
// 批次号(第二列) |
|
|
|
Cell batchNoCell = row.getCell(1); |
|
|
|
String batchNo = getCellValueAsString(batchNoCell); |
|
|
|
rowData.put("batchNo", batchNo != null ? batchNo.trim() : ""); |
|
|
|
|
|
|
|
// 数量(第三列) |
|
|
|
Cell rollQtyCell = row.getCell(2); |
|
|
|
BigDecimal rollQty = getCellValueAsDecimal(rollQtyCell); |
|
|
|
rowData.put("rollQty", rollQty); |
|
|
|
|
|
|
|
dataList.add(rowData); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (dataList.isEmpty()) { |
|
|
|
return R.error("Excel文件中没有有效数据"); |
|
|
|
} |
|
|
|
|
|
|
|
// 调用Service处理导入 |
|
|
|
String result = inboundNotificationService.labelImport(site, buNo, orderNo, dataList); |
|
|
|
|
|
|
|
if ("200".equals(result)) { |
|
|
|
return R.ok("导入成功,共导入 " + dataList.size() + " 条数据"); |
|
|
|
} else { |
|
|
|
return R.error("导入失败:" + result); |
|
|
|
} |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("标签导入失败", e); |
|
|
|
return R.error("导入失败: " + e.getMessage()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 下载标签导入模板 |
|
|
|
*/ |
|
|
|
@GetMapping("/downloadLabelTemplate") |
|
|
|
public ResponseEntity<byte[]> downloadLabelTemplate() { |
|
|
|
try { |
|
|
|
// 创建Excel工作簿 |
|
|
|
Workbook workbook = new XSSFWorkbook(); |
|
|
|
Sheet sheet = workbook.createSheet("标签导入模板"); |
|
|
|
|
|
|
|
// // 创建表头样式 |
|
|
|
// CellStyle headerStyle = workbook.createCellStyle(); |
|
|
|
// headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); |
|
|
|
// headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); |
|
|
|
// Font headerFont = workbook.createFont(); |
|
|
|
// headerFont.setBold(true); |
|
|
|
// headerStyle.setFont(headerFont); |
|
|
|
// headerStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
|
|
|
|
// 创建表头样式 |
|
|
|
CellStyle headerStyle = workbook.createCellStyle(); |
|
|
|
XSSFColor headerColor = new XSSFColor(new byte[]{(byte) 0x17, (byte) 0xb3, (byte) 0xa3}, null); |
|
|
|
if (headerStyle instanceof XSSFCellStyle) { |
|
|
|
((XSSFCellStyle) headerStyle).setFillForegroundColor(headerColor); |
|
|
|
} else { |
|
|
|
// 对于HSSFCellStyle,只能使用IndexedColors中的颜色 |
|
|
|
headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); |
|
|
|
} |
|
|
|
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); |
|
|
|
|
|
|
|
Font headerFont = workbook.createFont(); |
|
|
|
headerFont.setBold(true); |
|
|
|
headerStyle.setFont(headerFont); |
|
|
|
headerStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
|
|
|
|
// 创建表头行 |
|
|
|
Row headerRow = sheet.createRow(0); |
|
|
|
String[] headers = {"标签号", "批次号", "数量"}; |
|
|
|
for (int i = 0; i < headers.length; i++) { |
|
|
|
Cell cell = headerRow.createCell(i); |
|
|
|
cell.setCellValue(headers[i]); |
|
|
|
cell.setCellStyle(headerStyle); |
|
|
|
} |
|
|
|
|
|
|
|
// 设置列宽 |
|
|
|
sheet.setColumnWidth(0, 30 * 256); // 标签号 |
|
|
|
sheet.setColumnWidth(1, 20 * 256); // 批次号 |
|
|
|
sheet.setColumnWidth(2, 15 * 256); // 数量 |
|
|
|
|
|
|
|
// 添加示例数据(可选) |
|
|
|
// Row exampleRow = sheet.createRow(1); |
|
|
|
// exampleRow.createCell(0).setCellValue("ROLL001"); |
|
|
|
// exampleRow.createCell(1).setCellValue("BATCH001"); |
|
|
|
// exampleRow.createCell(2).setCellValue(100); |
|
|
|
|
|
|
|
// 将工作簿写入字节数组 |
|
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
|
|
|
workbook.write(outputStream); |
|
|
|
workbook.close(); |
|
|
|
|
|
|
|
byte[] bytes = outputStream.toByteArray(); |
|
|
|
|
|
|
|
HttpHeaders httpHeaders = new HttpHeaders(); |
|
|
|
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); |
|
|
|
httpHeaders.setContentDispositionFormData("attachment", "label_import_template.xlsx"); |
|
|
|
|
|
|
|
return ResponseEntity.ok() |
|
|
|
.headers(httpHeaders) |
|
|
|
.body(bytes); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("下载模板失败", e); |
|
|
|
return ResponseEntity.badRequest().body(null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取单元格字符串值 |
|
|
|
*/ |
|
|
|
private String getCellValueAsString(Cell cell) { |
|
|
|
if (cell == null) return null; |
|
|
|
|
|
|
|
switch (cell.getCellType()) { |
|
|
|
case STRING: |
|
|
|
return cell.getStringCellValue(); |
|
|
|
case NUMERIC: |
|
|
|
if (DateUtil.isCellDateFormatted(cell)) { |
|
|
|
return cell.getDateCellValue().toString(); |
|
|
|
} else { |
|
|
|
// 避免科学计数法 |
|
|
|
double value = cell.getNumericCellValue(); |
|
|
|
if (value == Math.floor(value)) { |
|
|
|
return String.valueOf((long) value); |
|
|
|
} |
|
|
|
return String.valueOf(value); |
|
|
|
} |
|
|
|
case BOOLEAN: |
|
|
|
return String.valueOf(cell.getBooleanCellValue()); |
|
|
|
case FORMULA: |
|
|
|
try { |
|
|
|
return cell.getStringCellValue(); |
|
|
|
} catch (Exception e) { |
|
|
|
return String.valueOf(cell.getNumericCellValue()); |
|
|
|
} |
|
|
|
default: |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取单元格数值 |
|
|
|
*/ |
|
|
|
private BigDecimal getCellValueAsDecimal(Cell cell) { |
|
|
|
if (cell == null) return BigDecimal.ZERO; |
|
|
|
|
|
|
|
switch (cell.getCellType()) { |
|
|
|
case NUMERIC: |
|
|
|
return BigDecimal.valueOf(cell.getNumericCellValue()); |
|
|
|
case STRING: |
|
|
|
try { |
|
|
|
return new BigDecimal(cell.getStringCellValue().trim()); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
return BigDecimal.ZERO; |
|
|
|
} |
|
|
|
default: |
|
|
|
return BigDecimal.ZERO; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|