//金额转大写
public class ConvertUpMoney {
private static final Logger log = LoggerFactory.getLogger(ConvertUpMoney.class);
/**
* 大写数字
*/
private static final String[] NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
/**
* 整数部分的单位
*/
private static final String[] I_UNIT = {"元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟"};
/**
* 小数部分的单位
*/
private static final String[] D_UNIT = {"角", "分", "厘"};
/**
* 转成中文大写金额
*
* @param integerStr 金额
* @return 中文大写金额
*/
public static String toChinese(String integerStr) {
integerStr = StringUtils.trimToEmpty(integerStr);
if (integerStr.isEmpty()) {
return "";
}
// 去掉","
integerStr = integerStr.replaceAll(",", "");
if (!integerStr.matches("-?\\d+(\\.\\d+)?([eE]-?\\d+)?")) {
log.error("转换中文大写金额失败,原因:str =【{}】为非数字!", integerStr);
return integerStr;
}
if (integerStr.matches("-?\\d+(\\.\\d+)?[eE]-?\\d+")) {
integerStr = new BigDecimal(integerStr).toPlainString();
}
if (integerStr.matches("-?0+(\\.0+)?")) {
return "零元整";
}
// 判断是否存在负号"-"
boolean isNegative = false;
if (integerStr.startsWith("-")) {
isNegative = true;
integerStr = integerStr.substring(1);
}
String[] integers = integerStr.split("\\.");
// beyond 超出计算能力,直接返回
if (integers[0].length() > I_UNIT.length) {
if (isNegative) {
integerStr = "-" + integerStr;
}
log.error("转换中文大写金额失败,原因:str =【{}】超出计算能力!", integerStr);
return integerStr;
}
StringBuilder result = new StringBuilder();
result.append(getChineseInteger(integers[0]));
if (integers.length > 1) {
result.append(getChineseDecimal(integers[1]));
} else {
result.append("整");
}
if (isNegative) {
// 如果是负数,加上"负"
return result.insert(0, "负").toString();
} else {
return result.toString();
}
}
/**
* 将整数部分转为大写的金额字符串
*
* @param integerStr 数字字符串
* @return 中文大写金额字符串
*/
private static String getChineseInteger(String integerStr) {
integerStr = StringUtils.trimToEmpty(integerStr);
if (integerStr.matches("0*")) {
return "零元";
}
// 去除开头的0
if (integerStr.matches("0\\d+")) {
integerStr = integerStr.replaceAll("^[0]+", "");
}
int[] integer = toIntArray(integerStr);
int length = integer.length;
StringBuilder chineseInteger = new StringBuilder();
for (int i = 0; i < length; i++) {
if (integer[i] == 0) {
String unit = "";
switch (length - i) {
case 13:
// 万亿
if (isValuable(integerStr, 13)) {
unit = I_UNIT[4];
if (!isValuable(integerStr, 9)) {
unit += I_UNIT[8];
}
}
break;
case 9:
// 亿
if (isValuable(integerStr, 9)) {
unit = I_UNIT[8];
}
break;
case 5:
// 万
if (isValuable(integerStr, 5)) {
unit = I_UNIT[4];
}
break;
case 1:
// 元
unit = I_UNIT[0];
break;
default:
}
if ((i + 1) < length && integer[i + 1] != 0) {
unit += NUMBERS[0];
}
chineseInteger.append(unit);
} else {
chineseInteger.append(NUMBERS[integer[i]]).append(I_UNIT[length - i - 1]);
}
}
return chineseInteger.toString();
}
/**
* 将字符串转为int数组
*
* @param number 数字字符串
* @return 转换后的数字数组
*/
private static int[] toIntArray(String number) {
int[] array = new int[number.length()];
for (int i = 0; i < number.length(); i++) {
array[i] = Integer.parseInt(number.substring(i, i + 1));
}
return array;
}
/**
* 判断计量单位对应档位是否有值
*
* @param integerStr 数字字符串
* @param index 档位索引值(万-5,亿-9,万亿-13)
* @return true-有值,false-无值
*/
private static boolean isValuable(String integerStr, int index) {
index = index - 1;
int length = integerStr.length();
if (length > index) {
int endIndex = Math.max(length - (index + 4), 0);
int startIndex = length - index;
return Integer.parseInt(integerStr.substring(endIndex, startIndex)) > 0;
} else {
return false;
}
}
/**
* 将小数部分转为大写的金额
*
* @param integerStr 数字字符串
* @return 中文大写金额字符串
*/
private static String getChineseDecimal(String integerStr) {
integerStr = StringUtils.trimToEmpty(integerStr);
// 去除末尾的0
if (integerStr.matches("\\d+0+")) {
integerStr = integerStr.replaceAll("[0]+$", "");
}
if (integerStr.matches("0*")) {
return "整";
}
int[] decimals = toIntArray(integerStr);
StringBuilder chineseDecimal = new StringBuilder();
for (int i = 0; i < decimals.length; i++) {
if (i == D_UNIT.length) {
break;
}
chineseDecimal.append(NUMBERS[decimals[i]]).append(D_UNIT[i]);
}
return chineseDecimal.toString().isEmpty() ? "整" : chineseDecimal.toString();
}
}