Browse Source

模版样式

master
han\hanst 1 week ago
parent
commit
f63ad484b4
  1. 37
      src/main/java/com/xujie/sys/common/utils/ExcelTemplateTX.java
  2. 259
      src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java
  3. 20
      src/main/resources/mapper/ecss/CoDelMapper.xml
  4. BIN
      src/main/resources/templates/ALPHA/declaration-all-template.xlsx
  5. BIN
      src/main/resources/templates/TX/declaration-all-template.xlsx

37
src/main/java/com/xujie/sys/common/utils/ExcelTemplateTX.java

@ -146,6 +146,38 @@ public class ExcelTemplateTX {
delRight = false;
}
private void applyMultilineStyleIfNeeded(XSSFCell cell, String content) {
if (cell == null || content == null || !content.contains("\n")) {
return;
}
XSSFCellStyle baseStyle = cell.getCellStyle();
XSSFCellStyle multilineStyle = workbook.createCellStyle();
if (baseStyle != null) {
multilineStyle.cloneStyleFrom(baseStyle);
}
multilineStyle.setWrapText(true);
multilineStyle.setVerticalAlignment(VerticalAlignment.TOP);
cell.setCellStyle(multilineStyle);
XSSFRow row = cell.getRow();
if (row == null) {
return;
}
int lineCount = content.split("\n", -1).length;
if (lineCount <= 1) {
return;
}
float defaultRowHeight = row.getSheet().getDefaultRowHeightInPoints();
float currentRowHeight = row.getHeightInPoints();
float targetHeight = Math.max(currentRowHeight, defaultRowHeight * lineCount);
if (targetHeight > currentRowHeight) {
row.setHeightInPoints(targetHeight);
}
}
private boolean findAndRemoveMergedRegion(XSSFSheet sheet, int rowIndex) {
for (int mi = 0; mi < sheet.getMergedRegions().size(); mi++) {
if (sheet.getMergedRegions().get(mi).getFirstRow() == rowIndex) {
@ -280,7 +312,9 @@ public class ExcelTemplateTX {
}
Matcher matcherHdr = PATTERN_HDR_FIELD.matcher(cellValue);
String result = c.getStringCellValue();
boolean hasHeaderPlaceholder = false;
while (matcherHdr.find()) {
hasHeaderPlaceholder = true;
for (int ri = 1; ri <= matcherHdr.groupCount(); ri++) {
String field = matcherHdr.group(ri);
Object value = variables.getOrDefault(field, "");
@ -315,6 +349,9 @@ public class ExcelTemplateTX {
}
}
}
if (hasHeaderPlaceholder) {
applyMultilineStyleIfNeeded(c, result);
}
Matcher matcherDtl = PATTERN_DTL_FIELD.matcher(cellValue);
while (matcherDtl.find()) {

259
src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelTXServiceImpl.java

@ -56,6 +56,14 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
@Autowired
private PlatformTransactionManager transactionManager;
/**
* TX导入固定必填表头必须全部存在
*/
private static final List<String> TX_REQUIRED_FIXED_HEADERS = Arrays.asList(
"发票号", "发票序号", "客户", "可提货时间", "发运方式", "目的地",
"PO", "ERP编码", "HS Code", "申报品名", "名称",
"Currency", "TP", "Total Revanue", "托数", "总体积", "净重", "毛重", "箱数","Qty"
);
@Override
public Map<String, Object> previewExcelTX(MultipartFile file, EcssCoDelNotifyHeaderData inData) {
String site = coDelMapper.getSiteByBu(inData.getBuNo());
@ -75,7 +83,17 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
previewList.add(summary);
}
} catch (Exception e) {
sheetErrors.add(SheetErrorInfo.createError(sheet.getSheetName(), i, "PARSE_ERROR", e.getMessage()));
Throwable cause = e;
while (cause.getCause() != null) {
cause = cause.getCause();
}
String errMsg = StringUtils.isNotBlank(cause.getMessage())
? cause.getMessage()
: (StringUtils.isNotBlank(e.getMessage()) ? e.getMessage() : "Sheet解析失败");
SheetErrorInfo errorInfo = SheetErrorInfo.createError(sheet.getSheetName(), i, "PARSE_ERROR", errMsg);
// 前端原因列优先展示 errorDetails这里同步写入避免空白
errorInfo.addErrorDetail(errMsg);
sheetErrors.add(errorInfo);
}
}
} catch (Exception e) {
@ -103,10 +121,7 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
headerMap.put(headerName, j);
}
}
if (!headerMap.containsKey("发票号") || !headerMap.containsKey("发票序号")) {
throw new Exception("缺少必要表头(发票号, 发票序号)");
}
validateTxImportHeaders(headerMap, sheet.getSheetName());
String cmcInvoice = "";
String readyDateStr = "";
@ -154,14 +169,13 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
totalQty = totalQty.add(qty);
}
if (headerMap.containsKey("ERP编码")) {
String erpCode = getMergedCellValue(sheet, r, headerMap.get("ERP编码"));
if (erpCode != null && !erpCode.isEmpty()) {
List<PartData> parts = coDelMapper.getPartNo(site, erpCode, username, buNo);
if (parts.isEmpty() && !invalidMaterials.contains(erpCode)) {
invalidMaterials.add(erpCode);
}
}
String erpCode = getMergedCellValue(sheet, r, headerMap.get("ERP编码"));
if (StringUtils.isBlank(erpCode)) {
throw new Exception("第" + (r + 1) + "行ERP编码为空");
}
List<PartData> parts = coDelMapper.getPartNo(site, erpCode, username, buNo);
if (parts.isEmpty() && !invalidMaterials.contains(erpCode)) {
invalidMaterials.add(erpCode);
}
}
@ -304,11 +318,8 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
headerMap.put(headerName, j);
}
}
// 检查必要表头
if (!headerMap.containsKey("发票号") || !headerMap.containsKey("发票序号")) {
throw new Exception("Sheet " + sheet.getSheetName() + " 缺少必要表头(发票号, 发票序号)");
}
// 检查导入表头必须与程序定义一致
validateTxImportHeaders(headerMap, sheet.getSheetName());
String cmcInvoice = "";
String customerName = "";
@ -433,6 +444,10 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
String invoiceSeqStr = getMergedCellValue(sheet, r, headerMap.get("发票序号"));
if (invoiceSeqStr == null || invoiceSeqStr.isEmpty()) continue;
String erpCode = getMergedCellValue(sheet, r, headerMap.get("ERP编码"));
if (StringUtils.isBlank(erpCode)) {
throw new Exception("第" + (r + 1) + "行ERP编码为空");
}
// 2. 发货通知单明细 EcssCoDelNotifyDetail
EcssCoDelNotifyDetail detail = detailMap.get(invoiceSeqStr);
@ -446,42 +461,39 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
detail.setModifyFlag(false);
detail.setStatus("仓库已确认");
if (headerMap.containsKey("PO")) detail.setCustomerPO(getMergedCellValue(sheet, r, headerMap.get("PO")));
if (headerMap.containsKey("ERP编码")) {
String erpCode = getMergedCellValue(sheet, r, headerMap.get("ERP编码"));
detail.setPn(erpCode);
List<PartData> parts = coDelMapper.getPartNo(site, erpCode, data.getUsername(), data.getBuNo());
if (parts.isEmpty()) {
detail.setPartNo(erpCode);
} else {
PartData partData = parts.getFirst();
detail.setPartNo(partData.getPartNo());
String hsCode = headerMap.containsKey("HS Code") ? getMergedCellValue(sheet, r, headerMap.get("HS Code")) : "";
String hsCodeDesc = headerMap.containsKey("申报品名") ? getMergedCellValue(sheet, r, headerMap.get("申报品名")) : "";
String brand = "无";
if (headerMap.containsKey("品牌")) {
brand = getMergedCellValue(sheet, r, headerMap.get("品牌"));
} else if (headerMap.containsKey("Brand")) {
brand = getMergedCellValue(sheet, r, headerMap.get("Brand"));
}
detail.setPn(erpCode);
List<PartData> parts = coDelMapper.getPartNo(site, erpCode, data.getUsername(), data.getBuNo());
if (parts.isEmpty()) {
detail.setPartNo(erpCode);
} else {
PartData partData = parts.getFirst();
detail.setPartNo(partData.getPartNo());
String hsCode = headerMap.containsKey("HS Code") ? getMergedCellValue(sheet, r, headerMap.get("HS Code")) : "";
String hsCodeDesc = headerMap.containsKey("申报品名") ? getMergedCellValue(sheet, r, headerMap.get("申报品名")) : "";
String brand = "无";
if (headerMap.containsKey("品牌")) {
brand = getMergedCellValue(sheet, r, headerMap.get("品牌"));
} else if (headerMap.containsKey("Brand")) {
brand = getMergedCellValue(sheet, r, headerMap.get("Brand"));
}
if (StringUtils.isNotBlank(hsCode) || StringUtils.isNotBlank(hsCodeDesc) || StringUtils.isNotBlank(brand)) {
coDelMapper.updatePartHsCode(site, partData.getPartNo(), hsCode, hsCodeDesc, brand);
if (StringUtils.isNotBlank(hsCodeDesc)) {
EcssHsCodeData hsCodeData = new EcssHsCodeData();
hsCodeData.setSite(site);
hsCodeData.setBuNo(data.getBuNo());
hsCodeData.setHsCodeDesc(hsCodeDesc);
hsCodeData.setBrand(brand);
List<EcssHsCodeData> existHsCodes = coDelMapper.checkHsCodeDescData(hsCodeData);
if (existHsCodes == null || existHsCodes.isEmpty()) {
hsCodeData.setHsCode(hsCode);
hsCodeData.setCreateBy(data.getUsername());
hsCodeData.setUnit(partData.getUmid());
// 根据BU赋值不同的codeNo
hsCodeData.setCodeNo("02-Hardtag".equals(data.getBuNo())?"HT001":"04-MHM".equals(data.getBuNo())?"MHM001":"");
coDelMapper.insertHsCodeData(hsCodeData);
}
if (StringUtils.isNotBlank(hsCode) || StringUtils.isNotBlank(hsCodeDesc) || StringUtils.isNotBlank(brand)) {
coDelMapper.updatePartHsCode(site, partData.getPartNo(), hsCode, hsCodeDesc, brand);
if (StringUtils.isNotBlank(hsCodeDesc)) {
EcssHsCodeData hsCodeData = new EcssHsCodeData();
hsCodeData.setSite(site);
hsCodeData.setBuNo(data.getBuNo());
hsCodeData.setHsCodeDesc(hsCodeDesc);
hsCodeData.setBrand(brand);
List<EcssHsCodeData> existHsCodes = coDelMapper.checkHsCodeDescData(hsCodeData);
if (existHsCodes == null || existHsCodes.isEmpty()) {
hsCodeData.setHsCode(hsCode);
hsCodeData.setCreateBy(data.getUsername());
hsCodeData.setUnit(partData.getUmid());
// 根据BU赋值不同的codeNo
hsCodeData.setCodeNo("02-Hardtag".equals(data.getBuNo())?"HT001":"04-MHM".equals(data.getBuNo())?"MHM001":"");
coDelMapper.insertHsCodeData(hsCodeData);
}
}
}
@ -623,15 +635,12 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
// ecss_CoDelBoxList item_no ecss_CoDelPalletDetail seq_no
palletDetail.setSeqNo(currentBoxItemNo);
palletDetail.setItemNo(palletDetailItemNo++);
if (headerMap.containsKey("ERP编码")) {
String erpCode = getMergedCellValue(sheet, r, headerMap.get("ERP编码"));
palletDetail.setPn(erpCode);
List<PartData> parts = coDelMapper.getPartNo(site, erpCode, data.getUsername(), data.getBuNo());
if (parts.isEmpty()) {
palletDetail.setPartNo(erpCode);
} else {
palletDetail.setPartNo(parts.get(0).getPartNo());
}
palletDetail.setPn(erpCode);
List<PartData> parts = coDelMapper.getPartNo(site, erpCode, data.getUsername(), data.getBuNo());
if (parts.isEmpty()) {
palletDetail.setPartNo(erpCode);
} else {
palletDetail.setPartNo(parts.get(0).getPartNo());
}
palletDetail.setQty(qty);
if (headerMap.containsKey("箱数")) {
@ -687,6 +696,31 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
}
}
/**
* TX导入表头严格校验
* 1. 固定列必须全部存在
* 2. 允许存在额外列不做拦截
*/
private void validateTxImportHeaders(Map<String, Integer> headerMap, String sheetName) throws Exception {
List<String> missingHeaders = new ArrayList<>();
for (String header : TX_REQUIRED_FIXED_HEADERS) {
if (!headerMap.containsKey(header)) {
missingHeaders.add(header);
}
}
if (missingHeaders.isEmpty()) {
return;
}
String errorMessage = "缺少必要表头(" + String.join(", ", missingHeaders) + ")";
if (StringUtils.isNotBlank(sheetName)) {
throw new Exception("Sheet " + sheetName + " " + errorMessage);
}
throw new Exception(errorMessage);
}
private String getMergedCellValue(Sheet sheet, int row, int col) {
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress region = sheet.getMergedRegion(i);
@ -1746,6 +1780,43 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
return result.toString();
}
/**
* PO号自动分行显示避免导出后超出单元格范围
*/
private String formatPoNoForDisplay(Collection<String> poNoCollection) {
if (poNoCollection == null || poNoCollection.isEmpty()) {
return "";
}
final int maxCharsPerLine = 85;
StringBuilder result = new StringBuilder();
int currentLineLength = 0;
for (String rawPoNo : poNoCollection) {
String poNo = rawPoNo == null ? "" : rawPoNo.trim();
if (StringUtils.isBlank(poNo)) {
continue;
}
if (result.length() == 0) {
result.append(poNo);
currentLineLength = poNo.length();
continue;
}
int appendLength = poNo.length() + 1; // +1 为空格分隔符
if (currentLineLength + appendLength > maxCharsPerLine) {
result.append("\n").append(poNo);
currentLineLength = poNo.length();
} else {
result.append(" ").append(poNo);
currentLineLength += appendLength;
}
}
return result.toString();
}
private void extractedInvoice(EcssDeclarationHeaderData data, ExcelTemplateAdapter template,
EcssCoDelNotifyHeaderData notifyHeader) {
List<EcssCoDelNotifyDetailData> notifyDetailList = data.getNotifyPartDetailList();
@ -1795,15 +1866,16 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
.filter(Objects::nonNull) // 防止空指针
.reduce(0, Integer::sum);
Map poNoMap = new HashMap<>();
Set<String> poNoSet = new LinkedHashSet<>();
for (int i = 0; i < detailList.size(); i++) {
Map eorder = detailList.get(i);
eorder.put("row_num", i + 1);
poNoMap.put(eorder.get("customerPO"), eorder.get("customerPO"));
String customerPO = Objects.toString(eorder.get("customerPO"), "").trim();
if (StringUtils.isNotBlank(customerPO)) {
poNoSet.add(customerPO);
}
}
StringBuilder ponos = new StringBuilder();
poNoMap.forEach((key, value) -> ponos.append(key + " "));
template.addVar("poNo", ponos);
template.addVar("poNo", formatPoNoForDisplay(poNoSet));
BigDecimal allPrice = BigDecimal.valueOf(0.0);
List<Map> ndList = sqlSession.selectList("ecssMapper.searchEcssCoDelNotifyDetailList", notifyHeader);
for (int i = 0; i < ndList.size(); i++) {
@ -1898,7 +1970,6 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
new java.text.SimpleDateFormat("d-MMM-yyyy", java.util.Locale.ENGLISH).format(notifyHeader.getReadyDate()));
template.addVar("cmc_invoice", notifyHeader.getCmcInvoice());
template.addVar("shippingMode", stringInput(notifyHeader.getShippingMode()));
Map poNoMap = new HashMap<>();
// 装箱数据
List<EcssCoDelPalletHeaderData> palletHeaderDataList = coDelMapper.searchEcssCoDelPalletHeaderData(notifyHeader);
// 总托数
@ -1908,14 +1979,11 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
.reduce(0, Integer::sum);
// 发货通知单明细
List<Map> detailList = coDelMapper.exportEcssCoDelNotifyDetail(data);
// 获取poNo
for (int i = 0; i < detailList.size(); i++) {
Map eorder = detailList.get(i);
poNoMap.put(eorder.get("customerPO"), eorder.get("customerPO"));
}
StringBuilder ponos = new StringBuilder();
poNoMap.forEach((key, value) -> ponos.append(key + " "));
template.addVar("poNo", ponos);
Set<String> poNoSet = detailList.stream()
.map(eorder -> Objects.toString(eorder.get("customerPO"), "").trim())
.filter(StringUtils::isNotBlank)
.collect(Collectors.toCollection(LinkedHashSet::new));
template.addVar("poNo", formatPoNoForDisplay(poNoSet));
List<Map> list = coDelMapper.selectBoxListTX(notifyHeader);
// DB中item_no可能是字符串区间"127~127""2~26"直接查询顺序可能不稳定导出前做自然排序
sortBoxListBySeqAndItemNo(list);
@ -2142,7 +2210,6 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
new java.text.SimpleDateFormat("d-MMM-yyyy", java.util.Locale.ENGLISH).format(notifyHeader.getReadyDate()));
template.addVar("cmc_invoice", notifyHeader.getCmcInvoice());
template.addVar("shippingMode", stringInput(notifyHeader.getShippingMode()));
Map poNoMap = new HashMap<>();
// 装箱数据
List<EcssCoDelPalletHeaderData> palletHeaderDataList = coDelMapper.searchEcssCoDelPalletHeaderData(notifyHeader);
// 总托数
@ -2152,14 +2219,11 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
.reduce(0, Integer::sum);
// 发货通知单明细
List<Map> detailList = coDelMapper.exportEcssCoDelNotifyDetail(data);
// 获取poNo
for (int i = 0; i < detailList.size(); i++) {
Map eorder = detailList.get(i);
poNoMap.put(eorder.get("customerPO"), eorder.get("customerPO"));
}
StringBuilder ponos = new StringBuilder();
poNoMap.forEach((key, value) -> ponos.append(key + " "));
template.addVar("poNo", ponos);
Set<String> poNoSet = detailList.stream()
.map(eorder -> Objects.toString(eorder.get("customerPO"), "").trim())
.filter(StringUtils::isNotBlank)
.collect(Collectors.toCollection(LinkedHashSet::new));
template.addVar("poNo", formatPoNoForDisplay(poNoSet));
List<Map> list = coDelMapper.selectBoxListTX(notifyHeader);
// DB中item_no可能是字符串区间"127~127""2~26"直接查询顺序可能不稳定导出前做自然排序
sortBoxListBySeqAndItemNo(list);
@ -2390,7 +2454,6 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
new java.text.SimpleDateFormat("d-MMM-yyyy", java.util.Locale.ENGLISH).format(notifyHeader.getReadyDate()));
template.addVar("cmc_invoice", notifyHeader.getCmcInvoice());
template.addVar("shippingMode", stringInput(notifyHeader.getShippingMode()));
Map poNoMap = new HashMap<>();
// 装箱数据
List<EcssCoDelPalletHeaderData> palletHeaderDataList = coDelMapper.searchEcssCoDelPalletHeaderData(notifyHeader);
// 总托数
@ -2400,14 +2463,11 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
.reduce(0, Integer::sum);
// 发货通知单明细
List<Map> detailList = coDelMapper.exportEcssCoDelNotifyDetail(data);
// 获取poNo
for (int i = 0; i < detailList.size(); i++) {
Map eorder = detailList.get(i);
poNoMap.put(eorder.get("customerPO"), eorder.get("customerPO"));
}
StringBuilder ponos = new StringBuilder();
poNoMap.forEach((key, value) -> ponos.append(key + " "));
template.addVar("poNo", ponos);
Set<String> poNoSet = detailList.stream()
.map(eorder -> Objects.toString(eorder.get("customerPO"), "").trim())
.filter(StringUtils::isNotBlank)
.collect(Collectors.toCollection(LinkedHashSet::new));
template.addVar("poNo", formatPoNoForDisplay(poNoSet));
List<Map> list = coDelMapper.selectBoxListTX(notifyHeader);
// DB中item_no可能是字符串区间"127~127""2~26"直接查询顺序可能不稳定导出前做自然排序
sortBoxListBySeqAndItemNo(list);
@ -2647,15 +2707,16 @@ public class CoDelExcelTXServiceImpl implements CoDelExcelTXService {
.collect(Collectors.joining("、")); // 用换行拼接
template.addVar("hs_code", stringInput(hsCodes));
Map<Object, Object> poNoMap = new HashMap<>();
Set<String> poNoSet = new LinkedHashSet<>();
BigDecimal ttlAmount = BigDecimal.ZERO;
for (Map map : nodifyDetailList) {
poNoMap.put(map.get("customerPO"), map.get("customerPO"));
String customerPO = Objects.toString(map.get("customerPO"), "").trim();
if (StringUtils.isNotBlank(customerPO)) {
poNoSet.add(customerPO);
}
ttlAmount = ttlAmount.add((BigDecimal) map.get("ttl_amount"));
}
StringBuilder ponos = new StringBuilder();
poNoMap.forEach((key, value) -> ponos.append(key).append("\n"));
template.addVar("poNo", ponos);
template.addVar("poNo", formatPoNoForDisplay(poNoSet));
template.addVar("shipping_port", stringInput(notifyHeader.getCnative()));
template.addVar("cmc_invoice", stringInput(notifyHeader.getCmcInvoice()));
// 导出时默认可编辑的栏目

20
src/main/resources/mapper/ecss/CoDelMapper.xml

@ -1356,11 +1356,21 @@ create_by,create_date,update_by,update_date
and w.record_type='ECSSPART' and w.code_no='BG001' and w.properties_item_no='BOXWEIGHT'
where a.site = #{site} and a.bu_no = #{buNo} and a.delNo = #{delNo}
order by
ISNULL(TRY_CONVERT(int, LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1)), 2147483647),
ISNULL(
TRY_CONVERT(int, SUBSTRING(a.item_no, CHARINDEX('~', a.item_no + '~') + 1, LEN(a.item_no))),
ISNULL(TRY_CONVERT(int, LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1)), 2147483647)
),
CASE
WHEN LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1) != ''
AND LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1) NOT LIKE '%[^0-9]%'
THEN CONVERT(int, LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1))
ELSE 2147483647
END,
CASE
WHEN SUBSTRING(a.item_no, CHARINDEX('~', a.item_no + '~') + 1, LEN(a.item_no)) != ''
AND SUBSTRING(a.item_no, CHARINDEX('~', a.item_no + '~') + 1, LEN(a.item_no)) NOT LIKE '%[^0-9]%'
THEN CONVERT(int, SUBSTRING(a.item_no, CHARINDEX('~', a.item_no + '~') + 1, LEN(a.item_no)))
WHEN LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1) != ''
AND LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1) NOT LIKE '%[^0-9]%'
THEN CONVERT(int, LEFT(a.item_no, CHARINDEX('~', a.item_no + '~') - 1))
ELSE 2147483647
END,
a.item_no
</select>

BIN
src/main/resources/templates/ALPHA/declaration-all-template.xlsx

BIN
src/main/resources/templates/TX/declaration-all-template.xlsx

Loading…
Cancel
Save