ChineseNumber.java 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package com.behosoft.util;
  2. public class ChineseNumber {
  3. // 字符串中存在多个'零'在一起的时候只读出一个'零',并省略多余的单位
  4. static String chnLetter[] = { "零", "一", "二", "三", "四", "五", "六", "七", "八",
  5. "九" };
  6. private String num;
  7. public static String getSingleChinese(int n) {
  8. String letter = "";
  9. if (n < 10 && n > -1) {
  10. letter = chnLetter[n];
  11. }
  12. return letter;
  13. }
  14. public ChineseNumber(double number) {
  15. num = number + "";
  16. }
  17. public ChineseNumber(int number) {
  18. num = number + "";
  19. }
  20. public ChineseNumber(float number) {
  21. num = number + "";
  22. }
  23. /**
  24. * 判断用户输入的数据是否合法,用户只能输入大于零的数字,不能输入其它字符
  25. *
  26. * @param s
  27. * String
  28. * @return 如果用户输入数据合法,返回 true,否则返回 false
  29. */
  30. private boolean checkNum() {
  31. // 如果用户输入的数里有非数字字符,则视为非法数据,返回 false
  32. try {
  33. float f = Float.valueOf(num);
  34. // 如果这个数小于零则视为非法数据,返回 false
  35. if (f < 0) {
  36. System.out.println("非法数据,请检查!");
  37. return false;
  38. } else {
  39. return true;
  40. }
  41. } catch (NumberFormatException e) {
  42. System.out.println("非法数据,请检查!");
  43. return false;
  44. }
  45. }
  46. /**
  47. * 把用户输入的数以小数点为界分割开来,并调用 numFormat() 方法 进行相应的中文金额大写形式的转换 注:传入的这个数应该是经过
  48. * roundString() 方法进行了四舍五入操作的
  49. *
  50. * @param s
  51. * String
  52. * @return 转换好的中文金额大写形式的字符串
  53. */
  54. public String num2RMB() {
  55. // 如果传入的是空串则继续返回空串
  56. if (!checkNum()) {
  57. return "";
  58. } else {
  59. roundString();
  60. // 以小数点为界分割这个字符串
  61. int index = num.indexOf(".");
  62. // 截取并转换这个数的整数部分
  63. String intOnly = num.substring(0, index);
  64. String part1 = this.numFormat(1, intOnly);
  65. // 截取并转换这个数的小数部分
  66. String smallOnly = num.substring(index + 1);
  67. String part2 = this.numFormat(2, smallOnly);
  68. // 把转换好了的整数部分和小数部分重新拼凑一个新的字符串
  69. String newS = part1 + part2;
  70. String str = cleanZero(newS);
  71. return str;
  72. }
  73. }
  74. /**
  75. * 对传入的数进行四舍五入操作
  76. *
  77. * @param s
  78. * String 从命令行输入的那个数
  79. * @return 四舍五入后的新值
  80. */
  81. private String roundString() {
  82. // 如果传入的是空串则继续返回空串
  83. if ("".equals(num)) {
  84. return "";
  85. }
  86. // 将这个数转换成 double 类型,并对其进行四舍五入操作
  87. double d = Double.parseDouble(num);
  88. // 此操作作用在小数点后两位上
  89. d = (d * 100 + 0.5) / 100;
  90. // 将 d 进行格式化
  91. num = new java.text.DecimalFormat("##0.000").format(d);
  92. // 以小数点为界分割这个字符串
  93. int index = num.indexOf(".");
  94. // 这个数的整数部分
  95. String intOnly = num.substring(0, index);
  96. // 规定数值的最大长度只能到万亿单位,否则返回 "0"
  97. if (intOnly.length() > 13) {
  98. System.out.println("输入数据过大!(整数部分最多13位!)");
  99. return "";
  100. }
  101. // 这个数的小数部分
  102. String smallOnly = num.substring(index + 1);
  103. // 如果小数部分大于两位,只截取小数点后两位
  104. if (smallOnly.length() > 2) {
  105. String roundSmall = smallOnly.substring(0, 2);
  106. // 把整数部分和新截取的小数部分重新拼凑这个字符串
  107. num = intOnly + "." + roundSmall;
  108. }
  109. return num;
  110. }
  111. /**
  112. * 把传入的数转换为中文金额大写形式
  113. *
  114. * @param flag
  115. * int 标志位,1 表示转换整数部分,0 表示转换小数部分
  116. * @param s
  117. * String 要转换的字符串
  118. * @return 转换好的带单位的中文金额大写形式
  119. */
  120. private String numFormat(int flag, String s) {
  121. int sLength = s.length();
  122. // 货币大写形式
  123. String bigLetter[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
  124. // 货币单位
  125. String unit[] = { "元", "拾", "佰", "仟", "万",
  126. // 拾万位到仟万位
  127. "拾", "佰", "仟",
  128. // 亿位到万亿位
  129. "亿", "拾", "佰", "仟", "万" };
  130. String small[] = { "分", "角" };
  131. // 用来存放转换后的新字符串
  132. String newS = "";
  133. // 逐位替换为中文大写形式
  134. for (int i = 0; i < sLength; i++) {
  135. if (flag == 1) {
  136. // 转换整数部分为中文大写形式(带单位)
  137. newS = newS + bigLetter[s.charAt(i) - 48]
  138. + unit[sLength - i - 1];
  139. } else if (flag == 2) {
  140. // 转换小数部分(带单位)
  141. newS = newS + bigLetter[s.charAt(i) - 48]
  142. + small[sLength - i - 1];
  143. }
  144. }
  145. return newS;
  146. }
  147. /**
  148. * 把已经转换好的中文金额大写形式加以改进,清理这个字 符串里面多余的零,让这个字符串变得更加可观 注:传入的这个数应该是经过 splitNum()
  149. * 方法进行处理,这个字 符串应该已经是用中文金额大写形式表示的
  150. *
  151. * @param s
  152. * String 已经转换好的字符串
  153. * @return 改进后的字符串
  154. */
  155. private String cleanZero(String s) {
  156. // 如果传入的是空串则继续返回空串
  157. if ("".equals(s)) {
  158. return "";
  159. }
  160. // 如果用户开始输入了很多 0 去掉字符串前面多余的'零',使其看上去更符合习惯
  161. while (s.charAt(0) == '零') {
  162. // 将字符串中的 "零" 和它对应的单位去掉
  163. s = s.substring(2);
  164. // 如果用户当初输入的时候只输入了 0,则只返回一个 "零"
  165. if (s.length() == 0) {
  166. return "零";
  167. }
  168. }
  169. // if(s.length()>0){
  170. // int len=s.length();
  171. // if(s.charAt(len-2)=='零'){
  172. // s=s.substring(0,len-2);
  173. // s= cleanZero(s);
  174. // }
  175. // }
  176. String regex1[] = { "零仟", "零佰", "零拾" };
  177. String regex2[] = { "零亿", "零万", "零元" };
  178. String regex3[] = { "亿", "万", "元" };
  179. String regex4[] = { "零角", "零分" };
  180. // 第一轮转换把 "零仟", 零佰","零拾"等字符串替换成一个"零"
  181. for (int i = 0; i < 3; i++) {
  182. s = s.replaceAll(regex1[i], "零");
  183. }
  184. // 第二轮转换考虑 "零亿","零万","零元"等情况
  185. // "亿","万","元"这些单位有些情况是不能省的,需要保留下来
  186. for (int i = 0; i < 3; i++) {
  187. // 当第一轮转换过后有可能有很多个零叠在一起
  188. // 要把很多个重复的零变成一个零
  189. s = s.replaceAll("零零零", "零");
  190. s = s.replaceAll("零零", "零");
  191. s = s.replaceAll(regex2[i], regex3[i]);
  192. }
  193. // 第三轮转换把"零角","零分"字符串省略
  194. for (int i = 0; i < 2; i++) {
  195. s = s.replaceAll(regex4[i], "");
  196. }
  197. // 当"万"到"亿"之间全部是"零"的时候,忽略"亿万"单位,只保留一个"亿"
  198. s = s.replaceAll("亿万", "亿");
  199. char endChar = s.charAt(s.length() - 1);
  200. if (endChar != '分' && endChar != '角' && endChar != '元') {
  201. s += '元';
  202. }
  203. s += '整';
  204. return s;
  205. }
  206. public static void main(String[] args) {
  207. System.out.println("\n--------将数字转换成中文金额的大写形式------------\n");
  208. ChineseNumber t2r = new ChineseNumber(3240);
  209. String s = t2r.num2RMB();
  210. // 如果转换过后是一个空串,则不输出屏幕
  211. if (!"".equals(s)) {
  212. System.out.println("转换成中文后为:" + s);
  213. ;
  214. }
  215. System.out.println("\n---------------------------------------------");
  216. }
  217. }