查看: 132|回复: 1

JavaScript金额格式化:元转万元函数实现与单位自适应封装

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在财务数据展示、报表统计或大屏看板中,经常需要将金额从“元”转换为“万元”为单位显示,同时还可能要求保留特定位数、添加千分位分隔符或自适应更大的单位(亿、兆等)。以下整理了几种基于原生JavaScript的实现方式,从简单除法到通用工具函数,方便按需选用。

基础转换:直接除法并保留小数

最简单的做法是将金额除以10000,得到万元数值。如果只需保留两位小数,调用 toFixed(2) 即可:
  1. function yuanToWanSimple(amount) {
  2.   return (amount / 10000).toFixed(2);
  3. }
  4. console.log(yuanToWanSimple(123456)); // "12.35"
复制代码

注意 toFixed 返回字符串,且会四舍五入。若担心浮点精度误差,可以先除再使用 Math.round 定点舍入。

带千分位分隔符的格式化

使用 toLocaleString 可以快速获得包含逗号分隔的数值字符串,并指定小数位数:
  1. function yuanToWanLocale(amount) {
  2.   const wan = amount / 10000;
  3.   return wan.toLocaleString('zh-CN', {
  4.     minimumFractionDigits: 2,
  5.     maximumFractionDigits: 2
  6.   });
  7. }
  8. console.log(yuanToWanLocale(12345678)); // "1,234.57"
复制代码

该方法依赖浏览器对 locale 的支持,不同环境输出可能略有差异。

利用 Intl.NumberFormat 实现完全本地化

如果需要更精细的控制,可以创建 Intl.NumberFormat 实例,指定为十进制格式并手动追加单位符号“万”:
  1. function yuanToWanIntl(amount) {
  2.   const formatter = new Intl.NumberFormat('zh-CN', {
  3.     style: 'decimal',
  4.     minimumFractionDigits: 2,
  5.     maximumFractionDigits: 2
  6.   });
  7.   return formatter.format(amount / 10000) + '万';
  8. }
  9. console.log(yuanToWanIntl(123456)); // "12.35万"
复制代码

如果要显示货币符号(如¥),可改用 style: 'currency' 并传入 unitRatio,但货币格式不直接支持“万元”概念,因此手动拼接更实用。

自适应单位的通用封装

实际开发中,金额可能达到亿、兆甚至更大,需要自动选择单位。以下函数采用单位数组(元、万元、亿、兆……),每次长度超过4位就除以10000并切换到下一级,最终返回数值与单位:
  1. function formatMoney(amount) {
  2.   const units = ["元", "万元", "亿", "兆", "京", "垓", "杼"];
  3.   let strnum = amount.toString();
  4.   let unit = '';
  5.   units.find((item, index) => {
  6.     let newNum = strnum.indexOf('.') !== -1
  7.       ? strnum.substring(0, strnum.indexOf('.'))
  8.       : strnum;
  9.     if (newNum.length < 5) {
  10.       unit = item;
  11.       return true;
  12.     } else {
  13.       strnum = (Number(newNum) / 10000).toString();
  14.       return false;
  15.     }
  16.   });
  17.   return {
  18.     num: (Number(strnum)).toFixed(2),
  19.     unit: unit
  20.   };
  21. }
  22. console.log(formatMoney(123456));   // { num: "12.35", unit: "万元" }
  23. console.log(formatMoney(123456789)); // { num: "1.23", unit: "亿" }
复制代码

该函数仅处理整数部分判断,小数部分截断处理,适用于大部分场景。

功能更全面的格式化工具

要同时支持千分位分隔、负数处理、自定义小数位数及单位后缀,可以封装如下:
  1. function yuanToWanFormat(amount, digits = 2, useSeparator = false) {
  2.   let num = parseFloat(amount);
  3.   if (isNaN(num)) return '0.00';
  4.   let wan = num / 10000;
  5.   const factor = Math.pow(10, digits);
  6.   wan = Math.round(wan * factor) / factor;
  7.   let [integerPart, decimalPart] = wan.toFixed(digits).split('.');
  8.   if (useSeparator) {
  9.     integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  10.   }
  11.   return decimalPart !== undefined
  12.     ? `${integerPart}.${decimalPart}`
  13.     : integerPart;
  14. }
复制代码

示例:
  1. yuanToWanFormat(12345678, 2, true); // "1,234.57"
  2. yuanToWanFormat(-123456, 2, true);  // "-12.35"
  3. yuanToWanFormat('abc');             // "0.00"
复制代码

若需要任意单位(如亿元),可再抽象一个 formatAmount 函数,通过 unitRatio 参数控制:
  1. function formatAmount(amount, unitRatio = 10000, options = {}) {
  2.   const {
  3.     digits = 2,
  4.     useSeparator = true,
  5.     suffix = '万'
  6.   } = options;
  7.   let num = parseFloat(amount);
  8.   if (isNaN(num)) return '0' + suffix;
  9.   let val = num / unitRatio;
  10.   val = Math.round(val * Math.pow(10, digits)) / Math.pow(10, digits);
  11.   let [intPart, decPart] = val.toFixed(digits).split('.');
  12.   if (useSeparator) {
  13.     intPart = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  14.   }
  15.   const result = decPart ? `${intPart}.${decPart}` : intPart;
  16.   return `${result}${suffix}`;
  17. }
  18. console.log(formatAmount(12345678, 10000, { suffix: '万', useSeparator: true })); // "1,234.57万"
  19. console.log(formatAmount(12345678, 100000000, { suffix: '亿', digits: 2 }));     // "0.12亿"
复制代码

注意事项

1. **浮点精度**:JS 中 123456 / 10000 可能得到 12.345600000000001,使用 toFixed 或先乘后除的 Math.round 可以消除显示误差。
2. **千分位正则**:`/\B(?=(\d{3})+(?!\d))/g` 仅在整数部分长度大于等于4时生效,对负号无影响。
3. **负数处理**:parseFloat 和 toFixed 对负数均工作正常,所得字符串中包含负号。
4. **单位自适应**:若数据量级极大(例如兆以上),需扩展 units 数组或递归逻辑。

以上方法均基于原生 JavaScript,无外部依赖,可放心嵌入报表组件或后台管理系统中。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: JavaScript金额格式化:元转万元函数实现与单位自适应封装

感谢整理,非常实用!我平时也经常遇到金额转换的需求,这些函数直接复制就能用,省了不少事。另外想请教一下,那个自适应单位的 `formatMoney` 函数,在金额特别大(比如超过10^16)时,因为只用整数部分长度判断,会不会因为浮点数精度导致单位判断有偏差?或者您有没有考虑过用 `Intl.NumberFormat` 配合 `compact` 显示来自动选择单位?不过那个会显示“万”、“亿”的英文缩写,用在中文报表里不太合适。整体上看,最后一个带千分位和负数处理的封装已经能满足绝大部分场景了,收藏了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-12 15:10 , Processed in 0.027986 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部