从事金融方向,免不了会用到将数字金额转化成大写的地方,没事写了一个挂上来,免得以后找不到。上述代码未经完整测试,只是测试了几个简单的例子,如果发现了问题,请在下面评论留言,本代码为本人原创,可以随意转载,更改,用于商业用途,但若因引用本代码而出现任何问题,本人概不负责。
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 金额工具类
* @author 闵崇建
* @Time 2013-09-25
*
*/
public class AmountUtil {
public static void main(String[] args) throws IOException {
amountOfConversion();
}
public static String ZHENG = "整";
public static String YUAN = "元";
public static String LING = "零";
public static String LINGLING = "零零";
public static String SHI = "拾";
public static String BAI = "佰";
public static String QIAN = "千";
public static String WAN = "万";
public static String YI = "亿";
public static String JIAO = "角";
public static String FEN = "分";
public static String ZEROZERO = "00";
public static String ZERO = "0";
public static String EMPTY = "";
/**
* 阿拉伯数字与大写映射
*/
public static Map<String,String> valueMap = new HashMap<String,String>();
static {
valueMap.put("0", "零");
valueMap.put("1", "壹");
valueMap.put("2", "贰");
valueMap.put("3", "叁");
valueMap.put("4", "肆");
valueMap.put("5", "伍");
valueMap.put("6", "陆");
valueMap.put("7", "柒");
valueMap.put("8", "捌");
valueMap.put("9", "玖");
}
/**
* <p>数字金额转换为中文大写金额<p>
* 本方法支持任意大小的整数部分转化,小数部分只支持两位。
*/
public static void amountOfConversion() {
String amount = "12322.03";
String result = null;
if (amount == null || amount.trim().equals(EMPTY)) {
throw new RuntimeException("amount can not be null or empty!");
}
//判断是否有小数点
String[] usefull = new String[2];
String[] args = amount.split("\\.");
if (args.length == 1) {
usefull[0] = args[0];
}else if (args.length == 2) {
usefull = args;
}
//解析整数部分
result = parseInteger(usefull[0]);
//解析小数部分
result += parseDecimal(usefull[1]);
//整理结果
result = clean(result);
System.out.println("the result to conversion\"" + amount + "\" to large is : " + result);
}
/**
* 清理结果
* @param result
* @return
*/
public static String clean(String result) {
if (result==null || result.trim().equals(EMPTY)) {
throw new RuntimeException("result can not be null or empty!");
}
//相邻之间有多个零,改为只有一个
while (result.contains(LINGLING)) {
result = result.replaceAll(LINGLING, LING);
}
StringBuffer sb = new StringBuffer(result);
//清除元之前的零
int index = sb.indexOf(YUAN);
if (String.valueOf(sb.charAt(index-1)).equals(LING)) {
sb.deleteCharAt(index-1);
}
//第一个数不能为零
if (String.valueOf(sb.charAt(0)).equals(LING)) {
sb.deleteCharAt(0);
}
return sb.toString();
}
/**
* 解析整数部分
* @param integer
* @return
*/
public static String parseInteger(String integer) {
//整数部分长度
int num = integer.length();
//存放最终的大写金额
StringBuffer result = new StringBuffer();
//共有多少个单元(至少有一个)
int sumUnit = num%4==0?num/4:(num/4+1);
//根据单元分组,存放在数组中
String[] arrAmount = new String[sumUnit];
int arrIndex = 0;
StringBuffer temp = new StringBuffer();
for (int i=0;i<num;i++) {
if ((num-i)%4 != 0) {
temp.append(integer.charAt(i));
} else {
arrAmount[arrIndex] = temp.toString();
temp.setLength(0);
arrIndex++;
temp.append(integer.charAt(i));
}
if (i==num-1) {
arrAmount[arrIndex] = temp.toString();
}
}
//逐个单元解析,并组合
for (int i=0;i<=arrIndex;i++) {
String valueTemp = parseUnit(arrAmount[i]);
result.append(valueTemp);
if (!valueTemp.equals(LING)) {
String uintTemp = unitIndexMapping(arrIndex-i);
result.append(uintTemp);
}
}
return result.toString();
}
/**
* 解析一个单位的数字,每4位为一个单位
* @param unit
* @param unitIndex
* @return
*/
public static String parseUnit(String unit) {
if (unit == null || unit.trim().equals(EMPTY)) {
throw new RuntimeException("一个单位的值不能为空!");
}
StringBuffer result = new StringBuffer();
//判断该单元的位数
int num = unit.length();
//判断是否都为零,如果是,直接返回零
StringBuffer sb = new StringBuffer();
for (int i=0;i<num;i++) {
sb.append(ZERO);
}
if (sb.toString().equals(unit)) {
return LING;
}
//开始解析单位
for (int i=0;i<num;i++) {
String temp = getValue(String.valueOf(unit.charAt(i)), num-i-1);
result.append(temp);
//判断后几位是否都为零,如果是,不需要继续操作
String last = unit.substring(i+1);
String compare = "";
for (int j=0;j<last.length();j++) {
compare += ZERO;
}
if (last.equals(compare)) {
return result.toString();
}
}
return result.toString();
}
/**
* 根据值和位置,计算出相关信息
* (这里不知道该怎么注释啊,举个例子,1120,这里传入一个1120的第一个数1,位置为3,就是1千
* 传入第二个数1,位置为2,就是1百)
* @param value
* @param unit
* @return
*/
public static String getValue(String value,int unit) {
StringBuffer result = new StringBuffer();
if (value.equals(ZERO)) {
return valueMap.get(value);
} else {
result.append(valueMap.get(value));
switch (unit) {
case 1:
result.append(SHI);
break;
case 2:
result.append(BAI);
break;
case 3:
result.append(QIAN);
break;
default:
break;
}
return result.toString();
}
}
/**
* 根据单位的索引,映射出单位
* @param unitIndex
* @return
*/
public static String unitIndexMapping(int unitIndex) {
if (unitIndex == 0) {
return YUAN;
} else if (unitIndex%2 == 0) {
return YI;
} else {
return WAN;
}
}
/**
* 解析小数部分(这里的代码有待优化)
* @param integer
* @return
*/
public static String parseDecimal(String decimal) {
if (decimal == null || decimal.trim().equals(EMPTY)) {
return ZHENG;
}
if (decimal.length() > 2) {
throw new RuntimeException("decimal place length can not be more than 2.");
}
if (decimal.equals(ZEROZERO)) {
return ZHENG;
}
if (decimal.length() == 1) {
String one = String.valueOf(decimal.charAt(0));
if (one.equals(ZERO)) {
return ZHENG;
} else {
return valueMap.get(one) + JIAO;
}
}
String one = String.valueOf(decimal.charAt(0));
String two = String.valueOf(decimal.charAt(1));
if (one.equals(ZERO)) {
return valueMap.get(two) + FEN;
}
if (two.equals(ZERO)) {
return valueMap.get(one) + JIAO;
}
return valueMap.get(one) + JIAO + valueMap.get(two) + FEN;
}
}