|
|
|
@ -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<Integer> boxRows = new ArrayList<>(); |
|
|
|
Set<Integer> invoiceUnitPriceCols = new HashSet<>(); |
|
|
|
Set<Integer> invoiceTotalPriceCols = new HashSet<>(); |
|
|
|
Set<Integer> declarationFixedPriceCols = new HashSet<>(); |
|
|
|
Set<Integer> declarationQtyCols = new HashSet<>(); |
|
|
|
Set<Integer> packingVolumeCols = new HashSet<>(); |
|
|
|
Set<Integer> 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; |
|
|
|
|