以下是一个将阿拉伯数字转换为中文人民币大写的 JavaScript 实现,符合财务规范,支持整数和小数部分(精确到角分):
/**
* 将阿拉伯数字转换为中文人民币大写(财务规范)
* @param {number|string} num - 需要转换的数字
* @returns {string} 转换后的中文大写金额
*/
function numberToChineseCurrency(num) {
// 处理特殊情况
if (num === 0 || num === '0' || num === '0.00') {
return '零元整';
}
// 处理负数
let isNegative = false;
if (typeof num === 'string') {
if (num.startsWith('-')) {
isNegative = true;
num = num.slice(1);
}
// 验证数字格式
if (!/^\d+(\.\d{1,2})?$/.test(num)) {
throw new Error('输入必须是有效的数字,最多保留两位小数');
}
} else if (typeof num === 'number') {
if (num < 0) {
isNegative = true;
num = Math.abs(num);
}
num = num.toFixed(2); // 确保两位小数
} else {
throw new Error('输入类型必须是数字或字符串');
}
// 中文数字字符表
const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
const units = ['', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟'];
const decimalUnits = ['角', '分'];
// 分割整数和小数部分
const [integerPartStr, decimalPartStr = '00'] = String(num).split('.');
const integerPart = parseInt(integerPartStr);
const decimalPart = parseInt(decimalPartStr);
// 转换整数部分
let integerResult = '';
if (integerPart > 0) {
const digitsArray = integerPartStr.split('').reverse();
let zeroFlag = false; // 标记连续的零
for (let i = 0; i < digitsArray.length; i++) {
const digit = parseInt(digitsArray[i]);
const position = i;
if (digit === 0) {
// 零的处理
zeroFlag = true;
// 如果当前位是万、亿单位,且前面有非零数字,添加单位
if (position % 4 === 0 && position > 0) {
integerResult = units[position] + integerResult;
}
} else {
// 非零数字的处理
if (zeroFlag) {
integerResult = '零' + integerResult;
zeroFlag = false;
}
// 添加数字和单位
integerResult = digits[digit] + units[position] + integerResult;
}
}
// 处理可能出现的连续零
integerResult = integerResult.replace(/零+/g, '零');
// 处理末尾的零
integerResult = integerResult.replace(/零+$/g, '');
// 添加"元"字
integerResult += '元';
} else {
integerResult = '零元';
}
// 转换小数部分
let decimalResult = '';
if (decimalPart > 0) {
for (let i = 0; i < decimalPartStr.length; i++) {
const digit = parseInt(decimalPartStr[i]);
if (digit > 0) {
decimalResult += digits[digit] + decimalUnits[i];
}
}
} else {
// 小数部分为零,添加"整"字
decimalResult = '整';
}
// 合并结果
let result = integerResult + decimalResult;
// 处理特殊情况:当整数部分为零且小数部分不为零时,去掉"零元"
if (integerPart === 0 && decimalPart > 0) {
result = result.replace('零元', '');
}
// 添加负号
if (isNegative) {
result = '负' + result;
}
return result;
}
// 示例用法
console.log(numberToChineseCurrency(3242423)); // 叁佰贰拾肆万贰仟肆佰贰拾叁元整
console.log(numberToChineseCurrency(10.5)); // 壹拾元伍角
console.log(numberToChineseCurrency(0.01)); // 壹分
console.log(numberToChineseCurrency(100001.02)); // 壹拾万零壹元零贰分
console.log(numberToChineseCurrency(-50020.3)); // 负伍万零贰拾元叁角
console.log(numberToChineseCurrency(100000000)); // 壹亿元整
核心特性:
财务规范:
- 使用"壹、贰、叁"等大写数字
- 严格遵循人民币大写规则(如零的位置、单位使用)
- 精确到角分,支持"整"字处理
完整处理:
- 支持整数和小数部分
- 处理负数(添加"负"字)
- 处理特殊情况(如零元、角分的零)
输入验证:
- 检查数字有效性
- 限制小数位数为两位
- 处理不同输入类型(数字/字符串)
性能优化:
- 高效的字符串处理
- 避免正则表达式的过度使用
使用场景:
- 财务报表中的金额大写
- 合同、发票等法律文件中的金额书写
- 支付系统中的金额显示
- 银行系统中的票据打印
注意事项:
- 该实现符合中国人民银行《支付结算办法》的规定
- 对于超过万亿的大数,可能需要扩展单位表
- 输入应避免使用科学计数法表示的大数(如
1e9
) - 如需国际化支持,可扩展为支持多种货币单位
这个实现提供了完整的人民币数字转中文大写功能,可直接应用于财务系统或需要金额大写的场景。