原创

金额大小写转换工具类

作者:cndz 围观群众:656 更新于 标签:Java 工具类金额转换工具类

金额大小写转换工具类

package top.jhone.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author zzy
 * @date 2022/11/24 10:30
 */
public class RMBUtil {
    private static final Pattern AMOUNT_PATTERN = Pattern.compile("^(0|[1-9]\\d{0,11})\\.(\\d\\d)$"); // 不考虑分隔符的正确性
    private static final char[] RMB_NUMS = "零壹贰叁肆伍陆柒捌玖".toCharArray();
    private static final String[] UNITS = {"元", "角", "分", "整"};
    private static final String[] U1 = {"", "拾", "佰", "仟"};
    private static final String[] U2 = {"", "万", "亿"};
    private static final String VER = "0123456789.";


    /**
     * 将金额(整数部分等于或少于 12 位,支持两位小数以内)转换为中文大写形式.
     *
     * @param amount 金额数字字符串
     * @return 中文大写
     * @throws IllegalArgumentException
     * @author wk
     * @date 2020/9/9 10:58
     */
    public static String convert2Str(String amount) throws IllegalArgumentException {
        if(amount.endsWith(".")){
           amount = amount.replace(".","");
        }
        if (null == amount || amount.equals("") || amount.trim().equals(""))
            throw new IllegalArgumentException("金额不能为空");
        for (char m : amount.toCharArray()) {
            if (!(VER.indexOf(m) > -1)) throw new IllegalArgumentException("金额不正确,整数部分12 位以内,小数部分两位以内");
        }
        if (amount.split("\\.")[0].length() > 12) throw new IllegalArgumentException("金额不正确,整数部分12 位以内,小数部分两位以内");
        if (!(amount.indexOf(".") > -1)) {
            return integer2rmb(amount) + UNITS[0] + UNITS[3];
        }
        StringBuffer stringBuffer = new StringBuffer(integer2rmb(amount.split("\\.")[0]));
        if (amount.split("\\.")[1].equals("0") || amount.split("\\.")[1].equals("00"))
            return stringBuffer.append(UNITS[3]).toString();
        if (amount.split("\\.").length == 0 || amount.split("\\.")[1].length() == 0)
            throw new IllegalArgumentException("金额不正确,整数部分12 位以内,小数部分两位以内");
        stringBuffer.append(UNITS[0]);
        stringBuffer.append(fraction2rmb(amount.split("\\.")[1]));
        String result = stringBuffer.toString();
        if(result.startsWith("元")){
            result = result.replace("元","");
        }
        if(result.startsWith("圆")){
            result = result.replace("圆","");
        }
        if(result.startsWith("零")){
            result = result.substring(1);
        }
        return result;
    }

    private static String fraction2rmb(String fraction) {
        if (fraction.length() == 0 || fraction.length() > 2) throw new IllegalArgumentException("金额不正确,整数部分12 位以内,小数部分两位以内");
        if (fraction.length() == 1)
            return RMB_NUMS[fraction.charAt(0) - '0'] + (fraction.charAt(0) > '0' ? UNITS[1] : "");
        if (fraction.length() == 2)
            return (RMB_NUMS[fraction.charAt(0) - '0'] + (fraction.charAt(0) > '0' ? UNITS[1] : ""))
                    + (fraction.charAt(1) > '0' ? RMB_NUMS[fraction.charAt(1) - '0'] + UNITS[2] : "");
        return "";
    }

    private static String integer2rmb(String integer) {
        StringBuilder buffer = new StringBuilder();
        int i, j;
        for (i = integer.length() - 1, j = 0; i >= 0; i--, j++) {
            char n = integer.charAt(i);
            if (n == '0') {
                if (i < integer.length() - 1 && integer.charAt(i + 1) != '0') {
                    buffer.append(RMB_NUMS[0]);
                }
                if (j % 4 == 0) {
                    if (i > 0 && integer.charAt(i - 1) != '0' || i > 1 && integer.charAt(i - 2) != '0'
                            || i > 2 && integer.charAt(i - 3) != '0') {
                        buffer.append(U2[j / 4]);
                    }
                }
            } else {
                if (j % 4 == 0) {
                    buffer.append(U2[j / 4]);
                }
                buffer.append(U1[j % 4]);
                buffer.append(RMB_NUMS[n - '0']);
            }
        }
        return buffer.reverse().toString();
    }


    public static String convert2Number(String rmbStr){
        rmbStr = rmbStr.replace("整","").replace("正","").replace("零","");
        if(rmbStr.indexOf("亿亿")>= 0 || rmbStr.indexOf("万万")  > 0 ){
            throw new IllegalArgumentException("大写金额格式错误");
        }

        BigDecimal number =  BigDecimal.ZERO;
        Map<String, BigDecimal> map1 = new HashMap<String, BigDecimal>(); //存放单位map
        map1.put("亿", new BigDecimal("100000000.0"));
        map1.put("万", new BigDecimal("10000.0"));
        map1.put("角", new BigDecimal("0.1"));
        map1.put("分", new BigDecimal("0.01"));
        //判断是否有亿作为单位
        String[] numbers;
        if(rmbStr.indexOf("亿") > 0){
            numbers = rmbStr.split("亿");
            number = number.add(handelRmbStr(numbers[0]).multiply(map1.get("亿")));
            if(numbers.length > 1)  rmbStr = numbers[1];
        }
        if(rmbStr.indexOf("万") > 0){
            numbers = rmbStr.split("万");
            number = number.add(handelRmbStr(numbers[0]).multiply(map1.get("万")));
            if(numbers.length > 1) rmbStr = numbers[1];
        }
        if(rmbStr.indexOf("元") > 0){
            numbers = rmbStr.split("元");
            number = number.add(handelRmbStr(numbers[0]));
            if(numbers.length >1) rmbStr = numbers[1];
        }
        if(rmbStr.indexOf("圆") > 0){
            numbers = rmbStr.split("圆");
            number = number.add(handelRmbStr(numbers[0]));
            if(numbers.length > 1) rmbStr = numbers[1];
        }
        if(rmbStr.indexOf("角") > 0){
            numbers = rmbStr.split("角");
            number = number.add(handelRmbStr(numbers[0]).multiply(map1.get("角")));
            if(numbers.length > 1) rmbStr = numbers[1];
        }
        if(rmbStr.indexOf("分") > 0){
            numbers = rmbStr.split("分");
            number = number.add(handelRmbStr(numbers[0]).multiply(map1.get("分")));
            if(numbers.length > 1){
                throw new IllegalArgumentException("小数部分仅支持到分");
            }
        }


        return number.setScale(2,BigDecimal.ROUND_HALF_UP).toString();
    }


    private static BigDecimal handelRmbStr(String amount){
        BigDecimal result = BigDecimal.ZERO;
        Map<String, BigDecimal> map = new HashMap<String, BigDecimal>(); //存放数字map
        map.put("壹", new BigDecimal("1.0"));
        map.put("贰", new BigDecimal("2.0"));
        map.put("叁", new BigDecimal("3.0"));
        map.put("肆", new BigDecimal("4.0"));
        map.put("伍", new BigDecimal("5.0"));
        map.put("陆", new BigDecimal("6.0"));
        map.put("柒", new BigDecimal("7.0"));
        map.put("捌", new BigDecimal("8.0"));
        map.put("玖", new BigDecimal("9.0"));
        Map<String, BigDecimal> map1 = new HashMap<String, BigDecimal>(); //存放单位map
        map1.put("拾", new BigDecimal("10.0"));
        map1.put("佰", new BigDecimal("100.0"));
        map1.put("仟", new BigDecimal("1000.0"));
        String[] numbers ;
        if(amount.indexOf("仟") > 0){
            numbers = amount.split("仟");
            BigDecimal nu = map.get(numbers[0]);
            if(nu == null) throw new IllegalArgumentException("转换过程发生错误:"+numbers[0]);
            result = result.add(map1.get("仟").multiply(nu));
            if(numbers.length > 1 ) amount = numbers[1];
        }
        if(amount.indexOf("佰") > 0){
            numbers = amount.split("佰");
            BigDecimal nu = map.get(numbers[0]);
            if(nu == null) throw new IllegalArgumentException("转换过程发生错误:"+numbers[0]);
            result = result.add(map1.get("佰").multiply(nu));
            if(numbers.length > 1) amount = numbers[1];
        }
        if(amount.indexOf("拾") > 0){
            numbers = amount.split("拾");
            BigDecimal nu = map.get(numbers[0]);
            if(nu == null) throw new IllegalArgumentException("转换过程发生错误:"+numbers[0]);
            result = result.add(map1.get("拾").multiply(nu));
            if(numbers.length > 1) amount = numbers[1];
        }
        if(map.get(amount) != null)
        result = result.add(map.get(amount));
        return result;

    }

    public static void main(String[] args) {
        System.out.println(convert2Str("111111111111.11"));
        System.out.println(convert2Number("壹佰壹拾壹k亿壹仟壹佰壹拾肆万亿肆仟肆佰肆拾肆亿壹仟壹佰壹拾壹万壹仟壹佰壹拾壹元整"));
    }





}