前端金额转换为人民币大写(5种方法)

当涉及到前端的财务模块有关的时候,比如列表展示、导出、打印发票报表等场景时,我们需要把金额转换为人民币大写

比如:数字:108.12 => 人民币大写:壹佰零捌元壹角贰分

亿
亿

这里有5种常见的方法,逐一介绍如下:

1.递归转换法:


这是一种比较复杂的方法,在每一个单位级别都需要进行递归转换。流程如下:

function convertToRMB(amount) {
    const units = ['元', '十', '百', '千', '万', '十万', '百万', '千万', '亿', '十亿', '百亿', '千亿'];
    const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  
    function convert(num) {
        if (num === 0) {
            return '';
        }
  
        let str = '';
  
        if (num < 10) {
            str = digits[num];
        } else if (num < 20) {
            str = '十' + digits[num - 10];
        } else if (num < 100) {
            str = digits[Math.floor(num / 10)] + '十' + digits[num % 10];
        } else {
            str = digits[Math.floor(num / 100)] + '百' + convert(num % 100);
        }
  
        return str;
    }
  
    const [integerPart, decimalPart] = String(amount).split('.');
    const integerInRMB = convert(parseInt(integerPart));
  
    let result = integerInRMB + '元';
  
    if (decimalPart) {
        result += decimalPart.split('').map(digit => digits[digit]).join('') + '角';
    }
  
    return result;
}

console.log(convertToRMB(108.12));  //壹百捌元壹贰角


2.查表转换法:


这种方法相对简单,事先准备好一个金额与大写的对应表。流程如下:
将金额转换为字符串,并按位拆分为一个数组。
从高位到低位,根据数组中的每一位查表并拼接对应的大写数字(例如0-9对应的大写数字为"零"、“壹”、"贰"等)。
根据小数点位置,对整数部分和小数部分进行拼接。

function convertToRMB(amount) {
    const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
    const units = ['', '拾', '佰', '仟', '万', '拾万', '佰万', '仟万', '亿', '拾亿', '佰亿', '仟亿'];

    const [integerPart, decimalPart] = String(amount).split('.');
    const integerDigits = integerPart.split('').map(digit => digits[parseInt(digit)]);
  
    let result = '';
  
    for (let i = 0; i < integerDigits.length; i++) {
        result += integerDigits[i] + units[integerDigits.length - 1 - i];
    }
  
    if (decimalPart) {
        const decimalDigits = decimalPart.split('').map(digit => digits[parseInt(digit)]);
        result += '点' + decimalDigits.join('');
    }
  
    return result;
}

console.log(convertToRMB(108.12));  //壹佰零拾捌点壹贰


3.数学计算法:


这种方法相比前两种方法更简洁,通过数学计算直接得出结果。流程如下:
将金额保留两位小数,并转换为数值型。
获取整数部分和小数部分。
将整数部分进行数学计算得到相应的大写数字。
将小数部分转换为对应的大写数字。

function convertToRMB(amount) {
    const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];

    const [integerPart, decimalPart] = String(amount.toFixed(2)).split('.');
    const integerDigits = integerPart.split('').map(digit => digits[parseInt(digit)]);
  
    let result = '';
  
    for (let i = 0; i < integerDigits.length; i++) {
        result += integerDigits[i];
    }
  
    if (decimalPart) {
        const decimalDigits = decimalPart.split('').map(digit => digits[parseInt(digit)]);
        result += '点' + decimalDigits.join('');
    }
  
    return result;
}

console.log(convertToRMB(108.12));  //壹零捌点壹贰


4.第3方库的使用:


这是最简单的方法,通过使用前端开发中已经存在的金额转换函数库来实现。流程如下:
在前端项目中引入合适的金额转换函数库。
调用相应的函数传入金额参数,即可得到转换结果。但是呢需要下包,常言鱼与熊掌不可兼得
 

4.1安装number-to-chinese-words

npm install number-to-chinese-words
 使用:
var converter = require('number-to-chinese-words');
converter.toOrdinal(108.12);

将数字转为文字:toWords(number)  

// 整數:
var converter = require('number-to-chinese-words');
converter.toWords(13); // => “十三”
 
// Decimal numbers:
converter.toWords(2.9); // => “二點九”
 
// Negative numbers:
converter.toWords(-3); // => "負三"
 
// Large numbers:
converter.toWords(9007199254740992); // => “九千零七兆一千九百九十二億五千四百七十四萬零九百九十二

将整数转换成文字:toWordsOrdinal(number)

但是会在原来的基础上再加上前置的「第」字。 如果输入的数字包含小数点,小数点后的数目将会被移除。

import converter from "number-to-chinese-words";

converter.toWordsOrdinal(21); // => “第二十一”

 转大写:

var converter = require("number-to-chinese-words")
converter.default.labels = Object.assign({},converter.default.labels, {
  digits : ['零','壹', '貳', '參', '肆', '伍', '陸', '柒', '捌', '玖'],
  units: ['','拾', '佰', '仟', '萬', '拾', '佰', '仟', '億', '拾', '佰', '仟', '兆', '拾', '佰', '仟', '京', '拾', '佰', '仟', '垓']
})
 
converter.toWords(199254740992); 
// => 壹仟玖佰玖拾貳億伍仟肆佰柒拾肆萬零玖佰玖拾貳

 4.2、安装pixiu-number-toolkit(推荐)

pixiu-number-toolkit是一个用TypeScript编写的数字工具集,提供了一组用于数字转换、财务计算、格式化和数学运算的函数。其中就包含了一个名为digitUppercase的函数,可以将数字金额转换为大写的人民币汉字表示。

安装
npm install pixiu-number-toolkit
使用digitUppercase函数进行转换:
import { digitUppercase } from "pixiu-number-toolkit";

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

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

这个函数还可以处理负金额,在结果前加上“欠”。零金额表示为“零元整”。

5.还有一种(推荐):

function transformStr(money) {
  var cnMoney = "零元整";
    var strOutput = "";
    var strUnit = '仟佰拾亿仟佰拾万仟佰拾元角分';
    money += "00";
    var intPos = money.indexOf('.');
    if (intPos >= 0) {
       money = money.substring(0, intPos) + money.substr(intPos + 1, 2);
    }
    strUnit = strUnit.substr(strUnit.length - money.length);
    for (var i = 0; i < money.length; i++) {
       strOutput += '零壹贰叁肆伍陆柒捌玖'.substr(money.substr(i, 1), 1) + strUnit.substr(i, 1);
    }
    cnMoney = strOutput.replace(/零角零分$/, '整').replace(/零[仟佰拾]/g, '零').replace(/零{2,}/g, '零').replace(/零([亿|万])/g, '$1').replace(/零+元/, '元').replace(/亿零{0,3}万/, '亿').replace(/^元/, "零元");
    return cnMoney;
}

// 108.12 => 壹佰零捌元壹角贰分

你可能感兴趣的:(JavaScript,的问题,javascript,前端)