项目中需要将数字金额转换成大写,Flutter没找到相关的工具,所以这里自己写了一个
主要思路是将金额*100,然后四舍五入转int类型
从最后一位开始进行转换
转换中如果每一位数字转换汉字,添加单位。
0 单独处理,汉字大写的规则,多个0,作为一个处理,关键单位(元,万,亿,兆)后加零,前不加,所以设置了3个标识符:
lastZero标识符确定了上一个是不是零,如果是,则跳过。
tag标识符确定了上一次转换关键单位后是不是有非零数字。
tag2标识符表示从上次关键单位到现在是否存在一个非零数字(新更新代码)
整段代码在2个地方进行加零操作:1、添加关键单位之前,2、添加非零数字之前。
注意长度
下面是代码
convertNumToChinese(double num) {
final List<String> CN_UPPER_NUMBER = [
"零",
"壹",
"贰",
"叁",
"肆",
"伍",
"陆",
"柒",
"捌",
"玖"
];
final List<String> CN_UPPER_MONETRAY_UNIT = [
"分",
"角",
"圆",
"拾",
"佰",
"仟",
"万",
"拾",
"佰",
"仟",
"亿",
"拾",
"佰",
"仟",
"兆",
"拾",
"佰",
"仟"
];
final String CN_FULL = "整";
final String CN_NEGATIVE = "负";
final String CN_ZEOR_FULL = "零圆" + CN_FULL;
double sign = num.sign;
if (sign == num) {
return CN_ZEOR_FULL;
}
if (num.toStringAsFixed(0).length > 15) {
return '超出最大限额';
}
num = num * 100;
int tempValue = int.parse(num.toStringAsFixed(0)).abs();
int p = 10;
int i = -1;
String CN_UP = '';
bool lastZero = false;
bool finish = false;
bool tag = false;
bool tag2 = false;
while (!finish) {
if (tempValue == 0) {
break;
}
int positionNum = tempValue % p;
double n = (tempValue - positionNum) / 10;
tempValue = int.parse(n.toStringAsFixed(0));
String tempChinese = '';
i++;
if (positionNum == 0) {
if (CN_UPPER_MONETRAY_UNIT[i] == "万" ||
CN_UPPER_MONETRAY_UNIT[i] == "亿" ||
CN_UPPER_MONETRAY_UNIT[i] == "兆" ||
CN_UPPER_MONETRAY_UNIT[i] == "圆") {
if (lastZero && tag2) {
CN_UP = CN_UPPER_NUMBER[0] + CN_UP;
}
CN_UP = CN_UPPER_MONETRAY_UNIT[i] + CN_UP;
lastZero = false;
tag = true;
continue;
}
if (!lastZero) {
lastZero = true;
} else {
continue;
}
} else {
if (lastZero && !tag && tag2) {
CN_UP = CN_UPPER_NUMBER[0] + CN_UP;
}
tag = false;
tag2 = true;
lastZero = false;
tempChinese = CN_UPPER_NUMBER[positionNum] + CN_UPPER_MONETRAY_UNIT[i];
}
CN_UP = tempChinese + CN_UP;
}
if (sign < 0) {
CN_UP = CN_NEGATIVE + CN_UP;
}
return CN_UP;
}
附:金额验证正则表达式
RegExp e = RegExp(r'^\d+(\.\d+)?$');
PS:初步测试可用,期待后续的BUG反馈