需求里面说,要生成一个发货单,发货单要注明总金额和金额中文大写,遂写了这个工具方法
/**
* 金额转中文大写
*
* @param amount 金额 如:new BigDecimal("278.00");
* @return 大写文字 如:贰佰柒拾捌元整
*/
public String amountToChinese(BigDecimal amount) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) == 0) return "零元整";
//保留两位小数,进行四舍五入,防止 278.005 这类数值导致计算异常
amount = amount.setScale(2, RoundingMode.HALF_UP);
StringBuilder sb = new StringBuilder();
//负数处理
if (amount.signum() < 0) {
sb.append("负");
amount = amount.abs();
}
//提取整数与小数部分
long yuan = amount.longValue();
int fen = amount.subtract(BigDecimal.valueOf(yuan)).multiply(BigDecimal.valueOf(100)).intValue();
String[] CN_NUM = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
//最大支持到千万亿
String[] CN_UNIT = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万亿", "拾", "佰", "仟"};
//转换整数部分
if (yuan > 0) {
String yuanStr = String.valueOf(yuan);
int len = yuanStr.length();
if (len > CN_UNIT.length) return "金额过大无法转换";
boolean prevZero = false;
for (int i = 0; i < len; i++) {
int d = yuanStr.charAt(i) - '0';
int unitIdx = len - 1 - i;
if (d != 0) {
if (prevZero) sb.append("零");
sb.append(CN_NUM[d]).append(CN_UNIT[unitIdx]);
prevZero = false;
} else {
prevZero = true;
//处理逢万、亿的情况
if (unitIdx % 4 == 0 && unitIdx > 0) {
//判断当前这4位区间内是否全是0,只有包含非0才追加单位
boolean blockHasValue = false;
int start = Math.max(0, i - 3);
for (int k = start; k <= i; k++) {
if (yuanStr.charAt(k) != '0') {
blockHasValue = true;
break;
}
}
if (blockHasValue) {
if (unitIdx == 4) sb.append("万");
else if (unitIdx == 8) sb.append("亿");
else if (unitIdx == 12) sb.append("万亿");
}
}
}
}
sb.append("元");
} else {
sb.append("零元");
}
//转换小数部分
if (fen == 0) {
sb.append("整");
} else {
int jiao = fen / 10;
int fen2 = fen % 10;
if (jiao > 0) {
sb.append(CN_NUM[jiao]).append("角");
} else if (yuan > 0) {
sb.append("零"); //处理类似 1.05 -> 壹元零伍分 的情况
}
if (fen2 > 0) {
sb.append(CN_NUM[fen2]).append("分");
}
}
return sb.toString();
}
微信扫码查看本文
发表评论