在财务数据展示、报表统计或大屏看板中,经常需要将金额从“元”转换为“万元”为单位显示,同时还可能要求保留特定位数、添加千分位分隔符或自适应更大的单位(亿、兆等)。以下整理了几种基于原生JavaScript的实现方式,从简单除法到通用工具函数,方便按需选用。
基础转换:直接除法并保留小数
最简单的做法是将金额除以10000,得到万元数值。如果只需保留两位小数,调用 toFixed(2) 即可:
- function yuanToWanSimple(amount) {
- return (amount / 10000).toFixed(2);
- }
- console.log(yuanToWanSimple(123456)); // "12.35"
复制代码
注意 toFixed 返回字符串,且会四舍五入。若担心浮点精度误差,可以先除再使用 Math.round 定点舍入。
带千分位分隔符的格式化
使用 toLocaleString 可以快速获得包含逗号分隔的数值字符串,并指定小数位数:
- function yuanToWanLocale(amount) {
- const wan = amount / 10000;
- return wan.toLocaleString('zh-CN', {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2
- });
- }
- console.log(yuanToWanLocale(12345678)); // "1,234.57"
复制代码
该方法依赖浏览器对 locale 的支持,不同环境输出可能略有差异。
利用 Intl.NumberFormat 实现完全本地化
如果需要更精细的控制,可以创建 Intl.NumberFormat 实例,指定为十进制格式并手动追加单位符号“万”:
- function yuanToWanIntl(amount) {
- const formatter = new Intl.NumberFormat('zh-CN', {
- style: 'decimal',
- minimumFractionDigits: 2,
- maximumFractionDigits: 2
- });
- return formatter.format(amount / 10000) + '万';
- }
- console.log(yuanToWanIntl(123456)); // "12.35万"
复制代码
如果要显示货币符号(如¥),可改用 style: 'currency' 并传入 unitRatio,但货币格式不直接支持“万元”概念,因此手动拼接更实用。
自适应单位的通用封装
实际开发中,金额可能达到亿、兆甚至更大,需要自动选择单位。以下函数采用单位数组(元、万元、亿、兆……),每次长度超过4位就除以10000并切换到下一级,最终返回数值与单位:
- function formatMoney(amount) {
- const units = ["元", "万元", "亿", "兆", "京", "垓", "杼"];
- let strnum = amount.toString();
- let unit = '';
- units.find((item, index) => {
- let newNum = strnum.indexOf('.') !== -1
- ? strnum.substring(0, strnum.indexOf('.'))
- : strnum;
- if (newNum.length < 5) {
- unit = item;
- return true;
- } else {
- strnum = (Number(newNum) / 10000).toString();
- return false;
- }
- });
- return {
- num: (Number(strnum)).toFixed(2),
- unit: unit
- };
- }
- console.log(formatMoney(123456)); // { num: "12.35", unit: "万元" }
- console.log(formatMoney(123456789)); // { num: "1.23", unit: "亿" }
复制代码
该函数仅处理整数部分判断,小数部分截断处理,适用于大部分场景。
功能更全面的格式化工具
要同时支持千分位分隔、负数处理、自定义小数位数及单位后缀,可以封装如下:
- function yuanToWanFormat(amount, digits = 2, useSeparator = false) {
- let num = parseFloat(amount);
- if (isNaN(num)) return '0.00';
- let wan = num / 10000;
- const factor = Math.pow(10, digits);
- wan = Math.round(wan * factor) / factor;
- let [integerPart, decimalPart] = wan.toFixed(digits).split('.');
- if (useSeparator) {
- integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- }
- return decimalPart !== undefined
- ? `${integerPart}.${decimalPart}`
- : integerPart;
- }
复制代码
示例:- yuanToWanFormat(12345678, 2, true); // "1,234.57"
- yuanToWanFormat(-123456, 2, true); // "-12.35"
- yuanToWanFormat('abc'); // "0.00"
复制代码
若需要任意单位(如亿元),可再抽象一个 formatAmount 函数,通过 unitRatio 参数控制:
- function formatAmount(amount, unitRatio = 10000, options = {}) {
- const {
- digits = 2,
- useSeparator = true,
- suffix = '万'
- } = options;
- let num = parseFloat(amount);
- if (isNaN(num)) return '0' + suffix;
- let val = num / unitRatio;
- val = Math.round(val * Math.pow(10, digits)) / Math.pow(10, digits);
- let [intPart, decPart] = val.toFixed(digits).split('.');
- if (useSeparator) {
- intPart = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- }
- const result = decPart ? `${intPart}.${decPart}` : intPart;
- return `${result}${suffix}`;
- }
- console.log(formatAmount(12345678, 10000, { suffix: '万', useSeparator: true })); // "1,234.57万"
- 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,无外部依赖,可放心嵌入报表组件或后台管理系统中。 |