最近接到一个任务,要去把普通的数值带着单位转大写人民币金额,例如:5.2 万元
转为大写:伍万贰仟元
,这其中可以拆解为两个任务,一个是数值转人民币大写,还有一个就是把单位体现进来,为了解耦合,我决定把逻辑分为两部分处理:
- 只进行数值转大写人民币,不关心单位
- 拿到数值后*单位,然后进行冗余0的去除,再调用数值转大写人民币方法
接下里就是实现过程:
MoneyConvert 全部代码实现类
package com.example.springboot.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; /** * 金额转换 */ public class MoneyConvert { /** * 整数部分单位 */ static String[] cashUnitLeft = {"元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万"}; /** * 小数部分单位 */ static String[] cashUnitRight = {"角", "分", "厘"}; /** * 大写数字 */ static String[] upperNumber = {"零", "壹", "贰", "弎", "肆", "伍", "陆", "柒", "捌", "玖"}; /** * 移除所有BigDecimal的废弃补0 * * @param money the money * @return the big decimal */ public static BigDecimal removeAmtLastZero(BigDecimal money) { String strMoney = money.toString(); if (strMoney.indexOf('.') != -1) { String[] arr = strMoney.split("\\."); String strDecimals = arr[1]; List<String> list = new ArrayList<>(); boolean isCanAdd = false; for (int i = strDecimals.length() - 1; i > -1; i--) { String ss = String.valueOf(strDecimals.charAt(i)); if (!ss.equals("0")) { isCanAdd = true; } if (!ss.equals("0") || isCanAdd) { list.add(ss); } } StringBuilder strZero = new StringBuilder(); for (int i = list.size() - 1; i > -1; i--) { strZero.append(list.get(i)); } strMoney = String.format("%s.%s", arr[0], strZero); } return new BigDecimal(strMoney); } /** * 金额转换 * * @param money the money * @return the string */ public static String convert(BigDecimal money) { String moneyString = money.toString(); try { if (moneyString.contains(".")) { //把数值分为整数型和带小数的数值分开处理。 String left = moneyString.substring(0, moneyString.indexOf(".")); String right = moneyString.substring(moneyString.indexOf(".") + 1); return convertLeft(left) + convertRight(right); } else { return convertLeft(moneyString); } } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); System.out.println("请输入转换范围内现金"); return null; } } /** * 整数部分金额转换 * * @param left the money * @return the string */ private static String convertLeft(String left) { //根据单位'亿','万','元',把整数部分分为3种情况处理 int length = left.length(); //金额在千元以内 if (length <= 4) { //金额为'0'元时的特殊情况 if (length == 1 && Integer.parseInt(left) == 0) { return "零元"; } return convertPart(left, length); } else if (length <= 8) { //金额在千万元以内 String part1 = left.substring(0, length - 4); String part2 = left.substring(length - 4, length); String result1 = convertPart(part1, length); String result2 = convertPart(part2, 4); return result1 + result2; } else if (length <= 12) { //金额在千亿元以内 String part1 = left.substring(0, length - 8); //截取单位为'亿'部分数值。 String part2 = left.substring(length - 8, length - 4); //截取单位为'万'部分数值。 String part3 = left.substring(length - 4, length); //截取单位为'元'部分数值。 String result1 = convertPart(part1, length); //转换单位为'亿'部分数值。 String result2 = convertPart(part2, 8); //转换单位为'万'部分数值。 String result3 = convertPart(part3, 4); //转换单位为'元'部分数值。 String result = result1 + result2 + result3; return result; } else { throw new IllegalArgumentException("超出转换数值范围!"); } } /** * 小部分金额转换 * * @param right the money * @return the string */ private static String convertRight(String right) { String result = ""; for (int i = 0; i < right.length(); i++) { String detail = right.substring(i, i + 1); int value = Integer.parseInt(detail); String number = upperNumber[value]; String unit = cashUnitRight[i]; result = result.concat(number).concat(unit); } result = result.replaceAll("零角", "").replaceAll("零分", "").replaceAll("零厘", ""); return result; } /** * 具体金额转换 * * @param part the money * @param position the money * @return the string */ private static String convertPart(String part, int position) { String result = ""; //用于排除单位为'万'时,四位数值均为'0'的情况 if (part.equals("0000") && position == 8) { return ""; } for (int i = 0; i < part.length(); i++) { int value = Integer.parseInt(String.valueOf(part.charAt(i))); String number = upperNumber[value]; String unit = cashUnitLeft[position - 1 - i]; result = result.concat(number).concat(unit); } //把单位'亿','万','元'放到最后替换 result = result.replaceAll("零仟", "零").replaceAll("零佰", "零") .replaceAll("零拾", "零").replaceAll("零零", "零") .replaceAll("零零", "零").replaceAll("零亿", "亿") .replaceAll("零万", "万").replaceAll("零元", "元"); return result; } }
单元测试,测试金额转写
package com.example.springboot; import com.example.springboot.service.MoneyConvert; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.math.BigDecimal; /** * * @Name MoneyConvertTest * * @Description * * @author tianmaolin * * @Date 2022/2/25 */ @SpringBootTest public class MoneyConvertTest { @Test public void moneyConvertTest() { //1 准备数据,金额值以及金额单位,金额单位为万时,值为10000 BigDecimal money_one = new BigDecimal("0.2343678"); BigDecimal money_two = new BigDecimal("5.2"); BigDecimal money_three = new BigDecimal("500.00000"); BigDecimal unit = new BigDecimal("10000"); //2 数字转大写人民币前进行预处理 System.out.println("Before convert:" + money_one + "," + money_two + "," + money_three); System.out.println("Before convert with unit:" + money_one.multiply(unit) + "," + money_two.multiply(unit) + "," + money_three.multiply(unit)); System.out.println("Before convert with unit remove 0:" + MoneyConvert.removeAmtLastZero(money_one.multiply(unit)) + "," + MoneyConvert.removeAmtLastZero(money_two.multiply(unit)) + "," + MoneyConvert.removeAmtLastZero(money_three.multiply(unit))); //2 金额转写逻辑 String result_one = MoneyConvert.convert(MoneyConvert.removeAmtLastZero(money_one.multiply(unit))); String result_two = MoneyConvert.convert(MoneyConvert.removeAmtLastZero(money_two.multiply(unit))); String result_three = MoneyConvert.convert(MoneyConvert.removeAmtLastZero(money_three.multiply(unit))); System.out.println("After convert result_one:" + result_one); System.out.println("After convert result_two:" + result_two); System.out.println("After convert result_three:" + result_three); } }
测试结果如下
Before convert:0.2343678,5.2,500.00000 Before convert with unit:2343.6780000,52000.0,5000000.00000 Before convert with unit remove 0:2343.678,52000,5000000 After convert result_one:贰仟弎佰肆拾弎元陆角柒分捌厘 After convert result_two:伍万贰仟元 After convert result_three:伍佰万元