定额发票,大写转小写
1 初衷
工作中遇到一个问题,需要将金额的大写转换成小写,即壹元 to 1
,且,金额的面值可以穷尽:壹元、贰元、伍元、拾元、贰拾元、伍拾元、壹佰元。所以我使用map<大写金额,阿拉伯数字>的方式来存值
结果上线后,客户拿出来一张面值为“叁元”的发票0_0 人麻了之后,发现map不是长久之计,我就决定写一种通用的工具类来将大写金额转换成小写。
2 工具类
package com.wdc.util.amount;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
public class CaseConversionUtils {
/**
* @date 20230205
* @description 定额发票金额 大写转小写
* 常见定额发票金额:壹元、贰元、伍元、拾元、贰拾元、伍拾元、壹佰元
* 原本做过一个最简单的方法,通过一个map<大写金额,小写金额>来存数据
* 结果上线后,遇到了一张面值为三块钱的,人麻了,客户说这种票属于正常情况,所以才想着写一个工具类用来把大写金额转换成小写金额
* @author wdc
*/
private static final String YUAN = "元";
private static final Map<String,String> NUM_MAP = new HashMap<String, String>(){{
put("壹","1");
put("贰","2");
put("叁","3");
put("肆","4");
put("伍","5");
put("陆","6");
put("柒","7");
put("捌","8");
put("玖","9");
}};
private static final Map<String,String> BIT_MAP = new HashMap<String, String>(){{
put("元","1");
put("拾","10");
put("佰","100");
put("仟","1000");
}};
public static BigDecimal upperCaseToLowerCase(String upperCase){
// 1 大写金额转算术表达式
String arithmeticExp = upperCaseToArithmeticExp(upperCase);
// 2 表达式金额计算
BigDecimal lowercase = calArithmeticExp(arithmeticExp);
return lowercase;
}
private static BigDecimal calArithmeticExp(String arithmeticExp) {
BigDecimal lowercase = new BigDecimal(-1);
// 1 算数表达式格式校验
boolean flag = checkArithmeticExp(arithmeticExp);
// 2 ?算术表达式金额计算
if(flag){
lowercase = calculateExp(arithmeticExp);
}
return lowercase;
}
private static BigDecimal calculateExp(String arithmeticExp) {
BigDecimal amount = new BigDecimal(0);
try{
arithmeticExp = arithmeticExp.replace(" ","");
String[] chars = arithmeticExp.split("x");
if(chars.length == 1){
amount = new BigDecimal(chars[0]);
}
if(chars.length == 2){
amount = new BigDecimal(chars[0]).multiply(new BigDecimal(chars[1])).setScale(0);
}
}catch (Exception e){
}
return amount;
}
private static boolean checkArithmeticExp(String arithmeticExp) {
boolean flag = true;
if(arithmeticExp == null || arithmeticExp.length() <=0){
flag = false;
}else if(arithmeticExp.startsWith("x") || arithmeticExp.endsWith("x")){
flag = false;
}else if(!(arithmeticExp.split("x").length == 1 || arithmeticExp.split("x").length == 2)){
flag = false;
}
return flag;
}
private static String upperCaseToArithmeticExp(String upperCase){
String arithmeticExp = "";
boolean flag = false;
if(upperCase!=null && upperCase.length()>1){
String[] chars = upperCase.split("");
for (int i = 0; i < chars.length; i++) {
if(YUAN.equals(chars[i]))
break;
if(NUM_MAP.containsKey(chars[i])){
arithmeticExp += NUM_MAP.get(chars[i]);
flag = true;
}
if(BIT_MAP.containsKey(chars[i])){
if(!flag){
arithmeticExp += "1";
}
arithmeticExp += "x" + BIT_MAP.get(chars[i]);
}
}
}
return arithmeticExp;
}
}
3 测试类
package com.wdc.util.amount;
import java.math.BigDecimal;
public class CaseConversionUtilsTest {
public static void main(String[] args) {
String upperCase1 = "壹元";
String upperCase2 = "贰元";
String upperCase3 = "伍元";
String upperCase4 = "拾元";
String upperCase5 = "贰拾元";
String upperCase6 = "伍拾元";
String upperCase7 = "壹佰元";
BigDecimal bigDecimal1 = CaseConversionUtils.upperCaseToLowerCase(upperCase1);System.out.println(bigDecimal1);
BigDecimal bigDecimal2 = CaseConversionUtils.upperCaseToLowerCase(upperCase2);System.out.println(bigDecimal2);
BigDecimal bigDecimal3 = CaseConversionUtils.upperCaseToLowerCase(upperCase3);System.out.println(bigDecimal3);
BigDecimal bigDecimal4 = CaseConversionUtils.upperCaseToLowerCase(upperCase4);System.out.println(bigDecimal4);
BigDecimal bigDecimal5 = CaseConversionUtils.upperCaseToLowerCase(upperCase5);System.out.println(bigDecimal5);
BigDecimal bigDecimal6 = CaseConversionUtils.upperCaseToLowerCase(upperCase6);System.out.println(bigDecimal6);
BigDecimal bigDecimal7 = CaseConversionUtils.upperCaseToLowerCase(upperCase7);System.out.println(bigDecimal7);
}
}