java實現數字金額轉換中文大寫金額
阿新 • • 發佈:2019-01-01
直接貼程式碼吧!
public class CnNumberUtils {
private final static Logger logger = LoggerFactory.getLogger(CnNumberUtils.class);
//阿拉伯數字對應大寫中文數字
private final static String[] CN_NUMERALS = {"零", "壹", "貳", "叄", "肆", "伍", "陸", "柒", "捌", "玖"};
//低單位
private final static String[] CN_NUM_UNIT = {"" , "拾", "佰", "仟"};
//萬元以上高單位
private final static String[] CN_NUM_HIGHT_UNIT = {"", "萬", "億", "萬億"};
//小數位單位
private final static String[] CN_NUM_DECIMAL_UNIT = {"", "角", "分"};
/**
* 轉換成中文大寫金額(最高支援萬億和兩位小數)
* @param num
* @return
*/
public static String toUppercase (Double num){
return toUppercase(String.valueOf(num));
}
/**
* 轉換成中文大寫金額(最高支援萬億和兩位小數)
* @param num
* @return
*/
public static String toUppercase(String num){
String[] strNumArray = num.split("\\.");
int strNumArrayLength = strNumArray.length;
if (strNumArrayLength > 2 || (strNumArrayLength == 2 && strNumArray[1].length() > 2)){
logger.error("金額格式異常,不能有多個小數點,小數位最多隻能兩位!");
}
BigDecimal bigDecimal = new BigDecimal(strNumArray[0]);
BigInteger bigInteger = bigDecimal.toBigInteger();
char[] chars = bigInteger.toString().toCharArray();
int intLength = chars.length;
StringBuilder strBuilder = new StringBuilder();
for(int i=0; i<intLength; i++){
String curCnNum = CN_NUMERALS[charNumToInt(chars[i])];
int ui = ((intLength-1)-i)%4;
int hui = ((intLength-1)-i)/4;
strBuilder.append(curCnNum);
if(!isZero(curCnNum)){
strBuilder.append(CN_NUM_UNIT[ui]);
String heightUnit = CN_NUM_HIGHT_UNIT[hui];
//如果剩餘沒有低金額單位或者後續都為零則加上高單位
if(ui == 0 || isZeroInResidue(chars, i, ui)){
strBuilder.append(heightUnit);
//萬單位以後的千單位如果不能為零則跳過零
if(heightUnit.equals(CN_NUM_HIGHT_UNIT[1]) && !isZeroOfIndex(chars, (ui+1)+i)){
i = i+skipZero(chars, i);
}
}
}
}
clearZero(0, strBuilder);
//小數位轉換
strBuilder.append("圓");
if(strNumArrayLength == 1 || strNumArray[1].matches("^[0]*$")){
strBuilder.append("整");
return strBuilder.toString();
}
char[] decimalChars = strNumArray[1].toCharArray();
int decimalCharLength = decimalChars.length;
for(int i=1; i<=decimalCharLength; i++){
String cnNum = CN_NUMERALS[charNumToInt(decimalChars[i-1])];
if(!isZero(cnNum)){
strBuilder.append(cnNum).append(CN_NUM_DECIMAL_UNIT[i]);
}else if(i == decimalCharLength){
return strBuilder.toString();
}else{
strBuilder.append(cnNum);
}
}
return strBuilder.toString();
}
/**
* 遞迴清除多餘的零
* @param startIndex
* @param strBuilder
*/
private static void clearZero(int startIndex, StringBuilder strBuilder){
int strLength = strBuilder.length();
int zeroIndex = strBuilder.indexOf(CN_NUMERALS[0], startIndex);
if(zeroIndex <= -1){
return;
}
if(strLength <= zeroIndex+1){
strBuilder.deleteCharAt(zeroIndex);
return;
}
if(zeroIndex > -1 && isZero(strBuilder.charAt(zeroIndex+1))){
strBuilder.deleteCharAt(zeroIndex);
clearZero(startIndex, strBuilder);
return;
}
if(strLength > zeroIndex+1){
clearZero(zeroIndex+1, strBuilder);
return;
}
}
private static boolean isZero(String cnNum){
return cnNum.equals(CN_NUMERALS[0]);
}
private static boolean isZero(char cnNum){
return isZero(String.valueOf(cnNum));
}
/**
* 跳過為零的下標
* @param chars
* @param beginIndex
* @return
*/
private static int skipZero(char[] chars, int beginIndex){
int newIndex = 0;
int charLength = chars.length;
for(int i=beginIndex+1; i<charLength; i++){
if(isZero(CN_NUMERALS[charNumToInt(chars[i])])){
newIndex++;
}else{
break;
}
}
return newIndex;
}
/**
* 指定下標值是否是為零
* @param chars
* @param index
* @return boolean
*/
private static boolean isZeroOfIndex(char[] chars, int index){
int numInex = Integer.parseInt(String.valueOf(chars[index]), 10);
String cnNum = CN_NUMERALS[numInex];
return isZero(cnNum);
}
/**
* 從begin開始至end結束是否都是零
* @param chars
* @param begin
* @param end
* @return
*/
private static boolean isZeroInResidue(char[] chars, int begin, int end){
for(int i=1; i<=end; i++){
boolean r = isZeroOfIndex(chars, begin+i);
if(!r){
return false;
}
}
return true;
}
/**
* char型別數值轉換為int
* @param charNum
* @return
*/
private static int charNumToInt(char charNum){
String ns = String.valueOf(charNum);
return Integer.parseInt(ns, 10);
}
}
技術要點:
金額字元長度-1-i(迴圈的當前索引)%4結果得出當前金額的小單位(十百千)。
金額字元長度-1-i(迴圈的當前索引)/4結果得出當前位金額大單位(萬以上)。
例如:
10000元
長度5,-1-i(0)/4=1=單位萬。