|
- package com.ruoyi.common.utils;
-
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.text.NumberFormat;
- import java.text.ParseException;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Locale;
-
- /**
- * 字符串工具类
- *
- * @author ruoyi
- */
- public class DecimalUtils {
-
- private static final List<String> CN_NUMBERS = Arrays.asList("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖");
- private static final List<String> CN_UNITS = Arrays.asList("", "拾", "佰", "仟");
- private static final List<String> CN_BIG_UNITS = Arrays.asList("", "万", "亿", "兆");
- private static final String CN_NEGATIVE = "负";
- private static final String CN_INTEGER = "整";
- private static final String CN_FULL = "圆";
- private static final String CN_DECIMAL_UNIT = "角分";
- private static final int MAXIMUM_NUMBER = 999999999;
-
- /**
- * 将金额数字转换为中文大写
- * @param amount 金额数字,支持最大到999999999.99
- * @return 中文大写金额字符串
- */
- public static String bigDecimalToChinese(BigDecimal amount) {
- if (amount == null) {
- throw new IllegalArgumentException("金额不能为空");
- }
-
- // 检查金额范围
- if (amount.abs().compareTo(new BigDecimal(MAXIMUM_NUMBER + ".99")) > 0) {
- throw new IllegalArgumentException("金额超出最大范围(999999999.99)");
- }
-
- StringBuilder result = new StringBuilder();
-
- // 处理负数
- if (amount.compareTo(BigDecimal.ZERO) < 0) {
- result.append(CN_NEGATIVE);
- amount = amount.abs();
- }
-
- // 转换为字符串处理
- String amountStr = amount.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
- String[] parts = amountStr.split("\\.");
- String integerPart = parts[0];
- String decimalPart = parts.length > 1 ? parts[1] : "";
-
- // 处理整数部分
- boolean hasInteger = !"0".equals(integerPart);
- if (hasInteger) {
- result.append(convertIntegerPart(integerPart)).append(CN_FULL);
- }
-
- // 处理小数部分
- String decimalStr = convertDecimalPart(decimalPart);
- if (!decimalStr.isEmpty()) {
- // 如果没有整数部分且有小部分,则不显示"零圆"
- if (!hasInteger && decimalStr.charAt(0) != CN_NUMBERS.get(0).charAt(0)) {
- result.append(decimalStr);
- } else {
- // 如果有整数部分或小数部分以零开头,则正常拼接
- if (!hasInteger) {
- result.append(CN_NUMBERS.get(0)).append(CN_FULL);
- }
- result.append(decimalStr);
- }
- } else {
- // 如果没有小数部分,添加"整"
- result.append(CN_INTEGER);
- }
-
- return result.toString();
- }
-
- private static String convertIntegerPart(String integerPart) {
- StringBuilder sb = new StringBuilder();
- int length = integerPart.length();
- int zeroCount = 0; // 连续零的个数
-
- for (int i = 0; i < length; i++) {
- int digit = Character.getNumericValue(integerPart.charAt(i));
- int pos = length - i - 1; // 当前位数
- int unitPos = pos % 4; // 单位位置(个十百千)
- int bigUnitPos = pos / 4; // 大单位位置(万,亿)
-
- if (digit == 0) {
- zeroCount++;
- } else {
- if (zeroCount > 0) {
- sb.append(CN_NUMBERS.get(0));
- zeroCount = 0;
- }
- sb.append(CN_NUMBERS.get(digit)).append(CN_UNITS.get(unitPos));
- }
-
- // 添加大单位(万,亿)
- if (unitPos == 0 && bigUnitPos > 0) {
- if (zeroCount < 4) { // 如果当前段不全为零
- sb.append(CN_BIG_UNITS.get(bigUnitPos));
- }
- zeroCount = 0;
- }
- }
-
- // 处理全零的情况
- if (sb.length() == 0) {
- return CN_NUMBERS.get(0);
- }
-
- return sb.toString();
- }
-
- private static String convertDecimalPart(String decimalPart) {
- StringBuilder sb = new StringBuilder();
- boolean hasNonZero = false;
-
- for (int i = 0; i < decimalPart.length() && i < CN_DECIMAL_UNIT.length(); i++) {
- int digit = Character.getNumericValue(decimalPart.charAt(i));
- if (digit != 0) {
- sb.append(CN_NUMBERS.get(digit)).append(CN_DECIMAL_UNIT.charAt(i));
- hasNonZero = true;
- } else if (hasNonZero || (i > 0 && sb.length() > 0)) {
- // 如果前面已经有非零数字,或者不是第一位,可以添加零
- sb.append(CN_NUMBERS.get(0));
- }
- }
-
- // 去除末尾的零
- while (sb.length() > 0 && sb.charAt(sb.length() - 1) == CN_NUMBERS.get(0).charAt(0)) {
- sb.deleteCharAt(sb.length() - 1);
- }
-
- return sb.toString();
- }
-
-
-
-
- //默认除法运算精度
- private static final int DEF_DIV_SCALE = 10;
-
- /**
- * 提供精确的加法运算
- *
- * @param v1 被加数
- * @param v2 加数
- * @return 两个参数的和
- */
-
- public static double add(double v1, double v2) {
- BigDecimal b1 = new BigDecimal(Double.toString(v1));
- BigDecimal b2 = new BigDecimal(Double.toString(v2));
- return b1.add(b2).doubleValue();
- }
-
- /**
- * 提供精确的加法运算
- *
- * @param v1 被加数
- * @param v2 加数
- * @return 两个参数的和
- */
- public static BigDecimal add(String v1, String v2) {
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.add(b2);
- }
-
- /**
- * 提供精确的加法运算
- *
- * @param v1 被加数
- * @param v2 加数
- * @param scale 保留scale 位小数
- * @return 两个参数的和
- */
- public static String add(String v1, String v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException(
- "The scale must be a positive integer or zero");
- }
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.add(b2).setScale(scale, RoundingMode.HALF_UP).toString();
- }
-
- /**
- * 提供精确的减法运算
- *
- * @param v1 被减数
- * @param v2 减数
- * @return 两个参数的差
- */
- public static double sub(double v1, double v2) {
- BigDecimal b1 = new BigDecimal(Double.toString(v1));
- BigDecimal b2 = new BigDecimal(Double.toString(v2));
- return b1.subtract(b2).doubleValue();
- }
-
- /**
- * 提供精确的减法运算。
- *
- * @param v1 被减数
- * @param v2 减数
- * @return 两个参数的差
- */
- public static BigDecimal sub(String v1, String v2) {
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.subtract(b2);
- }
-
- /**
- * 提供精确的减法运算
- *
- * @param v1 被减数
- * @param v2 减数
- * @param scale 保留scale 位小数
- * @return 两个参数的差
- */
- public static String sub(String v1, String v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException(
- "The scale must be a positive integer or zero");
- }
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
- }
-
- /**
- * 提供精确的乘法运算
- *
- * @param v1 被乘数
- * @param v2 乘数
- * @return 两个参数的积
- */
- public static double mul(double v1, double v2) {
- BigDecimal b1 = new BigDecimal(Double.toString(v1));
- BigDecimal b2 = new BigDecimal(Double.toString(v2));
- return b1.multiply(b2).doubleValue();
- }
-
- /**
- * 提供精确的乘法运算
- *
- * @param v1 被乘数
- * @param v2 乘数
- * @return 两个参数的积
- */
- public static BigDecimal mul(String v1, String v2) {
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.multiply(b2);
- }
-
- /**
- * 提供精确的乘法运算
- *
- * @param v1 被乘数
- * @param v2 乘数
- * @param scale 保留scale 位小数
- * @return 两个参数的积
- */
- public static double mul(double v1, double v2, int scale) {
- BigDecimal b1 = new BigDecimal(Double.toString(v1));
- BigDecimal b2 = new BigDecimal(Double.toString(v2));
- return round(b1.multiply(b2).doubleValue(), scale);
- }
-
- /**
- * 提供精确的乘法运算
- *
- * @param v1 被乘数
- * @param v2 乘数
- * @param scale 保留scale 位小数
- * @return 两个参数的积
- */
- public static String mul(String v1, String v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException(
- "The scale must be a positive integer or zero");
- }
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.multiply(b2).setScale(scale, RoundingMode.HALF_UP).toString();
- }
-
- /**
- * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
- * 小数点以后10位,以后的数字四舍五入
- *
- * @param v1 被除数
- * @param v2 除数
- * @return 两个参数的商
- */
-
- public static double div(double v1, double v2) {
- return div(v1, v2, DEF_DIV_SCALE);
- }
-
- /**
- * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
- * 定精度,以后的数字四舍五入
- *
- * @param v1 被除数
- * @param v2 除数
- * @param scale 表示表示需要精确到小数点以后几位。
- * @return 两个参数的商
- */
- public static double div(double v1, double v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException("The scale must be a positive integer or zero");
- }
- BigDecimal b1 = new BigDecimal(Double.toString(v1));
- BigDecimal b2 = new BigDecimal(Double.toString(v2));
- return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
- }
-
- /**
- * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
- * 定精度,以后的数字四舍五入
- *
- * @param v1 被除数
- * @param v2 除数
- * @param scale 表示需要精确到小数点以后几位
- * @return 两个参数的商
- */
- public static String div(String v1, String v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException("The scale must be a positive integer or zero");
- }
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v1);
- return b1.divide(b2, scale, RoundingMode.HALF_UP).toString();
- }
-
- /**
- * 提供精确的小数位四舍五入处理
- *
- * @param v 需要四舍五入的数字
- * @param scale 小数点后保留几位
- * @return 四舍五入后的结果
- */
- public static double round(double v, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException("The scale must be a positive integer or zero");
- }
- BigDecimal b = new BigDecimal(Double.toString(v));
- return b.setScale(scale, RoundingMode.HALF_UP).doubleValue();
- }
-
- /**
- * 提供精确的小数位四舍五入处理
- *
- * @param v 需要四舍五入的数字
- * @param scale 小数点后保留几位
- * @return 四舍五入后的结果
- */
- public static String round(String v, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException(
- "The scale must be a positive integer or zero");
- }
- BigDecimal b = new BigDecimal(v);
- return b.setScale(scale, RoundingMode.HALF_UP).toString();
- }
-
- /**
- * 取余数
- *
- * @param v1 被除数
- * @param v2 除数
- * @param scale 小数点后保留几位
- * @return 余数
- */
- public static String remainder(String v1, String v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException(
- "The scale must be a positive integer or zero");
- }
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- return b1.remainder(b2).setScale(scale, RoundingMode.HALF_UP).toString();
- }
-
- /**
- * 取余数 BigDecimal
- *
- * @param v1 被除数
- * @param v2 除数
- * @param scale 小数点后保留几位
- * @return 余数
- */
- public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
- if (scale < 0) {
- throw new IllegalArgumentException(
- "The scale must be a positive integer or zero");
- }
- return v1.remainder(v2).setScale(scale, RoundingMode.HALF_UP);
- }
-
- /**
- * 比较大小
- *
- * @param v1 被比较数
- * @param v2 比较数
- * @return 如果v1 大于v2 则 返回true 否则false
- */
- public static boolean compare(String v1, String v2) {
- BigDecimal b1 = new BigDecimal(v1);
- BigDecimal b2 = new BigDecimal(v2);
- int bj = b1.compareTo(b2);
- boolean res;
- res = bj > 0;
- return res;
- }
-
- /**
- * 将数字格式化为千分位
- *
- * @param number
- * @return 字符串
- */
- public static String convert(BigDecimal number) {
- if (null == number || number.compareTo(BigDecimal.ZERO) == 0) {
- return "";
- }
- NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ENGLISH);
-
- // 设置最大分数位数,这里设置为0表示不使用分数
- numberFormat.setMaximumFractionDigits(2);
-
- // 设置最小整数位数,这里设置为2表示整数部分至少2位
- //numberFormat.setMinimumIntegerDigits(2);
-
- // 设置grouping used属性为false,表示不使用千分位分隔符
- numberFormat.setGroupingUsed(true);
-
- return numberFormat.format(number);
- }
-
- /**
- * 将千分位数字字符串格式化为 BigDecimal
- * @param formattedNumber
- * @return 字符串
- */
- public static BigDecimal convert(String formattedNumber) {
- if (StringUtils.isEmpty(formattedNumber)) {
- return BigDecimal.ZERO;
- }
- try {
- NumberFormat format = NumberFormat.getInstance(Locale.US);
- Number number = format.parse(formattedNumber);
- BigDecimal bigDecimal = new BigDecimal(number.toString());
- return bigDecimal;
- } catch (ParseException e) {
- e.printStackTrace();
- return BigDecimal.ZERO;
- }
-
- }
-
- public static boolean isZero_s(BigDecimal b) {
-
- return null == b || b.compareTo(BigDecimal.ZERO) == 0;
- }
-
-
- /**
- * 将是0的处理成空
- * @param number
- * @return BigDecimal
- */
- public static String zeroToNull(BigDecimal number) {
- if(number.compareTo(BigDecimal.ZERO) == 0){
- return null;
- }else{
- return number.toString();
- }
- }
- }
|