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 b92d9422..b176b45b 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 @@ -46,6 +46,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.Normalizer; import java.util.*; import java.util.stream.Collectors; @@ -1185,6 +1186,22 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { return false; } + private boolean containsUSAKeyword(String... sourceTexts) { + if (sourceTexts == null || sourceTexts.length == 0) { + return false; + } + for (String sourceText : sourceTexts) { + if (StringUtils.isBlank(sourceText)) { + continue; + } + String normalizedText = normalizeCountryCompareText(sourceText); + if (normalizedText.contains("USA") || normalizedText.contains("美国")) { + return true; + } + } + return false; + } + private boolean isUsaCanadaPackageUnitBu(String buNo) { if (StringUtils.isBlank(buNo)) { return false; @@ -2150,14 +2167,14 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { for (int i = 0; i < asposeWorkbook.getWorksheets().getCount(); i++) { com.aspose.cells.Worksheet worksheet = asposeWorkbook.getWorksheets().get(i); PageSetup pageSetup = worksheet.getPageSetup(); - boolean isPackingListSheet = i == 1||i==0; + boolean isPackingListOrInvoiceSheet = i == 1||i==0; // 设置页面方向(纵向) pageSetup.setOrientation(i==2? PageOrientationType.LANDSCAPE:PageOrientationType.PORTRAIT); // 设置纸张大小(A4) pageSetup.setPaperSize(PaperSizeType.PAPER_A_4); - if (isPackingListSheet) { - // 箱单数据较多时,强制缩放到单页(宽1页*高1页) + if (isPackingListOrInvoiceSheet) { + // 发票和箱单数据较多时,强制缩放到单页(宽1页*高1页) pageSetup.setFitToPagesWide(1); pageSetup.setFitToPagesTall(1); } else { @@ -2554,20 +2571,25 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { Map eorder = ndList.get(i); eorder.put("row_num", i + 1); // 构建designation内容 - String designationContent = eorder.get("part_description") + "\n" - + "PO#" + eorder.get("customerPO")+ (data.getHsCodeFlag()!=null && data.getHsCodeFlag()?" HS CODE#" + eorder.get("hsCode"):""); + String designationContent = sanitizePdfRenderText(eorder.get("part_description")) + "\n" + + "PO#" + sanitizePdfRenderText(eorder.get("customerPO")) + + (data.getHsCodeFlag()!=null && data.getHsCodeFlag() ? " HS CODE#" + sanitizePdfRenderText(eorder.get("hsCode")) : ""); if ("02-Hardtag".equalsIgnoreCase(notifyHeader.getBuNo()) || "05-Alpha".equalsIgnoreCase(notifyHeader.getBuNo())){ - designationContent = eorder.get("part_description") + "\n" - + " PO:" + eorder.get("customerPO")+ (data.getHsCodeFlag()!=null && data.getHsCodeFlag()?" HS CODE:" + eorder.get("hsCode"):""); + designationContent = sanitizePdfRenderText(eorder.get("part_description")) + "\n" + + " PO:" + sanitizePdfRenderText(eorder.get("customerPO")) + + (data.getHsCodeFlag()!=null && data.getHsCodeFlag() ? " HS CODE:" + sanitizePdfRenderText(eorder.get("hsCode")) : ""); } if (notifyHeader.getBuNo().equals("04-MHM")) { - designationContent = designationContent + "\n"+(data.getHsCodeDescType()!=null&& data.getHsCodeDescType().equals("N") - ?(eorder.get("hsCodeDescEn")!=null?eorder.get("hsCodeDescEn"):"") :(eorder.get("hsCodeDesc")!=null?eorder.get("hsCodeDesc"):"")); + designationContent = designationContent + "\n" + sanitizePdfRenderText( + data.getHsCodeDescType()!=null && data.getHsCodeDescType().equals("N") + ? (eorder.get("hsCodeDescEn")!=null ? eorder.get("hsCodeDescEn") : "") + : (eorder.get("hsCodeDesc")!=null ? eorder.get("hsCodeDesc") : "") + ); } eorder.put("designation", designationContent); // 计算designation内容的行数,动态设置行高 - int lineCount = calculateLineCount(designationContent); + int lineCount = calculateLineCount(designationContent, 42); // 基础行高16点 + 每额外行增加15点(可根据实际字体大小调整) int rowHeight = 16 + (lineCount - 1) * 15; // 设置当前行的行高(ndList的当前索引) @@ -2736,12 +2758,16 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { eorder.put("net_weight",isFirstRow ? ((BigDecimal) list.get(m).get("net_weight")).setScale(2, RoundingMode.HALF_UP) : ""); // 构建artNo内容 - String artNoContent = eorder.get("pn")+" " + eorder.get("part_description") + "\n" - + " PO#" + eorder.get("po_no") + - (data.getHsCodeFlag()!=null && data.getHsCodeFlag()?" HS CODE#" + eorder.get("hsCode"):""); + String artNoContent = sanitizePdfRenderText(eorder.get("pn")) + " " + + sanitizePdfRenderText(eorder.get("part_description")) + "\n" + + " PO#" + sanitizePdfRenderText(eorder.get("po_no")) + + (data.getHsCodeFlag()!=null && data.getHsCodeFlag() ? " HS CODE#" + sanitizePdfRenderText(eorder.get("hsCode")) : ""); if (notifyHeader.getBuNo().equals("04-MHM")) { - artNoContent = artNoContent + "\n"+(data.getHsCodeDescType()!=null&& data.getHsCodeDescType().equals("N") - ?(eorder.get("hsCodeDescEn")!=null?eorder.get("hsCodeDescEn"):"") :eorder.get("hsCodeDesc")); + artNoContent = artNoContent + "\n" + sanitizePdfRenderText( + data.getHsCodeDescType()!=null&& data.getHsCodeDescType().equals("N") + ? (eorder.get("hsCodeDescEn")!=null ? eorder.get("hsCodeDescEn") : "") + : eorder.get("hsCodeDesc") + ); } eorder.put("artNo", artNoContent); // 计算artNo内容的行数,动态设置行高 @@ -3007,12 +3033,13 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { eorder.put("net_weight", isFirstRow ? ((BigDecimal) list.get(m).get("net_weight")).setScale(2, RoundingMode.HALF_UP) : ""); // 构建artNo内容 - String artNoContent = eorder.get("pn")+" " + eorder.get("part_description") + "\n" - + " PO:" + eorder.get("po_no") + - (data.getHsCodeFlag()!=null && data.getHsCodeFlag()?" HS CODE:" + eorder.get("hsCode"):""); + String artNoContent = sanitizePdfRenderText(eorder.get("pn")) + " " + + sanitizePdfRenderText(eorder.get("part_description")) + "\n" + + " PO:" + sanitizePdfRenderText(eorder.get("po_no")) + + (data.getHsCodeFlag()!=null && data.getHsCodeFlag() ? " HS CODE:" + sanitizePdfRenderText(eorder.get("hsCode")) : ""); eorder.put("artNo", artNoContent); // 计算artNo内容的行数,动态设置行高 - int lineCount = calculateLineCount(artNoContent); + int lineCount = calculateLineCount(artNoContent, 42); // 基础行高16点 + 每额外行增加15点(可根据实际字体大小调整) int rowHeight = 16 + (lineCount - 1) * 15; // 设置当前行的行高(exportList的当前索引) @@ -3273,9 +3300,9 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { eorder.put("net_weight", isFirstRow ? ((BigDecimal) list.get(m).get("net_weight")).setScale(2, RoundingMode.HALF_UP) : ""); // 构建artNo内容 - String artNoContent = eorder.get("part_description") + "\n" - + " PO:" + eorder.get("po_no") + - (data.getHsCodeFlag()!=null && data.getHsCodeFlag()?" HS CODE:" + eorder.get("hsCode"):""); + String artNoContent = sanitizePdfRenderText(eorder.get("part_description")) + "\n" + + " PO:" + sanitizePdfRenderText(eorder.get("po_no")) + + (data.getHsCodeFlag()!=null && data.getHsCodeFlag() ? " HS CODE:" + sanitizePdfRenderText(eorder.get("hsCode")) : ""); eorder.put("artNo", artNoContent); // 计算artNo内容的行数,动态设置行高 int lineCount = calculateLineCount(artNoContent); @@ -3464,10 +3491,10 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { boolean showInvoiceFlag = data != null && Boolean.TRUE.equals(data.getShowInvoiceFlag()); String poNoDisplayText = formatPoNoForDisplay(poNoSet); if (isShowOrderNoBu(buNo)) { - poNoDisplayText = showOrderNoFlag ? formatPoNoForHwDesc(poNoSet) : ""; + poNoDisplayText = showOrderNoFlag ? "PO#"+formatPoNoForHwDesc(poNoSet) : ""; } String hsCodeDescText = "N".equals(bookingHsCodeDescType) ? sbEn : sb; - String hwDescText = hsCodeDescText + "\nPO#" + poNoDisplayText; + String hwDescText = hsCodeDescText + "\n" + poNoDisplayText; if (isShowOrderNoBu(buNo) && showInvoiceFlag) { String cmcInvoiceText = stringInput(notifyHeader.getCmcInvoice()); if (StringUtils.isBlank(poNoDisplayText)) { @@ -3477,6 +3504,8 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { } } template.addVar("hw_desc", hwDescText); + template.addVar("hwmc", containsUSAKeyword(notifyHeader.getDestination())?"Anti-theft systems and their accessories" + :"Part of against shoplifting systems"); template.addVar("shipping_port", stringInput(notifyHeader.getCnative())); template.addVar("cmc_invoice", stringInput(notifyHeader.getCmcInvoice())); // 导出时默认,可编辑的栏目 @@ -3927,4 +3956,26 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService { return Math.max(1, totalLines); } + /** + * PDF渲染前统一清洗字符串,去除不可见字符,避免Aspose触发字体回退导致个别行发暗。 + */ + private String sanitizePdfRenderText(Object value) { + if (value == null) { + return ""; + } + String text = String.valueOf(value); + if (StringUtils.isBlank(text)) { + return ""; + } + String normalized = Normalizer.normalize(text, Normalizer.Form.NFKC) + .replace("\r\n", "\n") + .replace("\r", "\n") + .replace('\u00A0', ' ') + .replace('\u3000', ' '); + // 清理格式字符(如零宽空格)与控制字符(保留换行和Tab) + normalized = normalized.replaceAll("\\p{Cf}", ""); + normalized = normalized.replaceAll("[\\p{Cntrl}&&[^\\n\\t]]", ""); + return normalized; + } + } diff --git a/src/main/resources/templates/TX/declaration-all-template.xlsx b/src/main/resources/templates/TX/declaration-all-template.xlsx index 27f7872e..cf642364 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/export-goods-template.xlsx b/src/main/resources/templates/TX/export-goods-template.xlsx index 24621f12..b762b072 100644 Binary files a/src/main/resources/templates/TX/export-goods-template.xlsx and b/src/main/resources/templates/TX/export-goods-template.xlsx differ