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 }