1 package cc.boazy.vicp.util; 2 3 import java.math.BigDecimal; 4 import java.math.BigInteger; 5 import java.util.HashSet; 6 import java.util.Set; 7 8 /** 9 * 10 * @author Boazy 11 * @date 2012-12-4 12 */ 13 public class AmountUtil 14 { 15 /** 16 * 定义中文零到玖常量数组 以数组索引对应对应的中文大写数 17 */ 18 private static final char[] NUM_CAPITALS = {'零', '壹', '贰', '参', '肆', '伍', '陆', '柒', '捌', '玖'}; 19 20 /** 21 * 定义中文单位 22 */ 23 private static final char[] AMOUNT_UNITS = {'分', '角', '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟', 24 '万', '兆', '拾', '佰', '仟', '万', '亿'}; 25 26 /** 27 * 定义元万亿兆的索引 28 */ 29 private static final Set<Integer> YWYZ_INDEX = new HashSet<Integer>(); 30 31 static 32 { 33 YWYZ_INDEX.add(2); 34 YWYZ_INDEX.add(6); 35 YWYZ_INDEX.add(10); 36 YWYZ_INDEX.add(15); 37 } 38 39 /** 40 * 将阿拉伯数转为中文大写 41 * 42 * @param amount 阿拉伯数字符 (1051.08) 43 * @return 转换后的中文大写数 (壹仟零伍拾壹元零捌分) 44 */ 45 public static String toChineseCapital(String amount) 46 { 47 // 如果为空或等于零则返回空 48 if (null == amount || amount.length() == 0) 49 { 50 return null; 51 } 52 53 // 将浮点型字符分隔为数组,索引为0的为整数部分、为1的为小数部分 54 String[] zx = amount.split("\\."); 55 int zxLen = zx.length; 56 // 将amount拼成一个纯数的字符 57 // 如1234→12300,1234.1→123410,1234.01→123401,1234.1254→123412 58 StringBuilder aStr = new StringBuilder(); 59 if (zxLen >= 1) 60 { 61 aStr.append("".equals(zx[0]) ? "0" : zx[0]); 62 } 63 if (zxLen >= 2) 64 { 65 switch (zx[1].length()) 66 { 67 case 0: 68 aStr.append("00"); 69 break; 70 case 1: 71 aStr.append(zx[1]).append("0"); 72 break; 73 case 2: 74 aStr.append(zx[1]); 75 break; 76 default: 77 aStr.append(zx[1].substring(0, 2)); 78 break; 79 } 80 } 81 else 82 { 83 aStr.append("00"); 84 } 85 86 // 当要处理的字符串已大于单位所能容纳,就抛算术异常 87 if (aStr.length() > AMOUNT_UNITS.length) 88 { 89 throw new ArithmeticException("已大于单位所能容纳"); 90 } 91 92 // 定义保存中文数的字符串变量 93 StringBuilder chineseStr = new StringBuilder(); 94 // 将字符转为大整数 95 BigInteger big = new BigInteger(aStr.toString()); 96 // 单位索引,初始为0 97 int unitIndex = 0; 98 /* 99 * 循环从个位开始处理每个数转为中文大写 bi为每次循环后除10取整,当bi为0时处理结束 100 */ 101 for (BigInteger bi = big; !"0".equals(bi.toString()); bi = bi.divide(BigInteger.TEN)) 102 { 103 byte gw = bi.remainder(BigInteger.TEN).byteValue(); 104 105 int cStrLen = chineseStr.length(); 106 107 // gw不等于0 或 在指的在单位索引上,就添加单位 108 if (0 != gw || YWYZ_INDEX.contains(unitIndex)) 109 { 110 chineseStr.append(AMOUNT_UNITS[unitIndex]); 111 112 String xx = cStrLen < 2 ? null : chineseStr.substring(cStrLen - 1); 113 if("万亿".equals(xx) || "亿兆".equals(xx)) 114 { 115 chineseStr.delete(cStrLen - 1, cStrLen); 116 } 117 } 118 119 /* 120 * 如果个位数等于0时根据内层if过滤,否则直接添加中文数 121 */ 122 if (0 == gw) 123 { 124 // 定义中文字符中最后一个字符变量 125 String lastStr = null; 126 if (chineseStr.length() > 0) 127 { 128 lastStr = chineseStr.substring(chineseStr.length() - 1); 129 } 130 131 /* 132 * 如果最后一个字符不等于单位索引为2、6、10、16的字符, 并且等于"零",就添加中文数"零" 133 * 并且lastStr不等于null 134 */ 135 if (null != lastStr && !lastStr.equals(String.valueOf(NUM_CAPITALS[0])) 136 && !lastStr.equals(String.valueOf(AMOUNT_UNITS[2])) 137 && !lastStr.equals(String.valueOf(AMOUNT_UNITS[6])) 138 && !lastStr.equals(String.valueOf(AMOUNT_UNITS[10])) 139 && !lastStr.equals(String.valueOf(AMOUNT_UNITS[15]))) 140 { 141 chineseStr.append(NUM_CAPITALS[gw]); 142 } 143 } 144 else 145 { 146 chineseStr.append(NUM_CAPITALS[gw]); 147 } 148 149 // 每次循环后单位索引自增1 150 unitIndex++; 151 } 152 153 /* 154 * 此处已转换完成,将字符串反序后取最后一个字符判断是否等于"元" 是表示为整数就作处理,在反序后的中文字符最后加一个字符"整" 155 */ 156 if (chineseStr.reverse().substring(chineseStr.length() - 1).equals(String.valueOf(AMOUNT_UNITS[2]))) 157 { 158 chineseStr.append("整"); 159 } 160 161 return chineseStr.toString(); 162 } 163 164 public static String toChineseCapital(double amount) 165 { 166 return toChineseCapital(BigDecimal.valueOf(amount).toString()); 167 } 168 169 public static String toChineseCapital(float amount) 170 { 171 return toChineseCapital(BigDecimal.valueOf(amount).toString()); 172 } 173 }