diff --git a/src/main/java/com/xujie/sys/common/utils/ExcelTemplateALPHA.java b/src/main/java/com/xujie/sys/common/utils/ExcelTemplateALPHA.java index da779051..4d442566 100644 --- a/src/main/java/com/xujie/sys/common/utils/ExcelTemplateALPHA.java +++ b/src/main/java/com/xujie/sys/common/utils/ExcelTemplateALPHA.java @@ -9,6 +9,7 @@ import org.apache.poi.xssf.usermodel.*; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -49,6 +50,9 @@ public class ExcelTemplateALPHA { // 发票价格列是否使用固定小数位(单价5位、总价2位) @Setter private boolean fixedInvoicePriceScale = false; + // 报关单价格列是否固定两位小数(净重/单价/总价) + @Setter + private boolean fixedDeclarationPriceScale = false; // 数字靠右 箱单 @Setter private boolean intRight = false; @@ -146,6 +150,7 @@ public class ExcelTemplateALPHA { rangeStyle = false; priceRight = false; fixedInvoicePriceScale = false; + fixedDeclarationPriceScale = false; intRight = false; delRight = false; } @@ -296,6 +301,8 @@ public class ExcelTemplateALPHA { Set poNoCols = new HashSet<>(); Set invoiceUnitPriceCols = new HashSet<>(); Set invoiceTotalPriceCols = new HashSet<>(); + Set declarationFixedPriceCols = new HashSet<>(); + Set declarationQtyCols = new HashSet<>(); //整体填值 for (int i = 0; i <= sheet.getLastRowNum(); i++) { XSSFRow row = sheet.getRow(i); @@ -327,6 +334,10 @@ public class ExcelTemplateALPHA { invoiceUnitPriceCols.add(j); } else if (isInvoiceTotalPriceField(dtlField)) { invoiceTotalPriceCols.add(j); + } else if (isDeclarationFixedPriceField(dtlField)) { + declarationFixedPriceCols.add(j); + } else if (isDeclarationQtyField(dtlField)) { + declarationQtyCols.add(j); } } } @@ -614,19 +625,23 @@ public class ExcelTemplateALPHA { style.setVerticalAlignment(VerticalAlignment.CENTER); style.setAlignment(HorizontalAlignment.LEFT); c7.setCellStyle(style); - if (i==6 || i==11) { - // 尝试把字符串转成数值 + boolean declarationFixedTwoScaleColumn = fixedDeclarationPriceScale && declarationFixedPriceCols.contains(i); + boolean declarationQtyColumn = fixedDeclarationPriceScale && declarationQtyCols.contains(i); + boolean declarationNumberColumn = fixedDeclarationPriceScale + ? (declarationFixedTwoScaleColumn || declarationQtyColumn) + : (i == 6 || i == 11); + if (declarationNumberColumn) { + BigDecimal numericValue = null; if (c7.getCellType() == CellType.STRING) { - String strVal = c7.getStringCellValue(); - if (strVal != null && !strVal.trim().isEmpty()) { - try { - double num = Double.parseDouble(strVal.replace(",", "")); - c7.setCellValue(num); // 转换为数值写回 - } catch (NumberFormatException e) { - // 如果不是数字就保留原字符串 - System.out.println("非数字,保持原值: " + strVal); - } + numericValue = parseNumericString(c7.getStringCellValue()); + } else if (c7.getCellType() == CellType.NUMERIC) { + numericValue = BigDecimal.valueOf(c7.getNumericCellValue()); + } + if (numericValue != null) { + if (declarationFixedTwoScaleColumn) { + numericValue = numericValue.setScale(2, RoundingMode.HALF_UP); } + c7.setCellValue(numericValue.doubleValue()); } // 创建样式 XSSFCellStyle style7 = workbook.createCellStyle(); @@ -642,9 +657,16 @@ public class ExcelTemplateALPHA { style7.setAlignment(HorizontalAlignment.RIGHT); // 设置千分位格式(根据单元格实际小数位动态决定格式) DataFormat dataFormat = workbook.createDataFormat(); - String numFmt3 = (c7.getCellType() == CellType.NUMERIC) - ? buildDecimalFormat(c7.getNumericCellValue()) - : "#,##0.00"; + String numFmt3; + if (declarationFixedTwoScaleColumn) { + numFmt3 = "#,##0.00"; + } else if (declarationQtyColumn) { + numFmt3 = "#,##0"; + } else if (c7.getCellType() == CellType.NUMERIC) { + numFmt3 = buildDecimalFormat(c7.getNumericCellValue()); + } else { + numFmt3 = "#,##0.00"; + } style7.setDataFormat(dataFormat.getFormat(numFmt3)); c7.setCellStyle(style7); } @@ -883,6 +905,16 @@ public class ExcelTemplateALPHA { return "totalPrice".equalsIgnoreCase(field) || "ttl_amount".equalsIgnoreCase(field); } + private boolean isDeclarationFixedPriceField(String field) { + return "net_weight".equalsIgnoreCase(field) + || "unit_price".equalsIgnoreCase(field) + || "total_price".equalsIgnoreCase(field); + } + + private boolean isDeclarationQtyField(String field) { + return "qty".equalsIgnoreCase(field); + } + private BigDecimal parseNumericString(String value) { if (value == null) { return null; diff --git a/src/main/java/com/xujie/sys/common/utils/ExcelTemplateTX.java b/src/main/java/com/xujie/sys/common/utils/ExcelTemplateTX.java index c1327d37..34c51438 100644 --- a/src/main/java/com/xujie/sys/common/utils/ExcelTemplateTX.java +++ b/src/main/java/com/xujie/sys/common/utils/ExcelTemplateTX.java @@ -9,6 +9,7 @@ import org.apache.poi.xssf.usermodel.*; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -49,6 +50,12 @@ public class ExcelTemplateTX { // 发票价格列是否使用固定小数位(单价5位、总价2位) @Setter private boolean fixedInvoicePriceScale = false; + // 报关单价格列是否固定两位小数(净重/单价/总价) + @Setter + private boolean fixedDeclarationPriceScale = false; + // 箱单体积/净重是否固定小数位(体积3位、净重2位) + @Setter + private boolean fixedPackingVolumeWeightScale = false; // 数字靠右 箱单 @Setter private boolean intRight = false; @@ -146,6 +153,8 @@ public class ExcelTemplateTX { rangeStyle = false; priceRight = false; fixedInvoicePriceScale = false; + fixedDeclarationPriceScale = false; + fixedPackingVolumeWeightScale = false; intRight = false; delRight = false; } @@ -297,6 +306,10 @@ public class ExcelTemplateTX { List boxRows = new ArrayList<>(); Set invoiceUnitPriceCols = new HashSet<>(); Set invoiceTotalPriceCols = new HashSet<>(); + Set declarationFixedPriceCols = new HashSet<>(); + Set declarationQtyCols = new HashSet<>(); + Set packingVolumeCols = new HashSet<>(); + Set packingNetWeightCols = new HashSet<>(); //整体填值 for (int i = 0; i <= sheet.getLastRowNum(); i++) { XSSFRow row = sheet.getRow(i); @@ -322,9 +335,22 @@ public class ExcelTemplateTX { String dtlField = matcherDtlField.group(1); if (isInvoiceUnitPriceField(dtlField)) { invoiceUnitPriceCols.add(j); - } else if (isInvoiceTotalPriceField(dtlField)) { + } + if (isInvoiceTotalPriceField(dtlField)) { invoiceTotalPriceCols.add(j); } + if (isDeclarationFixedPriceField(dtlField)) { + declarationFixedPriceCols.add(j); + } + if (isDeclarationQtyField(dtlField)) { + declarationQtyCols.add(j); + } + if (isPackingVolumeField(dtlField)) { + packingVolumeCols.add(j); + } + if (isPackingNetWeightField(dtlField)) { + packingNetWeightCols.add(j); + } } } Matcher matcherHdr = PATTERN_HDR_FIELD.matcher(cellValue); @@ -527,6 +553,11 @@ public class ExcelTemplateTX { } else if (c7.getCellType() == CellType.NUMERIC) { numericValue = BigDecimal.valueOf(c7.getNumericCellValue()); } + boolean fixedPackingVolumeColumn = fixedPackingVolumeWeightScale && packingVolumeCols.contains(i); + if (fixedPackingVolumeColumn && numericValue != null) { + numericValue = numericValue.setScale(3, RoundingMode.HALF_UP); + c7.setCellValue(numericValue.doubleValue()); + } // 创建样式 XSSFCellStyle style7 = workbook.createCellStyle(); @@ -554,7 +585,9 @@ public class ExcelTemplateTX { // 设置千分位格式(根据单元格实际小数位动态决定格式) DataFormat dataFormat = workbook.createDataFormat(); String numFmt2; - if (numericValue != null) { + if (fixedPackingVolumeColumn) { + numFmt2 = "#,##0.000"; + } else if (numericValue != null) { // 去掉末尾0后按实际小数位显示:20.000000 -> 20,0.150000 -> 0.15 numFmt2 = buildDecimalFormatByDecimal(numericValue); } else if (c7.getCellType() == CellType.NUMERIC) { @@ -571,10 +604,27 @@ public class ExcelTemplateTX { if (row != null) { XSSFCell netWeightCell = row.getCell(9); if (netWeightCell != null) { + boolean fixedPackingNetWeightColumn = fixedPackingVolumeWeightScale && packingNetWeightCols.contains(9); + if (fixedPackingNetWeightColumn) { + BigDecimal netWeightValue = null; + if (netWeightCell.getCellType() == CellType.STRING) { + netWeightValue = parseNumericString(netWeightCell.getStringCellValue()); + } else if (netWeightCell.getCellType() == CellType.NUMERIC) { + netWeightValue = BigDecimal.valueOf(netWeightCell.getNumericCellValue()); + } + if (netWeightValue != null) { + netWeightValue = netWeightValue.setScale(2, RoundingMode.HALF_UP); + netWeightCell.setCellValue(netWeightValue.doubleValue()); + } + } XSSFCellStyle netWeightStyle = workbook.createCellStyle(); netWeightStyle.cloneStyleFrom(netWeightCell.getCellStyle()); netWeightStyle.setVerticalAlignment(VerticalAlignment.TOP); netWeightStyle.setAlignment(HorizontalAlignment.RIGHT); + if (fixedPackingNetWeightColumn) { + DataFormat dataFormat = workbook.createDataFormat(); + netWeightStyle.setDataFormat(dataFormat.getFormat("#,##0.00")); + } netWeightCell.setCellStyle(netWeightStyle); } } @@ -605,19 +655,23 @@ public class ExcelTemplateTX { style.setVerticalAlignment(VerticalAlignment.CENTER); style.setAlignment(HorizontalAlignment.LEFT); c7.setCellStyle(style); - if (i==6 || i==11) { - // 尝试把字符串转成数值 + boolean declarationFixedTwoScaleColumn = fixedDeclarationPriceScale && declarationFixedPriceCols.contains(i); + boolean declarationQtyColumn = fixedDeclarationPriceScale && declarationQtyCols.contains(i); + boolean declarationNumberColumn = fixedDeclarationPriceScale + ? (declarationFixedTwoScaleColumn || declarationQtyColumn) + : (i == 6 || i == 11); + if (declarationNumberColumn) { + BigDecimal numericValue = null; if (c7.getCellType() == CellType.STRING) { - String strVal = c7.getStringCellValue(); - if (strVal != null && !strVal.trim().isEmpty()) { - try { - double num = Double.parseDouble(strVal.replace(",", "")); - c7.setCellValue(num); // 转换为数值写回 - } catch (NumberFormatException e) { - // 如果不是数字就保留原字符串 - System.out.println("非数字,保持原值: " + strVal); - } + numericValue = parseNumericString(c7.getStringCellValue()); + } else if (c7.getCellType() == CellType.NUMERIC) { + numericValue = BigDecimal.valueOf(c7.getNumericCellValue()); + } + if (numericValue != null) { + if (declarationFixedTwoScaleColumn) { + numericValue = numericValue.setScale(2, RoundingMode.HALF_UP); } + c7.setCellValue(numericValue.doubleValue()); } // 创建样式 XSSFCellStyle style7 = workbook.createCellStyle(); @@ -633,9 +687,16 @@ public class ExcelTemplateTX { style7.setAlignment(HorizontalAlignment.RIGHT); // 设置千分位格式(根据单元格实际小数位动态决定格式) DataFormat dataFormat = workbook.createDataFormat(); - String numFmt3 = (c7.getCellType() == CellType.NUMERIC) - ? buildDecimalFormat(c7.getNumericCellValue()) - : "#,##0.00"; + String numFmt3; + if (declarationFixedTwoScaleColumn) { + numFmt3 = "#,##0.00"; + } else if (declarationQtyColumn) { + numFmt3 = "#,##0"; + } else if (c7.getCellType() == CellType.NUMERIC) { + numFmt3 = buildDecimalFormat(c7.getNumericCellValue()); + } else { + numFmt3 = "#,##0.00"; + } style7.setDataFormat(dataFormat.getFormat(numFmt3)); c7.setCellStyle(style7); } @@ -874,6 +935,24 @@ public class ExcelTemplateTX { return "totalPrice".equalsIgnoreCase(field) || "ttl_amount".equalsIgnoreCase(field); } + private boolean isDeclarationFixedPriceField(String field) { + return "net_weight".equalsIgnoreCase(field) + || "unit_price".equalsIgnoreCase(field) + || "total_price".equalsIgnoreCase(field); + } + + private boolean isDeclarationQtyField(String field) { + return "qty".equalsIgnoreCase(field); + } + + private boolean isPackingVolumeField(String field) { + return "volume".equalsIgnoreCase(field); + } + + private boolean isPackingNetWeightField(String field) { + return "net_weight".equalsIgnoreCase(field); + } + private BigDecimal parseNumericString(String value) { if (value == null) { return null; diff --git a/src/main/java/com/xujie/sys/common/utils/ExcelTemplateYB.java b/src/main/java/com/xujie/sys/common/utils/ExcelTemplateYB.java index a02c503b..25350be0 100644 --- a/src/main/java/com/xujie/sys/common/utils/ExcelTemplateYB.java +++ b/src/main/java/com/xujie/sys/common/utils/ExcelTemplateYB.java @@ -9,6 +9,7 @@ import org.apache.poi.xssf.usermodel.*; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -49,6 +50,9 @@ public class ExcelTemplateYB { // 发票价格列是否使用固定小数位(单价5位、总价2位) @Setter private boolean fixedInvoicePriceScale = false; + // 报关单价格列是否固定两位小数(净重/单价/总价) + @Setter + private boolean fixedDeclarationPriceScale = false; // 数字靠右 箱单 @Setter private boolean intRight = false; @@ -146,6 +150,7 @@ public class ExcelTemplateYB { rangeStyle = false; priceRight = false; fixedInvoicePriceScale = false; + fixedDeclarationPriceScale = false; intRight = false; delRight = false; } @@ -298,6 +303,8 @@ public class ExcelTemplateYB { Set poNoCols = new HashSet<>(); Set invoiceUnitPriceCols = new HashSet<>(); Set invoiceTotalPriceCols = new HashSet<>(); + Set declarationFixedPriceCols = new HashSet<>(); + Set declarationQtyCols = new HashSet<>(); //整体填值 for (int i = 0; i <= sheet.getLastRowNum(); i++) { XSSFRow row = sheet.getRow(i); @@ -329,6 +336,10 @@ public class ExcelTemplateYB { invoiceUnitPriceCols.add(j); } else if (isInvoiceTotalPriceField(dtlField)) { invoiceTotalPriceCols.add(j); + } else if (isDeclarationFixedPriceField(dtlField)) { + declarationFixedPriceCols.add(j); + } else if (isDeclarationQtyField(dtlField)) { + declarationQtyCols.add(j); } } } @@ -616,19 +627,23 @@ public class ExcelTemplateYB { style.setVerticalAlignment(VerticalAlignment.CENTER); style.setAlignment(HorizontalAlignment.LEFT); c7.setCellStyle(style); - if (i==6 || i==11) { - // 尝试把字符串转成数值 + boolean declarationFixedTwoScaleColumn = fixedDeclarationPriceScale && declarationFixedPriceCols.contains(i); + boolean declarationQtyColumn = fixedDeclarationPriceScale && declarationQtyCols.contains(i); + boolean declarationNumberColumn = fixedDeclarationPriceScale + ? (declarationFixedTwoScaleColumn || declarationQtyColumn) + : (i == 6 || i == 11); + if (declarationNumberColumn) { + BigDecimal numericValue = null; if (c7.getCellType() == CellType.STRING) { - String strVal = c7.getStringCellValue(); - if (strVal != null && !strVal.trim().isEmpty()) { - try { - double num = Double.parseDouble(strVal.replace(",", "")); - c7.setCellValue(num); // 转换为数值写回 - } catch (NumberFormatException e) { - // 如果不是数字就保留原字符串 - System.out.println("非数字,保持原值: " + strVal); - } + numericValue = parseNumericString(c7.getStringCellValue()); + } else if (c7.getCellType() == CellType.NUMERIC) { + numericValue = BigDecimal.valueOf(c7.getNumericCellValue()); + } + if (numericValue != null) { + if (declarationFixedTwoScaleColumn) { + numericValue = numericValue.setScale(2, RoundingMode.HALF_UP); } + c7.setCellValue(numericValue.doubleValue()); } // 创建样式 XSSFCellStyle style7 = workbook.createCellStyle(); @@ -644,9 +659,16 @@ public class ExcelTemplateYB { style7.setAlignment(HorizontalAlignment.RIGHT); // 设置千分位格式(根据单元格实际小数位动态决定格式) DataFormat dataFormat = workbook.createDataFormat(); - String numFmt3 = (c7.getCellType() == CellType.NUMERIC) - ? buildDecimalFormat(c7.getNumericCellValue()) - : "#,##0.00"; + String numFmt3; + if (declarationFixedTwoScaleColumn) { + numFmt3 = "#,##0.00"; + } else if (declarationQtyColumn) { + numFmt3 = "#,##0"; + } else if (c7.getCellType() == CellType.NUMERIC) { + numFmt3 = buildDecimalFormat(c7.getNumericCellValue()); + } else { + numFmt3 = "#,##0.00"; + } style7.setDataFormat(dataFormat.getFormat(numFmt3)); c7.setCellStyle(style7); } @@ -885,6 +907,16 @@ public class ExcelTemplateYB { return "totalPrice".equalsIgnoreCase(field) || "ttl_amount".equalsIgnoreCase(field); } + private boolean isDeclarationFixedPriceField(String field) { + return "net_weight".equalsIgnoreCase(field) + || "unit_price".equalsIgnoreCase(field) + || "total_price".equalsIgnoreCase(field); + } + + private boolean isDeclarationQtyField(String field) { + return "qty".equalsIgnoreCase(field); + } + private BigDecimal parseNumericString(String value) { if (value == null) { return null; diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java index 94628467..e5df8332 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java @@ -974,6 +974,16 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { || "02-Hardtag".equalsIgnoreCase(buNoTrim); } + /** + * 当前“天线”BU仅对 04-MHM 做报关单数值格式特殊处理。 + */ + private boolean isAntennaBu(String buNo) { + if (StringUtils.isBlank(buNo)) { + return false; + } + return "04-MHM".equalsIgnoreCase(buNo.trim()); + } + private String buildDefaultVoyage(EcssCoDelNotifyHeaderData notifyHeader) { if (notifyHeader == null) { return ""; @@ -1095,6 +1105,8 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { void setFixedInvoicePriceScale(boolean fixedInvoicePriceScale); + void setFixedDeclarationPriceScale(boolean fixedDeclarationPriceScale); + void addVar(String key, Object value); void addListVarAll(Collection rows); @@ -1154,6 +1166,11 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { delegate.setFixedInvoicePriceScale(fixedInvoicePriceScale); } + @Override + public void setFixedDeclarationPriceScale(boolean fixedDeclarationPriceScale) { + delegate.setFixedDeclarationPriceScale(fixedDeclarationPriceScale); + } + @Override public void addVar(String key, Object value) { delegate.addVar(key, value); @@ -1222,6 +1239,11 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { delegate.setFixedInvoicePriceScale(fixedInvoicePriceScale); } + @Override + public void setFixedDeclarationPriceScale(boolean fixedDeclarationPriceScale) { + delegate.setFixedDeclarationPriceScale(fixedDeclarationPriceScale); + } + @Override public void addVar(String key, Object value) { delegate.addVar(key, value); @@ -1290,6 +1312,11 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { delegate.setFixedInvoicePriceScale(fixedInvoicePriceScale); } + @Override + public void setFixedDeclarationPriceScale(boolean fixedDeclarationPriceScale) { + delegate.setFixedDeclarationPriceScale(fixedDeclarationPriceScale); + } + @Override public void addVar(String key, Object value) { delegate.addVar(key, value); @@ -1820,6 +1847,7 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { template.addVar("documents", stringInput(ecHeader.getDocuments())); template.addVar("packageType", stringInput(ecHeader.getPackageType())); EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(data.getSite(), data.getDelNo()); + template.setFixedDeclarationPriceScale(notifyHeader != null && isAntennaBu(notifyHeader.getBuNo())); List palletHeaderDataList = coDelMapper.searchEcssCoDelPalletHeaderData(notifyHeader); // 总托数 Integer totalPlt = palletHeaderDataList.stream() @@ -2211,6 +2239,7 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { template.setRangeStyle(true); template.setMoveSeal(true); template.setIntRight(true); + template.setFixedPackingVolumeWeightScale(isAntennaBu(notifyHeader.getBuNo())); if (notifyHeader.getBuNo().equals("03-RFID") || notifyHeader.getBuNo().equals("01-Label")){ template.setCellStyle2(true); } diff --git a/src/main/resources/templates/TX/declaration-all-template.xlsx b/src/main/resources/templates/TX/declaration-all-template.xlsx index 9d687fe2..9a0f01c9 100644 Binary files a/src/main/resources/templates/TX/declaration-all-template.xlsx and b/src/main/resources/templates/TX/declaration-all-template.xlsx differ diff --git a/src/main/resources/templates/TX/declaration-invoice2-template.xlsx b/src/main/resources/templates/TX/declaration-invoice2-template.xlsx index c15dfb12..81df4803 100644 Binary files a/src/main/resources/templates/TX/declaration-invoice2-template.xlsx and b/src/main/resources/templates/TX/declaration-invoice2-template.xlsx differ