小数金额转换(精确到分)
A.包含功能:
1.支持任意大小的金额
2.支持整形、小数金额转换
3.支持负数转换
4.支持以+开头的数,如+100
5.支持前缀0转换,如-000001、000001等
6.支持逗号去除,如100,000 转为 100000后转换为大写金额
7.将转换后开头的“壹拾”替换为“拾”(该功能可选,只要重新实现after方法即可)
8.小数位超过2位则强制进位,如:
10.001 ==> 10.01
10.005 ==> 10.01
10.561 ==> 10.57
10.565 ==> 10.57
9.小数位第一位不为0,则不加“零”否则加“零”,如:
10.001 ==> 拾元零壹分
10.005 ==> 拾元零壹分
10.561 ==> 拾元伍角柒分
10.565 ==> 拾元伍角柒分
10.若传入金额为整数,则结尾会加“整”,如:
10 ==> 拾元整
11 ==> 拾壹元整
101 ==> 壹佰零壹元整
说明:
结果中展示“拾”还是“壹拾”由after方法决定
B.关键代码:
1.整数部分转换:
/**
* 整数部分转换
*
* @param number 整数部分
* @return 大写金额
* @throws Exception
*/
private String convertInt(String number, boolean hasDecimal) throws Exception
{
if("0".equals(number))
{
return "";
}
StringBuffer sb = new StringBuffer();
//以8位为单位处理数字
int maxProcessUnit = 8;
//整数部分金额长度
int len = number.length();
//当前处理到哪一位(从左到右依次为0到1)
int currentOffset = 0;
//记录上一次有效的位置,用来控制是否需要添加“零”
int lastValidUnitPos = -1;
//每8位处理一次,总共需要处理多少次
int loop = len / maxProcessUnit;
for(int i = 0; i <= loop; i++)
{
//本次需要处理的位数
int currentLen = i == 0 ? len % maxProcessUnit : maxProcessUnit;
//用来辅助计算当前应该选哪个单位
int currentUnitOffset = 0;
//当前currentLen位是否有非0数字
boolean hasValidNumber = false;
for(int j=0; j
{
//当前要处理的数字
String numberAtOffset = number.substring(currentOffset, currentOffset+1);
int nao = Integer.parseInt(numberAtOffset);
//当前金额单位
int currentUnit = currentLen - currentUnitOffset - 1;
//将对应numberAtOffset位置的数字转为大写
if(nao > 0)
{
if(lastValidUnitPos >=0 && lastValidUnitPos - currentUnit > 1)
{
sb.append(NUM[0]);
}
sb.append(NUM[nao]);
hasValidNumber = true;
}
//处理numberAtOffset位置的单位
if(nao > 0)
{
sb.append(MONEY_UNIT[currentUnit]);
lastValidUnitPos = currentUnit;
}
else
{
if(currentUnit == 4 && hasValidNumber)
{
sb.append(MONEY_UNIT[currentUnit]);
lastValidUnitPos = currentUnit;
}
}
currentUnitOffset++;
currentOffset++;
}
//每8位之后增加单位“亿”
if(len >=maxProcessUnit && sb.length() > 0 && i < loop)
{
sb.append(MONEY_UNIT[MONEY_UNIT.length - 1]);
lastValidUnitPos = MONEY_UNIT.length - 1;
}
}
//添加单位“元”
sb.append(UNIT);
//添加单位“整”
if(!hasDecimal)
{
sb.append(ZHENG);
}
return sb.toString();
}
2.小数部分转换:
/**
* 小数部分转换
* 精确到分
*
* @param decimal 小数部分数值
* @param hasInt 整数部分是否为0
* @return
* @throws Exception
*/
private String convertDecimal(String decimal, boolean hasInt) throws Exception
{
if(Integer.parseInt(decimal) == 0)
{
return "";
}
StringBuffer sb = new StringBuffer();
for(int i=0; i< 2; i++)
{
int curNum = Integer.parseInt(decimal.substring(i,i+1));
if(curNum == 0)
{
if(i == 0 && hasInt)
{
sb.append(NUM[0]);
}
continue;
}
sb.append(NUM[curNum]);
sb.append(CHANGE_MONEY_UNIT[i]);
}
return sb.toString();
}
3.转换方法:
@Override
protected String doConvert(String number) throws Exception
{
StringBuffer sb = new StringBuffer();
if(isNegative(number))
{
number = number.substring(1);
sb.append(NEGATIVE_SIGN_DESC);
}
//检查并去除无效前缀0
BigDecimal decimal = new BigDecimal(number);
if("0".equals(decimal.toString()))
{
if(sb.length() > 0)
{
sb.setLength(sb.length() - 1);
}
return sb.append(NUM[0]).append(UNIT).append(ZHENG).toString();
}
BigDecimal decimalRounded = decimal.setScale(2, BigDecimal.ROUND_UP);
String newNum = decimalRounded.toString();
String[] numArr = newNum.split("\\.");
String numInt = numArr[0];
String numDecimal = newNum.split("\\.")[1];
sb.append(convertInt(numInt, 0 < Integer.parseInt(numDecimal)));
if(numArr.length > 1)
{
sb.append(convertDecimal(numDecimal, !"".equals(sb.toString())));
}
return sb.toString();
}
整数金额转换(方式一)
A.包含功能:
1.支持任意整数金额转换
2.支持负数转换
3.支持以+开头的数,如+100
4.支持前缀0转换,如-000001、000001等
5.支持逗号去除,如100,000 转为 100000后转换为大写金额
6.将转换后开头的“壹拾”替换为“拾”(该功能可选,只要重新实现after方法即可)
B.关键代码:
@Override
protected String doConvert(String number) throws Exception
{
StringBuffer sb = new StringBuffer();
//检查并去除可能出现的"+"
BigDecimal numDec = new BigDecimal(number);
if(isNegative(number))
{
sb.append(NEGATIVE_SIGN_DESC);
number = number.substring(1);
//去除前缀0
numDec = new BigDecimal(number);
}
//修正数据
number = numDec.toString();
if(numDec.toString().equals("0"))
{
return sb.append(NUM[0]).append(UNIT).toString();
}
int len = number.length();
int maxProcessUnit = 8;//以8位为单位处理数字
int currentOffset = 0;//当前处理到哪一位(从左到右依次为0到1)
int lastValidUnitPos = -1;//记录上一次有效的位置,用来控制是否需要添加“零”
int loop = len / maxProcessUnit;
for(int i = 0; i <= loop; i++)
{
//本次需要处理的位数
int currentLen = i == 0 ? len % maxProcessUnit : maxProcessUnit;
//用来辅助计算当前应该选哪个单位
int currentUnitOffset = 0;
//当前currentLen位是否有非0数字
boolean hasValidNumber = false;
for(int j=0; j
{
//当前要处理的数字
String numberAtOffset = number.substring(currentOffset, currentOffset+1);
int nao = Integer.parseInt(numberAtOffset);
//当前金额单位
int currentUnit = currentLen - currentUnitOffset - 1;
//将对应numberAtOffset位置的数字转为大写
if(nao > 0)
{
if(lastValidUnitPos >=0 && lastValidUnitPos - currentUnit > 1)
{
sb.append(NUM[0]);
}
sb.append(NUM[nao]);
hasValidNumber = true;
}
//处理numberAtOffset位置的单位
if(nao > 0)
{
sb.append(MONEY_UNIT[currentUnit]);
lastValidUnitPos = currentUnit;
}
else
{
if(currentUnit == 4 && hasValidNumber)
{
sb.append(MONEY_UNIT[currentUnit]);
lastValidUnitPos = currentUnit;
}
}
currentUnitOffset++;
currentOffset++;
}
//每8位之后增加单位“亿”
if(len >=8 && sb.length() > 0 && !NEGATIVE_SIGN_DESC.equals(sb.toString()) && i < loop)
{
sb.append(MONEY_UNIT[MONEY_UNIT.length - 1]);
lastValidUnitPos = MONEY_UNIT.length - 1;
}
}
//添加单位“圆整”
sb.append(UNIT);
return sb.toString();
}
整数金额转换(方式二)
A.包含功能:
1.支持任意整数金额转换
2.支持负数转换
3.支持以+开头的数,如+100
4.支持前缀0转换,如-000001、000001等
5.支持逗号去除,如100,000 转为 100000后转换为大写金额
6.将转换后开头的“壹拾”替换为“拾”(该功能可选,只要重新实现after方法即可)
B.关键代码:
@Override
protected String doConvert(String number) throws Exception
{
StringBuffer sb = new StringBuffer();
//检查并去除可能出现的"+"
BigDecimal numDec = new BigDecimal(number);
if(isNegative(number))
{
sb.append(NEGATIVE_SIGN_DESC);
number = number.substring(1);
//去除前缀0
numDec = new BigDecimal(number);
}
//修正数据
number = numDec.toString();
if(numDec.toString().equals("0"))
{
return sb.append(NUM[0]).append(UNIT).toString();
}
int len = number.length();
//当前处理位置,从左至右
int currentOffset = 0;
//记录上个非0数据位置
int lastValidNumPos = -1;
//记录最近一次添加的有效单位
int lastValidUnitPos = -1;
int unitLen = MONEY_UNIT.length - 1;
while(currentOffset < len)
{
String currentNum = number.substring(currentOffset, currentOffset+1);
int currentNumInt = Integer.parseInt(currentNum);
//计算单位
int currentIndex = len - currentOffset - 1;
int currentUnitPos = currentIndex % unitLen;
//是否需要替换lastValidUnitPos变量
boolean unitValid = false;
//判断是否需要加“零”,如101应为壹佰零一元整
if(lastValidUnitPos > 0 && lastValidUnitPos - currentUnitPos > 1 && currentNumInt > 0)
{
sb.append(NUM[0]);
}
//添加数字对应大写
if(currentNumInt > 0)
{
sb.append(NUM[currentNumInt]);
lastValidNumPos = currentOffset;
unitValid = true;
}
//判断是否需要加“万”
if(currentNumInt > 0 || (currentUnitPos == 4 && currentOffset - lastValidNumPos <= 3))
{
sb.append(MONEY_UNIT[currentUnitPos]);
unitValid = true;
}
//判断是否需要加“亿”
int remainLen = len - currentOffset - 1;
if(len - currentOffset - 1 > 0 && remainLen / unitLen > 0 && remainLen % unitLen == 0)
{
sb.append(MONEY_UNIT[MONEY_UNIT.length-1]);
currentUnitPos = MONEY_UNIT.length-1;
unitValid = true;
}
//替换lastValidUnitPos
if(unitValid)
{
lastValidUnitPos = currentUnitPos;
}
currentOffset++;
}
sb.append(UNIT);
return sb.toString();
}
说明:
1.完整源码见附件
2.源码文件说明:
小数金额转换 --> DecimalStrToRMB.java
整数金额转换(方式一)-->IntStrToRMB.java
整数金额转换(方式二)-->IntStrToRMB1.java
3.其他类请参考注释