代碼如下:
package com.wy.test.other;
/**
* 人民幣格式化工具
* 用于將人民幣小寫金額轉換成大寫金額
* 要點:1.區(qū)分金額是整數(shù)還是小數(shù)击敌,需要分開處理谓松;
* 2.將金額數(shù)字倒序,便于同單位合并
* 3.異常處理,判斷數(shù)字中是否含有非法字符盯腌,有則return溉知;
* 4.數(shù)字中0的處理;
*/
public class MoneyFormatUtil {
//單位
private static final char[] UNIT = {'億', '拾', '佰', '仟', '萬', '拾', '佰', '仟'};
//大寫金額模板
private static final char[] TEMPLATE = {'零', '壹', '貳', '叁', '肆', '伍', '陸', '柒', '捌', '玖'};
private String submoneyCN[] = {"", "拾", "佰", "仟"}; //表示數(shù)字位數(shù)的數(shù)組
private String numberCNN[] = {"零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"}; //大寫數(shù)字的數(shù)組
private static MoneyFormatUtil instance;
/**
* 獲取類的實例
*
* @return 類的實例
*/
public static MoneyFormatUtil getInstance() {
if (instance == null) {
instance = new MoneyFormatUtil();
}
return instance;
}
/**
* 將人民幣小寫金額轉換成大寫金額
*
* @return 轉換后的大寫金額
*/
public String convert(String money) {
String formatCN = "";
int point = money.indexOf("."); //判斷字符串是否包含小數(shù)點(不包含返回-1)
if (point != -1) {//包含小數(shù)點的情況
formatCN = decimalConversion(money, point);
} else {
formatCN = integerConversion(money);
}
return formatCN;
}
/**
* 小數(shù)轉換
*
* @param decimalString 小數(shù)字符串(例:1234567.89 壹佰貳拾叁萬肆仟伍佰陸拾柒元捌角玖分)
* @param pointPosition 小數(shù)點在字符串中的位置
* @return 轉換后的大寫金額
*/
private String decimalConversion(String decimalString, int pointPosition) {
String formatDecimalString = "";
String money1 = decimalString.substring(0, pointPosition); //小數(shù)點之前的部分
String money1_1 = (new StringBuffer(money1).reverse()).toString();//字符串倒序
String money2 = decimalString.substring(pointPosition + 1); //小數(shù)點之后的部分
//異常處理
for (int i = 0; i < money1.length(); i++) {
if (!Character.isDigit(money1.charAt(i))) {
return "數(shù)字中含有非法字符";
}
}
for (int i = 0; i < money2.length(); i++) {
if (!Character.isDigit(money2.charAt(i))) {
return "數(shù)字中含有非法字符";
}
}
if (money2.length() < 2) { //如果小數(shù)點后的部分少于兩位犯助,用"0"補齊
if (money2.length() == 0) {
money2 = "00";
} else {
money2 += "0";
}
} else {
//如果小數(shù)點后的位數(shù)大于2位瞳抓,則只前2位
money2 = decimalString.substring(pointPosition + 1, pointPosition + 3);
}
int len = money1_1.length(); //字符串反轉之后,小數(shù)點之前的字符位數(shù)
int pos = len - 1;
String sigle = "";
boolean allhavenum = false;
boolean havenum = false;
boolean mark = false; //設置一個開關變量军洼,若當前數(shù)為"0"玫荣,將該值設為true甚淡;不為"0"時設為false
/**以下代碼為讀出小數(shù)點左面的部分*/
while (pos >= 0) {
sigle = money1_1.substring(pos, pos + 1);//截取1位數(shù)字,比如數(shù)字1234.56,將左側的字符串反轉捅厂,值為4321贯卦,則截取的值為1
/**讀取“億單元”的代碼。
* 假設讀取10024531042.34焙贷。
* 小數(shù)點左面反轉后為:24013542001
* pos的初始值為10
* mark的初始值為false
* havenum的初始值為false
* */
if (pos >= 8 && pos < 12) {
if (!sigle.equals("0")) { //如果當前值不為"0"
if (!mark) { //如果當前值的前一位數(shù)不為"0"
formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];
} else { //如果當前值不為"0"撵割,但該值的前一位數(shù)為"0"
if (allhavenum) { //如果在當前值之前有不為"0"的數(shù)字出現(xiàn)。該條件用來處理用戶輸入的如:0012.34的數(shù)值
formatDecimalString += "零";
}
formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];
mark = false;
}
havenum = true;
allhavenum = true; //變量allhavenum表示小數(shù)點左面的數(shù)中是否有不為"0"的數(shù)字辙芍;true表示有啡彬,false表示無
} else { //如果當前值為"0"
mark = true;
}
if (pos % 4 == 0 && havenum) { //如果當前數(shù)字為該單元的最后一位,并且該單元中有不為"0"的數(shù)字出現(xiàn)
formatDecimalString += "億";
havenum = false;
}
}
/**讀取“萬單元”的代碼*/
if (pos >= 4 && pos < 8) {
if (!sigle.equals("0")) {
if (!mark) {
formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];
} else {
if (allhavenum) {
formatDecimalString += "零";
}
formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];
mark = false;
}
havenum = true;
allhavenum = true;
} else {
mark = true;
}
if (pos % 4 == 0 && havenum) {
formatDecimalString += "萬";
havenum = false;
}
}
/**讀取“個故硅、十庶灿、百、千”的代碼*/
if (pos >= 0 && pos < 4) {
if (!sigle.equals("0")) {
if (!mark) {
formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];
} else {
if (allhavenum) {
formatDecimalString += "零";
}
formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];
mark = false;
}
havenum = true;
allhavenum = true;
} else {
mark = true;
}
}
pos--;
}
/**碰到小數(shù)點時的讀法*/
if (allhavenum) { //如:00.34就不能讀為:元3角4分.變量allhavenum表示小數(shù)點左面的內容中是否有數(shù)字出現(xiàn)
formatDecimalString += "元";
} else {//如果小數(shù)點左面的部分都為0如:00.34應讀為:零元3角4分
formatDecimalString = "零元";
}
/**以下代碼為讀出小數(shù)點右面的部分 */
if (money2.equals("00")) {
formatDecimalString += "整";
} else {
/**讀出角,如120.34讀為:1佰2拾元零3角4分吃衅;123.04讀為:1佰2拾3元零4分*/
// if(money2.startsWith("0")||(allhavenum&&money1.endsWith("0"))){
// formatCN+="零";
// }
if (!money2.startsWith("0")) {
formatDecimalString += numberCNN[Integer.parseInt(money2.substring(0, 1))] + "角";
}
//讀出分往踢,如:12.30讀1拾2元3角零分
formatDecimalString += numberCNN[Integer.parseInt(money2.substring(1))] + "分";
}
return formatDecimalString;
}
/**
* 整數(shù)轉換
*
* @param integerString 整數(shù)字符串(例:123456789 壹億貳仟叁佰肆拾伍萬陸仟柒佰捌拾玖元整)
* @return 轉換后的大寫金額
*/
private String integerConversion(String integerString) {
//用來存放轉換后的大寫數(shù)字,因為是StringBuffer類型,所以順便把沒有轉換
//的數(shù)字倒序排列一下,省一個變量.
StringBuffer ChineseCharI = new StringBuffer(integerString);
//倒序的數(shù)字,便于同單位合并
String rintString = ChineseCharI.reverse().toString();
//清空一下
ChineseCharI.delete(0, ChineseCharI.length());
//單位索引
int unitIndex = 0;
//數(shù)字長度
int intStringLen = integerString.length();
//一位由字符轉換的數(shù)字
int intStringnumber = 0;
//補0
boolean addZero = false;
boolean flagZero = false;
for (int i = 0; i < intStringLen; i++) {
//按單位長度循環(huán)索引
unitIndex = i % UNIT.length;
//異常處理
if (!Character.isDigit(rintString.charAt(i))) {
return "數(shù)字中含有非法字符";
}
//將字符轉為數(shù)字,范圍為10以內(不包括10徘层,超出則返回-1)
intStringnumber = Character.digit(rintString.charAt(i), 10);
//如果當前位是0,開啟補0繼續(xù)循環(huán)直到不是0的位
if (intStringnumber == 0) {
addZero = true;
if (i != 0 && i % 4 == 0) {
if (addZero && ChineseCharI.length() != 0) {
ChineseCharI.append(TEMPLATE[0]);
addZero = false;
}
flagZero = true;
ChineseCharI.append(UNIT[unitIndex]);
}
} else {
//若當前位不是第一位且補0開啟
if (addZero && ChineseCharI.length() != 0 && !flagZero) {
ChineseCharI.append(TEMPLATE[0]);
}
flagZero = false;
//插入單位
//個位數(shù)后面不需要單位
if (i > 0) {
ChineseCharI.append(UNIT[unitIndex]);
}
//插入大寫數(shù)字
ChineseCharI.append(TEMPLATE[intStringnumber]);
//補0關閉
addZero = false;
}
}
//異常處理
if (ChineseCharI.length() == 0) {
return "零";
}
return ChineseCharI.reverse().toString() + "元整";
}
}
在項目中的應用:
String convert = MoneyFormatUtil.getInstance().convert("1234567.89");
String convert1 = MoneyFormatUtil.getInstance().convert("1.34");
String convert2 = MoneyFormatUtil.getInstance().convert("100.34");
String convert3 = MoneyFormatUtil.getInstance().convert("34f5460.34");
String convert4 = MoneyFormatUtil.getInstance().convert("10000.34");
String convert5 = MoneyFormatUtil.getInstance().convert("100000.34f");
String convert6 = MoneyFormatUtil.getInstance().convert("1003430000.34");
String convert7 = MoneyFormatUtil.getInstance().convert("1101010101.34");
String convert8 = MoneyFormatUtil.getInstance().convert("1010101010.34");
早計劃峻呕,早準備,早完成惑灵。 歡迎關注!交流眼耀!Star英支!
GitHub:https://github.com/wangyang0313
微信公眾號:一個靈活的胖子MrWang
CSDN:https://blog.csdn.net/qq941263013