在开始之前要先说一下,中国对于大写的一些表示规则,也就是大写规范:
一、中文大写金额数字到"元"为止的,在"元"之后,应写"整"(或"正")字,在"角"之后,可以不写"整"(或"正")字。大写金额数字有"分"的,"分"后面不写"整"(或"正")字。
二、阿拉伯数字小写金额数字中有"0"时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。举例如下:
1·阿拉伯数字中间有"0"时,中文大写要写"零"字,如¥1409.50,应写成人民币壹仟肆佰零玖元伍角。
2·阿拉伯数字中间连续有几个"0"时,中文大写金额中间可以只写一个"零"字,如¥6007.14,应写成人民币陆仟零柒元壹角肆分。
3·阿拉伯金额数字万位和元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写金额中可以只写一个零字,也可以不写"零"字。如¥1680.32,应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分,又如¥107000.53,应写成人民币壹拾万柒仟元零伍角叁分,或者写成人民币壹拾万零柒仟元伍角叁分。
4·阿拉伯金额数字角位是"0",而分位不是"0"时,中文大写金额"元"后面应写"零"字。如¥16409.02,应写成人民币壹万陆仟肆佰零玖元零贰分;又如¥325.04,应写成人民币叁佰贰拾伍元零肆分。
三、在文书中有万元、亿元等单位约定的,如¥533.12万元,应写成人民币伍佰叁拾叁点壹贰万元。
了解了这些之后,来看看如何实现(如果各位读者发现了缺陷,记得留言哦):
public class MoneyFormat {
// 定义大写汉字集
private final String[] pattern = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
// 定义整数部分单位
private final String[] cPattern = { "", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿" };
// 定义小数部分单位
private final String[] cfPattern = { "", "角", "分" };
// 定义单独出现零
private final String ZERO = "零";
public MoneyFormat() {
System.out.println("转换启动");
}
//转换的方法开始:
//1.传入String类型的货币额数据
public String format(String moneyString) {
//根据.来判断是否为小数
int dotPoint = moneyString.indexOf(".");
String moneyStr;
// 是小数就截取,分成整数部分和小数部分
if (dotPoint != -1) {
moneyStr = moneyString.substring(0, moneyString.indexOf("."));
}
// 否则不截取
else {
moneyStr = moneyString;
}
StringBuilder fraction = null; // 小数部分的处理,以及最后的yuan.
StringBuilder ms = new StringBuilder();
for (int i = 0; i < moneyStr.length(); i++) {
// 将字符值转换为数组的索引,并将对应索引的大写汉字加入
ms.append(pattern[moneyStr.charAt(i) - 48]);
}
//在金额中开始插入单位
int cpCursor = 1;
for (int j = moneyStr.length() - 1; j > 0; j--) {
// 在j之后加字符,不影响j对原字符串的相对位置
// 只是moneyStr.length()不断增加
// insert(j,"string")就在j位置处插入,j=0时为第一位
ms.insert(j, cPattern[cpCursor]);
// 亿位之后重新循环,将cpCursor的值,也就是cPattern单位数组的索引初始化为1
cpCursor = cpCursor == 8 ? 1 : cpCursor + 1;
}
while (ms.indexOf("零拾") != -1) { // 当十位为零时用一个"零"代替"零拾"
// replace的起始位置和终止位置
ms.replace(ms.indexOf("零拾"), ms.indexOf("零拾") + 2, ZERO);
}
while (ms.indexOf("零佰") != -1) { // 当百位为零时,同理
ms.replace(ms.indexOf("零佰"), ms.indexOf("零佰") + 2, ZERO);
}
while (ms.indexOf("零仟") != -1) { // 同理
ms.replace(ms.indexOf("零仟"), ms.indexOf("零仟") + 2, ZERO);
}
while (ms.indexOf("零万") != -1) { // 需要保留万位
ms.replace(ms.indexOf("零万"), ms.indexOf("零万") + 2, "万");
}
while (ms.indexOf("零亿") != -1) { // 同上
ms.replace(ms.indexOf("零亿"), ms.indexOf("零亿") + 2, "亿");
}
while (ms.indexOf("零零") != -1) {// 有连续数位出现零,即有以下情况,此时根据习惯保留一个零即可
ms.replace(ms.indexOf("零零"), ms.indexOf("零零") + 2, ZERO);
}
while (ms.indexOf("亿万") != -1) { // 特殊情况,如:100000000,根据习惯保留高位
ms.replace(ms.indexOf("亿万"), ms.indexOf("亿万") + 2, "亿");
}
while (ms.lastIndexOf("零") == ms.length() - 1) { // 当结尾为零,不必显示,经过处理也只可能出现一个零
ms.delete(ms.lastIndexOf("零"), ms.lastIndexOf("零") + 1);
}
int end;
//处理小数
if ((dotPoint = moneyString.indexOf(".")) != -1) {
//使用.进行截取,操作小数部分
String fs = moneyString.substring(dotPoint + 1, moneyString.length());
if (fs.indexOf("00") == -1 || fs.indexOf("00") >= 2) {// 若前两位小数全为零,则跳过操作
end = fs.length() > 2 ? 2 : fs.length(); // 仅保留两位小数
fraction = new StringBuilder(fs.substring(0, end));
for (int j = 0; j < fraction.length(); j++) {
// 将字符值转换为pattern数组的索引,并将对应索引的大写汉字加入
fraction.replace(j, j + 1, this.pattern[fraction.charAt(j) - 48]);
}
for (int i = fraction.length(); i > 0; i--) { // 插入中文单位,角,分
fraction.insert(i, cfPattern[i]);
}
fraction.insert(0, "元"); // 为整数部分添加标识
} else {
//小数部分除了0没有数值,表示为"元整"
fraction = new StringBuilder("元整");
}
} else {
//没有小数部分,表示为元整
fraction = new StringBuilder("元整");
}
// 加入小数部分
ms.append(fraction);
//将结果转换成字符串表示
return ms.toString();
}
}
感谢大家! |
|