網頁

2021/1/21

信用卡中心 請款檔卡人資訊欄位長度錯誤

最近在寫產生送給信用卡中心的請款檔的卡人資訊欄位一直有問題。

原來該欄的編碼必須是BIG5,一開始沒注意到這點直接用預設的UTF-8所以產出的請款明細長度一直不符規格。

序號 欄位位置 欄位長度
(Byte)
資料型態 說明 送件需填欄位 回覆資料欄位
10 120-159 40 文數字 卡人資訊
左靠右補空白此欄位需填放 BIG5〝全形字元〞, 如果沒有資料請填20個全形空白
選填 選填

產生該欄的內容在計算填空的數目時必須用BIG5編碼的字元集來計算Byte長度。下面的format可輸入原始內容、欄位Byte長度、靠左靠右、填充字及字元編碼產生規格要求的格式。

package com.abc.demo;

import org.apache.commons.lang3.StringUtils;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class Main {

    public static void main(String[] args) {
    
        String content = "王大明";
        int columnBytesLength = 40;
        int alignment = 0; // 0:靠左, 1:靠右
        String filler = "\u3000"; // 全形空白
        Charset charset = Charset.forName("big5"); // BIG5編碼字元集

        String result = format(content, columnBytesLength, alignment, filler, charset);

        System.out.printf("result=[%s], charset=%s", result, charset); // result=[王大明                 ], charset=Big5

    }

    /**
     * 請款檔明細欄位格式化。charset若為null預設為UTF-8
     *
     * @param content           原始內容
     * @param columnBytesLength 欄位長度(Byte)
     * @param alignment         靠左靠右對齊,0:靠左,1:靠右
     * @param filler            填充字
     * @param charset           字符集
     * @return 格式化的欄位
     */
    static String format(String content, int columnBytesLength, int alignment, String filler, Charset charset) {
        if (content == null) {
            content = "";
        }
        if (charset == null) {
            charset = StandardCharsets.UTF_8;
        }
        if (StringUtils.isEmpty(filler)) {
            throw new IllegalArgumentException("filler cannot be empty");
        }
        int originContentBytesLength = content.getBytes(charset).length; // 原始內容Bytes長度
        if (originContentBytesLength > columnBytesLength) { // 原始內容Bytes長度不可超過欄位Bytes長度
            throw new IllegalArgumentException("content bytes length cannot be greater than columnBytesLength");
        }
        int fillerCount = (columnBytesLength - originContentBytesLength) / filler.getBytes(charset).length; // 填充字數 = (欄位Bytes長度 - 原始內容長度) / 填充字Bytes長度
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < fillerCount; i++) {
            stringBuilder.append(filler); // 生成填充字
        }
        if (alignment == 1) {
            stringBuilder.append(content); // 原始內容靠右
        } else {
            stringBuilder.insert(0, content); // 原始內容靠左
        }

        return stringBuilder.toString();
    }

}


沒有留言:

張貼留言