当涉及到前端的财务模块有关的时候,比如列表展示、导出、打印发票报表等场景时,我们需要把金额转换为人民币大写
比如:数字: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.还有一种(推荐):
functiontransformStr(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 => 壹佰零捌元壹角贰分
版权归原作者 じòぴé南冸じょうげん 所有, 如有侵权,请联系我们删除。