工具篇——MoneyFormatUtil(用于将人民币小写金额转换成大写金额)

代码如下:

package com.wy.test.other;

/**

* 人民币格式化工具

* 用于将人民币小写金额转换成大写金额

* 要点:1.区分金额是整数还是小数,需要分开处理;

*       2.将金额数字倒序,便于同单位合并

*       3.异常处理,判断数字中是否含有非法字符,有则return;

*       4.数字中0的处理;

*/

public class MoneyFormatUtil {

    //单位

    private static final char[] UNIT = {'亿', '拾', '佰', '仟', '万', '拾', '佰', '仟'};

    //大写金额模板

    private static final char[] TEMPLATE = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'};

    private String submoneyCN[] = {"", "拾", "佰", "仟"};                                    //表示数字位数的数组

    private String numberCNN[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};    //大写数字的数组

    private static MoneyFormatUtil instance;

    /**

     * 获取类的实例

     *

     * @return 类的实例

     */

    public static MoneyFormatUtil getInstance() {

        if (instance == null) {

            instance = new MoneyFormatUtil();

        }

        return instance;

    }

    /**

     * 将人民币小写金额转换成大写金额

     *

     * @return 转换后的大写金额

     */

    public String convert(String money) {

        String formatCN = "";

        int point = money.indexOf(".");                //判断字符串是否包含小数点(不包含返回-1)

        if (point != -1) {//包含小数点的情况

            formatCN = decimalConversion(money, point);

        } else {

            formatCN = integerConversion(money);

        }

        return formatCN;

    }

    /**

     * 小数转换

     *

     * @param decimalString 小数字符串(例:1234567.89  壹佰贰拾叁万肆仟伍佰陆拾柒元捌角玖分)

     * @param pointPosition 小数点在字符串中的位置

     * @return 转换后的大写金额

     */

    private String decimalConversion(String decimalString, int pointPosition) {

        String formatDecimalString = "";

        String money1 = decimalString.substring(0, pointPosition);    //小数点之前的部分

        String money1_1 = (new StringBuffer(money1).reverse()).toString();//字符串倒序

        String money2 = decimalString.substring(pointPosition + 1);    //小数点之后的部分

        //异常处理

        for (int i = 0; i < money1.length(); i++) {

            if (!Character.isDigit(money1.charAt(i))) {

                return "数字中含有非法字符";

            }

        }

        for (int i = 0; i < money2.length(); i++) {

            if (!Character.isDigit(money2.charAt(i))) {

                return "数字中含有非法字符";

            }

        }

        if (money2.length() < 2) {                    //如果小数点后的部分少于两位,用"0"补齐

            if (money2.length() == 0) {

                money2 = "00";

            } else {

                money2 += "0";

            }

        } else {

            //如果小数点后的位数大于2位,则只前2位

            money2 = decimalString.substring(pointPosition + 1, pointPosition + 3);

        }

        int len = money1_1.length();            //字符串反转之后,小数点之前的字符位数

        int pos = len - 1;

        String sigle = "";

        boolean allhavenum = false;

        boolean havenum = false;

        boolean mark = false;                    //设置一个开关变量,若当前数为"0",将该值设为true;不为"0"时设为false

        /**以下代码为读出小数点左面的部分*/

        while (pos >= 0) {

            sigle = money1_1.substring(pos, pos + 1);//截取1位数字,比如数字1234.56,将左侧的字符串反转,值为4321,则截取的值为1

            /**读取“亿单元”的代码。

             * 假设读取10024531042.34。

             * 小数点左面反转后为:24013542001

             * pos的初始值为10

             * mark的初始值为false

             * havenum的初始值为false

             * */

            if (pos >= 8 && pos < 12) {

                if (!sigle.equals("0")) {         //如果当前值不为"0"

                    if (!mark) {                 //如果当前值的前一位数不为"0"

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                    } else {                         //如果当前值不为"0",但该值的前一位数为"0"

                        if (allhavenum) {             //如果在当前值之前有不为"0"的数字出现。该条件用来处理用户输入的如:0012.34的数值

                            formatDecimalString += "零";

                        }

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                        mark = false;

                    }

                    havenum = true;

                    allhavenum = true;            //变量allhavenum表示小数点左面的数中是否有不为"0"的数字;true表示有,false表示无

                } else {                            //如果当前值为"0"

                    mark = true;

                }

                if (pos % 4 == 0 && havenum) {            //如果当前数字为该单元的最后一位,并且该单元中有不为"0"的数字出现

                    formatDecimalString += "亿";

                    havenum = false;

                }

            }

            /**读取“万单元”的代码*/

            if (pos >= 4 && pos < 8) {

                if (!sigle.equals("0")) {

                    if (!mark) {

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                    } else {

                        if (allhavenum) {

                            formatDecimalString += "零";

                        }

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                        mark = false;

                    }

                    havenum = true;

                    allhavenum = true;

                } else {

                    mark = true;

                }

                if (pos % 4 == 0 && havenum) {

                    formatDecimalString += "万";

                    havenum = false;

                }

            }

            /**读取“个、十、百、千”的代码*/

            if (pos >= 0 && pos < 4) {

                if (!sigle.equals("0")) {

                    if (!mark) {

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                    } else {

                        if (allhavenum) {

                            formatDecimalString += "零";

                        }

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                        mark = false;

                    }

                    havenum = true;

                    allhavenum = true;

                } else {

                    mark = true;

                }

            }

            pos--;

        }

        /**碰到小数点时的读法*/

        if (allhavenum) { //如:00.34就不能读为:元3角4分.变量allhavenum表示小数点左面的内容中是否有数字出现

            formatDecimalString += "元";

        } else {//如果小数点左面的部分都为0如:00.34应读为:零元3角4分

            formatDecimalString = "零元";

        }

        /**以下代码为读出小数点右面的部分 */

        if (money2.equals("00")) {

            formatDecimalString += "整";

        } else {

            /**读出角,如120.34读为:1佰2拾元零3角4分;123.04读为:1佰2拾3元零4分*/

//                if(money2.startsWith("0")||(allhavenum&&money1.endsWith("0"))){

//                    formatCN+="零";

//                }

            if (!money2.startsWith("0")) {

                formatDecimalString += numberCNN[Integer.parseInt(money2.substring(0, 1))] + "角";

            }

            //读出分,如:12.30读1拾2元3角零分

            formatDecimalString += numberCNN[Integer.parseInt(money2.substring(1))] + "分";

        }

        return formatDecimalString;

    }

    /**

     * 整数转换

     *

     * @param integerString 整数字符串(例:123456789   壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元整)

     * @return 转换后的大写金额

     */

    private String integerConversion(String integerString) {

        //用来存放转换后的大写数字,因为是StringBuffer类型,所以顺便把没有转换

        //的数字倒序排列一下,省一个变量.

        StringBuffer ChineseCharI = new StringBuffer(integerString);

        //倒序的数字,便于同单位合并

        String rintString = ChineseCharI.reverse().toString();

        //清空一下

        ChineseCharI.delete(0, ChineseCharI.length());

        //单位索引

        int unitIndex = 0;

        //数字长度

        int intStringLen = integerString.length();

        //一位由字符转换的数字

        int intStringnumber = 0;

        //补0

        boolean addZero = false;

        boolean flagZero = false;

        for (int i = 0; i < intStringLen; i++) {

            //按单位长度循环索引

            unitIndex = i % UNIT.length;

            //异常处理

            if (!Character.isDigit(rintString.charAt(i))) {

                return "数字中含有非法字符";

            }

            //将字符转为数字,范围为10以内(不包括10,超出则返回-1)

            intStringnumber = Character.digit(rintString.charAt(i), 10);

            //如果当前位是0,开启补0继续循环直到不是0的位

            if (intStringnumber == 0) {

                addZero = true;

                if (i != 0 && i % 4 == 0) {

                    if (addZero && ChineseCharI.length() != 0) {

                        ChineseCharI.append(TEMPLATE[0]);

                        addZero = false;

                    }

                    flagZero = true;

                    ChineseCharI.append(UNIT[unitIndex]);

                }

            } else {

                //若当前位不是第一位且补0开启

                if (addZero && ChineseCharI.length() != 0 && !flagZero) {

                    ChineseCharI.append(TEMPLATE[0]);

                }

                flagZero = false;

                //插入单位

                //个位数后面不需要单位

                if (i > 0) {

                    ChineseCharI.append(UNIT[unitIndex]);

                }

                //插入大写数字

                ChineseCharI.append(TEMPLATE[intStringnumber]);

                //补0关闭

                addZero = false;

            }

        }

        //异常处理

        if (ChineseCharI.length() == 0) {

            return "零";

        }

        return ChineseCharI.reverse().toString() + "元整";

    }

}

在项目中的应用:

String convert = MoneyFormatUtil.getInstance().convert("1234567.89");

String convert1 = MoneyFormatUtil.getInstance().convert("1.34");

String convert2 = MoneyFormatUtil.getInstance().convert("100.34");

String convert3 = MoneyFormatUtil.getInstance().convert("34f5460.34");

String convert4 = MoneyFormatUtil.getInstance().convert("10000.34");

String convert5 = MoneyFormatUtil.getInstance().convert("100000.34f");

String convert6 = MoneyFormatUtil.getInstance().convert("1003430000.34");

String convert7 = MoneyFormatUtil.getInstance().convert("1101010101.34");

String convert8 = MoneyFormatUtil.getInstance().convert("1010101010.34");

早计划,早准备,早完成。 欢迎关注!交流!Star!

GitHub:https://github.com/wangyang0313

微信公众号:一个灵活的胖子MrWang

CSDN:https://blog.csdn.net/qq941263013

20200430145304899.jpg

你可能感兴趣的:(工具篇——MoneyFormatUtil(用于将人民币小写金额转换成大写金额))