財務系統、票據打印、合同生成等場景常需將數字金額(如 1234.56)轉為中文大寫格式(壹仟貳佰叁拾肆元伍角陸分)。標準大寫字符:
數字:零 壹 貳 叁 肆 伍 陸 柒 捌 玖 單位:分 角 元 拾 佰 仟 萬 拾萬 佰萬 仟萬 億 ...
import java.math.BigDecimal;
import java.math.RoundingMode;
public class ChineseAmountConverter {
private static final String[] DIGITS = {"零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"};
private static final String[] UNITS = {"", "拾", "佰", "仟"};
private static final String[] BIG_UNITS = {"", "萬", "億", "兆"}; // 擴展單位
private static final String YUAN = "元";
private static final String ZHENG = "整";
/**
* 轉換入口:支持長整型、BigDecimal、字符串
*/
public static String convert(Object amount) {
if (amount == null) return "零元整";
BigDecimal bd;
if (amount instanceof BigDecimal) {
bd = (BigDecimal) amount;
} else if (amount instanceof Number) {
bd = new BigDecimal(amount.toString());
} else {
bd = new BigDecimal(amount.toString().trim());
}
// 保留兩位小數,四捨五入
bd = bd.setScale(2, RoundingMode.HALF_UP);
// 分離整數部分和小數部分
long yuanPart = bd.longValue(); // 元部分
int fenPart = bd.remainder(BigDecimal.ONE) // 小數部分
.movePointRight(2)
.intValue(); // 轉為分(角*10 + 分)
String yuanStr = convertIntegerPart(yuanPart);
String fenStr = convertDecimalPart(fenPart);
return yuanStr + fenStr;
}
/** 處理整數部分(元) */
private static String convertIntegerPart(long num) {
if (num == 0) return "零" + YUAN;
StringBuilder sb = new StringBuilder();
int unitIndex = 0; // 萬/億單位索引
while (num > 0) {
int section = (int) (num % 10000); // 取低4位
if (section != 0) {
String sectionStr = convertSection(section);
sb.insert(0, sectionStr + BIG_UNITS[unitIndex]);
} else if (sb.length() > 0 && !sb.toString().startsWith("零")) {
// 中間有0段,補零
sb.insert(0, DIGITS[0]);
}
num /= 10000;
unitIndex++;
}
return sb.append(YUAN).toString();
}
/** 處理4位一段(千/百/十/個) */
private static String convertSection(int num) {
StringBuilder sb = new StringBuilder();
boolean zeroFlag = false;
for (int i = 0; i < 4; i++) {
int digit = num % 10;
if (digit == 0) {
zeroFlag = true;
} else {
if (zeroFlag) {
sb.insert(0, DIGITS[0]);
zeroFlag = false;
}
sb.insert(0, DIGITS[digit] + UNITS[i]);
}
num /= 10;
}
// 處理段內尾部零(如 1000 -> 壹仟,不需補零)
return sb.toString().replaceAll("零+$", "");
}
/** 處理小數部分(角分) */
private static String convertDecimalPart(int fen) {
if (fen == 0) return ZHENG;
int jiao = fen / 10;
int fenDigit = fen % 10;
StringBuilder sb = new StringBuilder();
if (jiao > 0) sb.append(DIGITS[jiao]).append("角");
if (fenDigit > 0) sb.append(DIGITS[fenDigit]).append("分");
if (jiao == 0 && fenDigit > 0) sb.insert(0, DIGITS[0]); // 0角X分 -> 零角X分
return sb.toString();
}
}
public static void main(String[] args) {
// 基礎測試
System.out.println(convert(0)); // 零元整
System.out.println(convert(1011)); // 壹仟零壹拾壹元整
System.out.println(convert("1234.56")); // 壹仟貳佰叁拾肆元伍角陸分
System.out.println(convert("10000")); // 壹萬元整
System.out.println(convert("100000000")); // 壹億元整
System.out.println(convert("100000001")); // 壹億零壹元整
System.out.println(convert("1000.01")); // 壹仟元零壹分
System.out.println(convert("0.01")); // 零元零壹分
System.out.println(convert("123456789.99")); // 壹億貳仟叁佰肆拾伍萬陸仟柒佰捌拾玖元玖角玖分
// BigDecimal 精度測試
System.out.println(convert(new BigDecimal("0.005"))); // 零元零壹分 (四捨五入)
}
double/floatBIG_UNITS 可輕鬆擴展到「兆/京」等更大單位BigDecimal 實例或預編譯正則