JavaScript中金额转为中文大写

200 阅读3分钟

使用npm包或方法实现金额转为中文大写

先使用插件的方式

  1. 首先去npm官网中搜索pixiu-number-toolkit ,然后使用npm install pixiu-number-toolkit -S安装到项目中,-S的作用是安装插件到生产环境,如果不加或者是加的-D则只会安装到开发环境,项目上线后是找不到这个插件的。
  2. 可以看到这里有一个中文文档,点击进去可以看到相关的api

image.png 或者点击直接跳转到官方文档

  1. 找到这个方法digitUppercase
  2. 根据官方提供的示例引入api,然后就可以直接使用了
import { digitUppercase } from "pixiu-number-toolkit";

const amount = 1234.56;
const result = digitUppercase(amount);

console.log(result);
// 输出: "壹仟贰佰叁拾肆元伍角陆分"

详细的使用方法可以参考文档

注意事项:这个插件编译后的代码包里面,使用了一些高级语法和api,然后就导致了在App项目中使用H5页面,H5页面无法正常解析这些语法和Api导致报错(这就是我遇到的坑),所以有了这篇文章和下面的手写方法。

手写实现金额转中文大写

为了兼容低版本手机的浏览器内核,就不能使用npm包的方式了,于是在网上找了找相关的问题,大概写了一个方法

/**
     * 兼容低版本浏览器使用的方法
     * @param money 需要转换的金额(数字),最大 999999999999999.9999
     * @returns 转换后的中文大写
     */
    numberToChinese(money) {
        let cnNums = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"); //汉字的数字
        let cnIntRadice = new Array("", "拾", "佰", "仟"); //基本单位
        let cnIntUnits = new Array("", "万", "亿", "兆"); //对应整数部分扩展单位
        let cnDecUnits = new Array("角", "分", "毫", "厘"); //对应小数部分单位
        let cnInteger = "整"; //整数金额时后面跟的字符
        let cnIntLast = "元"; //整型完以后的单位
        let maxNum = 999999999999999.9999; //最大处理的数字
        let IntegerNum; //金额整数部分
        let DecimalNum; //金额小数部分
        let ChineseStr = ""; //输出的中文金额字符串
        let parts; //分离金额后用的数组,预定义
        let Symbol = ""; //正负值标记
        if (money == "") {
            return "";
        }

        money = parseFloat(money);
        if (money >= maxNum) {
            alert('超出最大处理数字');
            return "";
        }
        if (money == 0) {
            ChineseStr = cnNums[0] + cnIntLast + cnInteger;
            return ChineseStr;
        }
        if (money < 0) {
            money = -money;
            Symbol = "负 ";
        }
        money = money.toString(); //转换为字符串
        if (money.indexOf(".") == -1) {
            IntegerNum = money;
            DecimalNum = '';
        } else {
            parts = money.split(".");
            IntegerNum = parts[0];
            DecimalNum = parts[1].substr(0, 4);
        }
        if (parseInt(IntegerNum, 10) > 0) { //获取整型部分转换
            let zeroCount = 0;
            let IntLen = IntegerNum.length;
            for (let i = 0; i < IntLen; i++) {
                let n = IntegerNum.substr(i, 1);
                let p = IntLen - i - 1;
                let q = p / 4;
                let m = p % 4;
                if (n == "0") {
                    zeroCount++;
                } else {
                    if (zeroCount > 0) {
                        ChineseStr += cnNums[0];
                    }
                    zeroCount = 0; //归零
                    ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
                }
                if (m == 0 && zeroCount < 4) {
                    ChineseStr += cnIntUnits[q];
                }
            }
            ChineseStr += cnIntLast;
            //整型部分处理完毕
        }
        if (DecimalNum != '') { //小数部分
            let decLen = DecimalNum.length;
            for (let i = 0; i < decLen; i++) {
                let n = DecimalNum.substr(i, 1);
                if (n != '0') {
                    ChineseStr += cnNums[Number(n)] + cnDecUnits[i];
                }
            }
        }
        if (ChineseStr == '') {
            ChineseStr += cnNums[0] + cnIntLast + cnInteger;
        } else if (DecimalNum == '') {
            ChineseStr += cnInteger;
        }
        ChineseStr = Symbol + ChineseStr;

        return ChineseStr;
    },

逻辑主要分为处理整数部分和小数部分,处理的逻辑差不多,都是把数字转为字符,然后循环遍历字符的每一位以及后面的长度然后根据中文金额的规则进行分段处理。 大致试了一下,满足我的需求,也能处理负数的情况。

个人见解只是记录一下遇到的问题,欢迎讨论