在Java中,将数字价格转换为中文大写通常涉及几个步骤,包括将数字分解为各个部分(如个位、十位、百位等),然后根据这些部分转换为对应的中文大写数字,并添加适当的单位(如元、角、分)。
我这边按照正式合同要求到角也加了整数,然后小数点后两位以后的数字将会直接舍弃
/** 中文大写数字 */
private static final char[] CNS = new char[] {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'};
/** 次级单位 */
private static final char[] LOW = new char[] {'拾', '佰', '仟'};
/** 一级单位 */
private static final char[] HIGH = new char[] {'万', '亿'};
/** 基本单位 */
private static final char[] UNIT = new char[] {'元', '角', '分'};
/** 整 or 正 */
private static final char PERFECT = '整';
/** 字符0 */
private static final char ZERO = '0';
/** 字符串0 */
private static final String ZERO_STRING = "0";
/** 零元整 */
private static final String PERFECT_ZERO = "零元整";
/** 负号 */
private static final char NEGATIVE_SYMBOL = '-';
/** 中文负字 */
private static final String NEGATIVE_CN = "负";
/**
* 阿拉伯数字转中文大写数字,小数点后两位以后的数字将会被直接舍弃
*
* @param input 非负阿拉伯数字
* @return 中文大写数字,转换失败返回null
*/
public static String convert(String input) {
if (!isValidNumber(input)) {
if (isScientificNotation(input)) {
input = new BigDecimal(input).toPlainString();
} else {
return null;
}
}
// 处理负值
boolean isNegative = false;
if (input.charAt(0) == NEGATIVE_SYMBOL) {
isNegative = true;
input = input.substring(1);
}
if (Objects.equals(input, ZERO_STRING)) {
return PERFECT_ZERO;
}
// 移除开头的无效0
for (int i = 0; i < input.length(); ++i) {
char c = input.charAt(i);
if (c == '.') {
input = input.substring(i - 1);
break;
} else if (c != ZERO) {
input = input.substring(i);
break;
}
}
// 转换整数部分
String[] arrays = input.split("\\.");
input = arrays[0];
char[] chars = input.toCharArray();
StringBuilder res = new StringBuilder();
int idx = chars.length - 1;
int lowIdx = idx % 4 - 1;
int highIdx = idx / 4 == 0 ? -1 : (idx / 4) % 2 != 0 ? 0 : 1;
boolean needToAddZero = false;
boolean canAddNextHigh = false;
for (char c : chars) {
if (c == ZERO) {
needToAddZero = true;
} else {
if (needToAddZero) {
res.append(CNS[0]);
needToAddZero = false;
}
res.append(CNS[c - ZERO]);
if (lowIdx != -1) {
res.append(LOW[lowIdx]);
}
canAddNextHigh = true;
}
if (--lowIdx == -2) {
lowIdx = 2;
}
if (idx % 4 == 0 && idx != 0) {
if (canAddNextHigh) {
res.append(HIGH[highIdx]);
canAddNextHigh = false;
needToAddZero = false;
}
if (--highIdx == -1) {
highIdx = 1;
}
}
--idx;
}
if (res.length() == 0) {
res.append(CNS[0]);
}
res.append(UNIT[0]);
// 转换小数部分
int len = res.length();
boolean hasDecimalPart = arrays.length == 2;
if (hasDecimalPart) {
// 小数点后2位以后的直接舍弃
char[] chs = arrays[1].toCharArray();
int count = chs.length;
if (count == 1) {
if (chs[0] != ZERO) {
res.append(CNS[chs[0] - ZERO]).append(UNIT[1]);
}
} else {
if (chs[0] != ZERO || chs[1] != ZERO) {
res.append(CNS[chs[0] - ZERO]);
if (chs[0] != ZERO) {
res.append(UNIT[1]);
}
if (chs[1] != ZERO) {
res.append(CNS[chs[1] - ZERO]).append(UNIT[2]);
}
}
}
}
// 添加“整”字逻辑
if (len == res.length() || (hasDecimalPart && res.charAt(res.length() - 1) == '角')) { // 修改点
res.append(PERFECT); // 修改点
}
return PERFECT_ZERO.equals(res)
? PERFECT_ZERO
: isNegative ? NEGATIVE_CN.concat(res.toString()) : res.toString();
}
public static void main(String[] args) {
System.out.println(convert("0.00"));
System.out.println(convert("100"));
System.out.println(convert("100.00"));
System.out.println(convert("100.01"));
System.out.println(convert("1000.00"));
System.out.println(convert("10000"));
System.out.println(convert("10000.002"));
System.out.println(convert("106912.00"));
System.out.println(convert("10010000.00"));
System.out.println(convert("17056086.6"));
System.out.println(convert("17056086.65"));
}
/**
* 是否是合法的阿拉伯数字
*
* @param input 需要检验的阿拉伯数字
* @return 合法返回true,反之返回false
*/
public static boolean isValidNumber(String input) {
return StringUtils.isNotBlank(input) && input.matches("^-?[0-9]+(\\.[0-9]+)?$");
}
/**
* 是否科学记数法
*
* @param input 需要检验的阿拉伯数字
* @return 合法返回true,反之返回false
*/
public static boolean isScientificNotation(String input) {
return StringUtils.isNotBlank(input)
&& input.matches("^([+|-]?\\d+(.{0}|.\\d+))[Ee]([+|-]?\\d+)$");
}
输出内容为: