JS人民币数字转换成为中文

发布于:2025-07-26 ⋅ 阅读:(17) ⋅ 点赞:(0)

以下是一个将阿拉伯数字转换为中文人民币大写的 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));   // 壹亿元整

核心特性:

  1. 财务规范

    • 使用"壹、贰、叁"等大写数字
    • 严格遵循人民币大写规则(如零的位置、单位使用)
    • 精确到角分,支持"整"字处理
  2. 完整处理

    • 支持整数和小数部分
    • 处理负数(添加"负"字)
    • 处理特殊情况(如零元、角分的零)
  3. 输入验证

    • 检查数字有效性
    • 限制小数位数为两位
    • 处理不同输入类型(数字/字符串)
  4. 性能优化

    • 高效的字符串处理
    • 避免正则表达式的过度使用

使用场景:

  • 财务报表中的金额大写
  • 合同、发票等法律文件中的金额书写
  • 支付系统中的金额显示
  • 银行系统中的票据打印

注意事项:

  1. 该实现符合中国人民银行《支付结算办法》的规定
  2. 对于超过万亿的大数,可能需要扩展单位表
  3. 输入应避免使用科学计数法表示的大数(如 1e9
  4. 如需国际化支持,可扩展为支持多种货币单位

这个实现提供了完整的人民币数字转中文大写功能,可直接应用于财务系统或需要金额大写的场景。


网站公告

今日签到

点亮在社区的每一天
去签到