@@ -28,6 +28,8 @@ public class FlowModelService extends LCSingleService { | |||||
return new FlowModelSaveHandler<>(); | return new FlowModelSaveHandler<>(); | ||||
case TYPE_MODEL_DEL: | case TYPE_MODEL_DEL: | ||||
return new FlowModelDelHandler(); | return new FlowModelDelHandler(); | ||||
case TYPE_FLOW: | |||||
return new FlowTransHandler(); | |||||
} | } | ||||
return super.createHandler(type); | return super.createHandler(type); | ||||
} | } | ||||
@@ -25,6 +25,7 @@ public class FlowLcLc1Service extends FlowModelService { | |||||
case TYPE_MODEL_LOAD: | case TYPE_MODEL_LOAD: | ||||
case TYPE_MODEL_SAVE: | case TYPE_MODEL_SAVE: | ||||
case TYPE_MODEL_DEL: | case TYPE_MODEL_DEL: | ||||
case TYPE_FLOW: | |||||
return super.createHandler(type); | return super.createHandler(type); | ||||
} | } | ||||
return worker.createHandler(type); | return worker.createHandler(type); | ||||
@@ -22,6 +22,7 @@ public class FlowLcMsService extends FlowModelService { | |||||
switch (type) { | switch (type) { | ||||
case TYPE_MODEL_LIST: | case TYPE_MODEL_LIST: | ||||
case TYPE_MODEL_LOAD: | case TYPE_MODEL_LOAD: | ||||
case TYPE_FLOW: | |||||
return super.createHandler(type); | return super.createHandler(type); | ||||
case TYPE_MODEL_SAVE: | case TYPE_MODEL_SAVE: | ||||
return new FlowLcMsSaveHandler(); | return new FlowLcMsSaveHandler(); | ||||
@@ -34,7 +34,21 @@ | |||||
<#if fields.lookup??> | <#if fields.lookup??> | ||||
"lookup": { | "lookup": { | ||||
<#list fields.lookup as k, v> | <#list fields.lookup as k, v> | ||||
"${k}": "${v}" <#if k_has_next>,</#if> | |||||
<#if v?is_enumerable> | |||||
"${k}": [ | |||||
<#list v as v1> | |||||
{ | |||||
<#list v1 as vk1, vv1> | |||||
"${vk1}": "${vv1}"<#if vk1_has_next>,</#if> | |||||
</#list> | |||||
} | |||||
<#if v1_has_next>,</#if> | |||||
</#list> | |||||
] | |||||
<#else> | |||||
"${k}": "${v}" | |||||
</#if> | |||||
<#if k_has_next>,</#if> | |||||
</#list> | </#list> | ||||
}, | }, | ||||
</#if> | </#if> | ||||
@@ -184,7 +184,21 @@ | |||||
<#if fields.lookup??> | <#if fields.lookup??> | ||||
"lookup": { | "lookup": { | ||||
<#list fields.lookup as k, v> | <#list fields.lookup as k, v> | ||||
"${k}": "${v}" <#if k_has_next>,</#if> | |||||
<#if v?is_enumerable> | |||||
"${k}": [ | |||||
<#list v as v1> | |||||
{ | |||||
<#list v1 as vk1, vv1> | |||||
"${vk1}": "${vv1}"<#if vk1_has_next>,</#if> | |||||
</#list> | |||||
} | |||||
<#if v1_has_next>,</#if> | |||||
</#list> | |||||
] | |||||
<#else> | |||||
"${k}": "${v}" | |||||
</#if> | |||||
<#if k_has_next>,</#if> | |||||
</#list> | </#list> | ||||
}, | }, | ||||
</#if> | </#if> | ||||
@@ -80,7 +80,21 @@ | |||||
<#if field.lookup??> | <#if field.lookup??> | ||||
"lookup": { | "lookup": { | ||||
<#list field.lookup as k, v> | <#list field.lookup as k, v> | ||||
"${k}": "${v}" <#if k_has_next>,</#if> | |||||
<#if v?is_enumerable> | |||||
"${k}": [ | |||||
<#list v as v1> | |||||
{ | |||||
<#list v1 as vk1, vv1> | |||||
"${vk1}": "${vv1}"<#if vk1_has_next>,</#if> | |||||
</#list> | |||||
} | |||||
<#if v1_has_next>,</#if> | |||||
</#list> | |||||
] | |||||
<#else> | |||||
"${k}": "${v}" | |||||
</#if> | |||||
<#if k_has_next>,</#if> | |||||
</#list> | </#list> | ||||
}, | }, | ||||
</#if> | </#if> | ||||
@@ -165,7 +165,21 @@ | |||||
<#if field.lookup??> | <#if field.lookup??> | ||||
"lookup": { | "lookup": { | ||||
<#list field.lookup as k, v> | <#list field.lookup as k, v> | ||||
"${k}": "${v}" <#if k_has_next>,</#if> | |||||
<#if v?is_enumerable> | |||||
"${k}": [ | |||||
<#list v as v1> | |||||
{ | |||||
<#list v1 as vk1, vv1> | |||||
"${vk1}": "${vv1}"<#if vk1_has_next>,</#if> | |||||
</#list> | |||||
} | |||||
<#if v1_has_next>,</#if> | |||||
</#list> | |||||
] | |||||
<#else> | |||||
"${k}": "${v}" | |||||
</#if> | |||||
<#if k_has_next>,</#if> | |||||
</#list> | </#list> | ||||
}, | }, | ||||
</#if> | </#if> | ||||
@@ -168,7 +168,21 @@ | |||||
<#if dfield.lookup??> | <#if dfield.lookup??> | ||||
"lookup": { | "lookup": { | ||||
<#list dfield.lookup as k, v> | <#list dfield.lookup as k, v> | ||||
"${k}": "${v}" <#if k_has_next>,</#if> | |||||
<#if v?is_enumerable> | |||||
"${k}": [ | |||||
<#list v as v1> | |||||
{ | |||||
<#list v1 as vk1, vv1> | |||||
"${vk1}": "${vv1}"<#if vk1_has_next>,</#if> | |||||
</#list> | |||||
} | |||||
<#if v1_has_next>,</#if> | |||||
</#list> | |||||
] | |||||
<#else> | |||||
"${k}": "${v}" | |||||
</#if> | |||||
<#if k_has_next>,</#if> | |||||
</#list> | </#list> | ||||
}, | }, | ||||
</#if> | </#if> | ||||
@@ -168,6 +168,16 @@ | |||||
<artifactId>spring-boot-starter-test</artifactId> | <artifactId>spring-boot-starter-test</artifactId> | ||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.apache.poi</groupId> | |||||
<artifactId>poi</artifactId> | |||||
<version>5.2.2</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.apache.poi</groupId> | |||||
<artifactId>poi-ooxml</artifactId> | |||||
<version>5.2.2</version> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
<build> | <build> | ||||
<plugins> | <plugins> | ||||
@@ -54,6 +54,14 @@ public abstract class AbstractListHandler extends AbstractHandler { | |||||
return R.success(buildListData()); | return R.success(buildListData()); | ||||
} | } | ||||
/** | |||||
* 导出excel | |||||
* @return R:{ file: fileName@@filePath } | |||||
*/ | |||||
public R exportExcel() { | |||||
return R.success(buildListData()); | |||||
} | |||||
public SwListData buildListData() { | public SwListData buildListData() { | ||||
List<SwMap> listData; | List<SwMap> listData; | ||||
SqlPara sqlPara = buildDataSql(); | SqlPara sqlPara = buildDataSql(); | ||||
@@ -0,0 +1,131 @@ | |||||
package cc.smtweb.framework.core.util; | |||||
import org.apache.poi.ss.usermodel.Cell; | |||||
import org.apache.poi.ss.usermodel.CellType; | |||||
import org.apache.poi.ss.usermodel.Row; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
public class ExcelUtil { | |||||
private static int xy(int x, int y) { | |||||
if (y == 0) return 1; | |||||
if (y == 1) return x; | |||||
int f = x * x; | |||||
for (int i = 0; i < (y - 2); ++i) { | |||||
f *= x; | |||||
} | |||||
return f; | |||||
} | |||||
// Z==> 26, AA == > 27 , AB ==> 28 | |||||
public static int toColInt(String col) { | |||||
col = col.toUpperCase(); | |||||
int colv = 0, left = 0; | |||||
for (int i = col.length(); i > 0; --i) { | |||||
char c = col.charAt(i - 1); | |||||
colv += (c - 'A' + 1) * xy(26, left); | |||||
++left; | |||||
} | |||||
return colv - 1; // excel是从0开始的 | |||||
} | |||||
/** | |||||
* 数字下标转列 | |||||
* @param index | |||||
* @return | |||||
*/ | |||||
public static String toColExcel(int index) { | |||||
int shang = 0; | |||||
int yu = 0; | |||||
List<Integer> list = new ArrayList<Integer>(); //10进制转26进制 倒序 | |||||
do { | |||||
shang = index / 26; | |||||
yu = index % 26; | |||||
index = shang; | |||||
list.add(yu); | |||||
} while (shang != 0); | |||||
StringBuilder sb = new StringBuilder(); | |||||
for (int j = list.size() - 1; j >= 0; j--) { | |||||
sb.append((char) (list.get(j) + 'A' - (Math.min(j, 1)))); //倒序拼接 序号转字符 非末位 序号减去 1 | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
// 注意col要大写字母 | |||||
public static String getStr(Row row, char col) { | |||||
int i = col - 'A'; | |||||
return getStr(row, i); | |||||
} | |||||
public static String getStr(Row row, int col) { | |||||
if(col <0) return ""; | |||||
Cell cell = row.getCell(col); | |||||
if (null == cell) return ""; | |||||
if (cell.getCellType() == CellType.BLANK || cell.getCellType() == CellType.ERROR) { | |||||
return ""; | |||||
} | |||||
// AKzz : cell 是数字时,会报错误, | |||||
if (cell.getCellType() == CellType.NUMERIC) { | |||||
// 非日期格式 | |||||
if (!org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { | |||||
double d = cell.getNumericCellValue(); | |||||
// long x = (long) d; | |||||
return MathUtil.getDoubleStr(d); | |||||
} else { | |||||
return cc.smtweb.framework.core.util.DateUtil.toStdDateString(cell.getDateCellValue()); | |||||
} | |||||
} | |||||
if (cell.getCellType() == CellType.STRING) { | |||||
return StringUtil.checkNull(cell.getStringCellValue()); | |||||
} | |||||
if (cell.getCellType() == CellType.FORMULA) { | |||||
return getFormulaStr(cell); | |||||
} | |||||
return ""; | |||||
} | |||||
// 注意col要大写字母 | |||||
public static int getInt(Row row, char col) { | |||||
int i = col - 'A'; | |||||
return getInt(row, i); | |||||
} | |||||
public static int getInt(Row row, int col) { | |||||
if(col <0) return 0; | |||||
Cell cell = row.getCell(col); | |||||
if (null == cell) return 0; | |||||
if (cell.getCellType() == CellType.NUMERIC && !org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { | |||||
double d = cell.getNumericCellValue(); | |||||
return (int) d; | |||||
} else if (cell.getCellType() == CellType.STRING) { | |||||
return MathUtil.toint(cell.getStringCellValue(), 0); | |||||
} else if (cell.getCellType() == CellType.FORMULA) { | |||||
return (int) getFormulaDbl(cell); | |||||
} | |||||
return 0; | |||||
} | |||||
private static String getFormulaStr(Cell cell) { | |||||
try { | |||||
return StringUtil.checkNull(cell.getStringCellValue()); | |||||
} catch (Exception e) { | |||||
// UtilLogger.warn("读取数据出错:"+cell, e); | |||||
System.err.println("读取数据出错"); | |||||
String v = MathUtil.toStdNumberString(cell.getNumericCellValue()); | |||||
if (v.endsWith(".00")) v = v.substring(0, v.length() - 3); | |||||
return v; | |||||
} | |||||
} | |||||
private static double getFormulaDbl(Cell cell) { | |||||
try { | |||||
return cell.getNumericCellValue(); | |||||
} catch (Exception e) { | |||||
return MathUtil.todouble(cell.getStringCellValue()); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,54 @@ | |||||
package cc.smtweb.framework.core.util; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
public class ExportUtil { | |||||
//填充变量 | |||||
public static String myReplaceStr(String s, Map<String, String> map) { | |||||
boolean isDouble = s.startsWith("[@exprd"); | |||||
boolean isInt = s.startsWith("[@expri@]"); | |||||
if (isDouble || isInt) { | |||||
s = s.substring(s.indexOf("@]") + 2); | |||||
String b = "[#", e = "#]", svar; | |||||
int n = s.indexOf(b), lb = b.length(); | |||||
Map<String, Object> mapvar = new HashMap<>(); | |||||
int i = 0; | |||||
while (n >= 0) { | |||||
svar = "a" + (++i); | |||||
String fn = s.substring(n + lb, s.indexOf(e)); | |||||
s = s.replace(b + fn + e, svar); | |||||
n = s.indexOf(b); | |||||
mapvar.put(svar, StringUtil.getDoubleIgnoreErr(map.get(fn))); | |||||
} | |||||
double d; | |||||
try { | |||||
d = MathUtil.calcExprMapDouble(s, mapvar); | |||||
} catch (Exception e1) { | |||||
d = 0.0; | |||||
// UtilLogger.error("计算错误:", e1); | |||||
} | |||||
if (isDouble) { | |||||
String v = MathUtil.getAmountStr(d); | |||||
v = v.replace(".00", "").replaceAll(",", ""); | |||||
if (v.contains(".") && v.endsWith("0")) v = v.substring(0, v.length() - 1); | |||||
return v; | |||||
} | |||||
return MathUtil.toStdNumberString(d, 0); | |||||
} else if (s.startsWith("[@d") || s.startsWith("[@i@]")) s = s.substring(s.indexOf("@]") + 2); | |||||
else if (s.startsWith("[@expfml@]")) s = s.substring(10); | |||||
return myReplaceStrEx(s, "[#", "#]", map); | |||||
} | |||||
//填充变量 | |||||
public static String myReplaceStrEx(String s, String b, String e, Map<String, String> map) { | |||||
int n = s.indexOf(b), lb = b.length(); | |||||
while (n >= 0) { | |||||
String fn = s.substring(n + lb, s.indexOf(e)); | |||||
s = s.replace(b + fn + e, StringUtil.checkNull(map.get(fn))); | |||||
n = s.indexOf(b); | |||||
} | |||||
return s; | |||||
} | |||||
} |
@@ -3,6 +3,7 @@ package cc.smtweb.framework.core.util; | |||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.apache.commons.codec.binary.Base64; | import org.apache.commons.codec.binary.Base64; | ||||
import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||
import sun.misc.BASE64Decoder; | |||||
import sun.misc.BASE64Encoder; | import sun.misc.BASE64Encoder; | ||||
import javax.imageio.ImageIO; | import javax.imageio.ImageIO; | ||||
@@ -98,6 +99,24 @@ public class FileUtil { | |||||
return "data:image/png;base64," + png_base64; | return "data:image/png;base64," + png_base64; | ||||
} | } | ||||
/** | |||||
* 判断是否是图片 | |||||
* | |||||
* @param base64Str | |||||
* @return | |||||
*/ | |||||
public static boolean isImageFromBase64(String base64Str) { | |||||
try { | |||||
BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(base64Str))); | |||||
if (null == bufImg) { | |||||
return false; | |||||
} | |||||
} catch (Exception e) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
public static boolean copyFile(File oldfile, String newPath, boolean isDelOld) { | public static boolean copyFile(File oldfile, String newPath, boolean isDelOld) { | ||||
if (!oldfile.exists()) return true; | if (!oldfile.exists()) return true; | ||||
int byteread; | int byteread; | ||||
@@ -0,0 +1,507 @@ | |||||
package cc.smtweb.framework.core.util; | |||||
import org.apache.commons.jexl3.*; | |||||
import org.apache.commons.jexl3.internal.Engine; | |||||
import java.math.BigDecimal; | |||||
import java.math.RoundingMode; | |||||
import java.text.DecimalFormat; | |||||
import java.util.Map; | |||||
public class MathUtil { | |||||
//整数 | |||||
private static DecimalFormat dfLng = new DecimalFormat("##############0"); | |||||
private static DecimalFormat dfLong = new DecimalFormat("###,###,###,###,##0"); | |||||
//一位小数 | |||||
private static DecimalFormat df1 = new DecimalFormat("##############0.0"); | |||||
private static DecimalFormat df1Format = new DecimalFormat("###,###,###,###,##0.0"); | |||||
//两位小数 | |||||
private static DecimalFormat df2 = new DecimalFormat("##############0.00"); | |||||
private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00"); | |||||
//四位小数 | |||||
private static DecimalFormat df4 = new DecimalFormat("###,###,###,###,##0.0000"); | |||||
//六位小数 | |||||
private static DecimalFormat df6Number = new DecimalFormat("#######################0.000000"); | |||||
private static DecimalFormat df6NumberF = new DecimalFormat("#,###,###,###,###,###,##0.000000"); | |||||
public final static DecimalFormat stdAmountFormat = new DecimalFormat("###,###,###,###,##0.00"); | |||||
public final static DecimalFormat stdNumberFormat = new DecimalFormat("#0.00"); | |||||
public final static String DEF_NUM_TEN_THOUSAND = "10000";//万 | |||||
public static final double MAX_VALUE = 9999999999999.99D; | |||||
public static final double MIN_VALUE = -9999999999999.99D; | |||||
private final static BigDecimal ONE_BIG = new BigDecimal(1.00D); | |||||
private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分"; | |||||
private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖"; | |||||
/** | |||||
* 4舍5入double,2位小数 | |||||
*/ | |||||
public static double roundDouble(double src) { | |||||
return roundDouble(src, 2); | |||||
} | |||||
/** | |||||
* 4舍5入double,N 位小数 | |||||
* | |||||
* @param src | |||||
* @param scale 小数位数 | |||||
* @return | |||||
*/ | |||||
public static double roundDouble(Object src, int scale) { | |||||
if (src == null) return 0.0; | |||||
String v = src.toString(); | |||||
if (StringUtil.isEmpty(v)) return 0.0; | |||||
if (scale < 0) scale = 2; | |||||
BigDecimal src_b = new BigDecimal(v); | |||||
BigDecimal src_v = src_b.divide(ONE_BIG, scale + 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 | |||||
src_v = src_v.divide(ONE_BIG, scale, BigDecimal.ROUND_HALF_UP);// 4舍5入 | |||||
return src_v.doubleValue(); | |||||
} | |||||
/** | |||||
* 舍位处理,原生floor有坑,部分浮点数记录为.99999999999形式,导致floor结果错误 | |||||
* | |||||
* @param d | |||||
* @return | |||||
*/ | |||||
public static double floor(double d) { | |||||
return Math.floor(MathUtil.roundDouble(d, 2)); | |||||
} | |||||
/** | |||||
* 比较两Double是否相等,将会吧他们专程BigDecimal进行比较; | |||||
* | |||||
* @param src double1 | |||||
* @param tag double2 | |||||
* @return src > tag 返回1, src < tag 返回-1, 否则返回0 | |||||
*/ | |||||
public static int compare(double src, double tag) { | |||||
BigDecimal src_b = new BigDecimal(src); | |||||
BigDecimal src_v = src_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 | |||||
BigDecimal tag_b = new BigDecimal(tag); | |||||
BigDecimal tag_v = tag_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 | |||||
return src_v.compareTo(tag_v); | |||||
} | |||||
/** | |||||
* 自动过滤金额中的逗号转换为double,如果出错,则返回0 | |||||
* | |||||
* @param s 源串,可能为带逗号的金额串; | |||||
* @return double | |||||
*/ | |||||
public static Double toDouble(String s) { | |||||
return todouble(s); | |||||
} | |||||
/** | |||||
* 自动过滤金额中的逗号转换为double,如果出错,则返回0 | |||||
* | |||||
* @param s 源串,可能为带逗号的金额串; | |||||
* @return double | |||||
*/ | |||||
public static double todouble(String s) { | |||||
try { | |||||
return Double.parseDouble(s.replaceAll(",", "")); | |||||
} catch (Exception e) { | |||||
return 0.00; | |||||
} | |||||
} | |||||
/** | |||||
* 获取double,主要过滤d为null的情况; | |||||
* | |||||
* @param d Double对象; | |||||
* @return double | |||||
*/ | |||||
public static double todouble(Double d) { | |||||
if (d == null) return 0.0d; | |||||
return d.doubleValue(); | |||||
} | |||||
/** | |||||
* 自动过滤金额中的逗号转换为float,如果出错,则返回0 | |||||
* | |||||
* @param s 源串,可能为带逗号的金额串; | |||||
* @return Float | |||||
*/ | |||||
public static Float toFloat(String s) { | |||||
return tofloat(s); | |||||
} | |||||
/** | |||||
* 自动过滤金额中的逗号转换为float,如果出错,则返回0 | |||||
* | |||||
* @param s 源串,可能为带逗号的金额串; | |||||
* @return Float | |||||
*/ | |||||
public static float tofloat(String s) { | |||||
try { | |||||
return Float.parseFloat(s.replaceAll(",", "")); | |||||
} catch (Exception e) { | |||||
return 0.0f; | |||||
} | |||||
} | |||||
public static long tolong(String src, long defaultvalue) { | |||||
try { | |||||
return Long.parseLong(src); | |||||
} catch (Exception e) { | |||||
return defaultvalue; | |||||
} | |||||
} | |||||
public static int toint(String src, int defaultvalue) { | |||||
try { | |||||
return Integer.parseInt(src); | |||||
} catch (Exception e) { | |||||
return defaultvalue; | |||||
} | |||||
} | |||||
/** | |||||
* 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001 | |||||
* | |||||
* @param value double类型 | |||||
* @return boolean | |||||
*/ | |||||
public static boolean isBigThanZero(double value) { | |||||
return (value > 0.00001); | |||||
} | |||||
/** | |||||
* 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001 | |||||
* | |||||
* @param value String类型 | |||||
* @return boolean | |||||
*/ | |||||
public static boolean isBigThanZero(String value) { | |||||
return !StringUtil.isEmpty(value) && isBigThanZero(toDouble(value)); | |||||
} | |||||
/** | |||||
* 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。 | |||||
* | |||||
* @param value double类型 | |||||
* @return boolean | |||||
*/ | |||||
public static boolean isEqualsZero(double value) { | |||||
return (-0.00001 < value && value < 0.00001); | |||||
} | |||||
/** | |||||
* 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。 | |||||
* | |||||
* @param value String类型 | |||||
* @return boolean | |||||
*/ | |||||
public static boolean isEqualsZero(String value) { | |||||
return StringUtil.isEmpty(value) || isEqualsZero(toDouble(value)); | |||||
} | |||||
/** | |||||
* 是否是负数 | |||||
* | |||||
* @param db_val 要判断的double | |||||
* @return 负数则返回true; | |||||
*/ | |||||
public static boolean isNegative(double db_val) { | |||||
return (compare(db_val, 0.00D) == -1); | |||||
} | |||||
/** | |||||
* 是否是正数 | |||||
* | |||||
* @param db_val 要判断的double | |||||
* @return 正数则返回true; | |||||
*/ | |||||
public static boolean isPlus(double db_val) { | |||||
return (compare(db_val, 0.00D) == 1); | |||||
} | |||||
/** | |||||
* 得到金额字符串,保持小数点2位 | |||||
* | |||||
* @param db 将double转换为金额字符串; | |||||
* @return 金额字符串#0.00; | |||||
*/ | |||||
public static String toStdNumberString(double db) { | |||||
try { | |||||
return stdNumberFormat.format(db); | |||||
} catch (Exception e) { | |||||
return "0.00"; | |||||
} | |||||
} | |||||
public static String toStdNumberStringEx(double db) { | |||||
try { | |||||
if (compare(db, -1d) == 0) return "-"; | |||||
return stdNumberFormat.format(db); | |||||
} catch (Exception e) { | |||||
return "0.00"; | |||||
} | |||||
} | |||||
/** | |||||
* 将金额格式字符串,如23,333,093.01 去掉逗号 | |||||
* | |||||
* @param s 金额串 | |||||
* @return String 去掉逗号后的串,如果amount为空,则返回0.00 | |||||
*/ | |||||
public static String toStdNumberString(String s) { | |||||
if (StringUtil.isEmpty(s)) | |||||
return "0.00"; | |||||
return stdNumberFormat.format(MathUtil.todouble(s)); | |||||
} | |||||
/** | |||||
* 将数据转换为两位小数的数字格式; | |||||
* | |||||
* @param d 数据 | |||||
* @param isZeroToEmpty 如果未0,是否返回“”; | |||||
* @return 两位小数的字符串; | |||||
*/ | |||||
public static String toStdNumberString(double d, boolean isZeroToEmpty) { | |||||
if (isEqualsZero(d)) { | |||||
return isZeroToEmpty ? "" : "0.00"; | |||||
} | |||||
return stdNumberFormat.format(d); | |||||
} | |||||
public static String toStdNumberString(String s, boolean isZeroToEmpty) { | |||||
return toStdNumberString(MathUtil.todouble(s), isZeroToEmpty); | |||||
} | |||||
public static String toStdNumberString(double d, int scale) { | |||||
DecimalFormat dfn = null; | |||||
if (scale == 1) dfn = df1Format; | |||||
if (scale == 2) dfn = df2Format; | |||||
else if (scale == 4) dfn = df4; | |||||
else if (scale == 6) dfn = df6NumberF; | |||||
else if (scale <= 0) dfn = dfLong; | |||||
else { | |||||
StringBuilder sb = new StringBuilder("###,###,###,###,##0."); | |||||
for (int i = 0; i < scale; i++) sb.append("0"); | |||||
dfn = new DecimalFormat(sb.toString()); | |||||
} | |||||
return dfn.format(d); | |||||
} | |||||
/** | |||||
* 将数字乘100,保留小数点后两位, 然后后面添加% | |||||
* | |||||
* @param d 值 | |||||
* @param isZeroToEmpty,如果值为0,是否返回空; | |||||
* @return 字符串; | |||||
*/ | |||||
public static String toStdPercentNumberStr(double d, boolean isZeroToEmpty) { | |||||
if (d > -0.00000000001 && d < 0.00000000001) { | |||||
return isZeroToEmpty ? "" : "0.00%"; | |||||
} | |||||
return toStdNumberString(d * 100) + "%"; | |||||
} | |||||
public static String toStdAmountString(double d) { | |||||
return toStdAmountString(d, false); | |||||
} | |||||
/** | |||||
* 将数据转换为两位小数的金额格式,带逗号; | |||||
* | |||||
* @param d 数据 | |||||
* @param isZeroToEmpty 如果未0,是否返回“”; | |||||
* @return 金额格式的字符串; | |||||
*/ | |||||
public static String toStdAmountString(double d, boolean isZeroToEmpty) { | |||||
if (isEqualsZero(d)) { | |||||
return isZeroToEmpty ? "" : "0.00"; | |||||
} | |||||
return stdAmountFormat.format(d); | |||||
} | |||||
public static String toStdAmountString(String s) { | |||||
return toStdAmountString(MathUtil.todouble(s), false); | |||||
} | |||||
public static String toStdAmountString(String s, boolean isZeroToEmpty) { | |||||
return toStdAmountString(MathUtil.todouble(s), isZeroToEmpty); | |||||
} | |||||
/** | |||||
* 将小写金额转换为人民币大写金额 | |||||
* | |||||
* @param s 金额格式的串 | |||||
* @return String 转换结果 | |||||
*/ | |||||
public static String toCapsAmountString(String s) { | |||||
if (StringUtil.isEmpty(s)) return ""; | |||||
return toCapsAmountString(todouble(s)); | |||||
} | |||||
/** | |||||
* 将小写金额转换为人民币大写金额 | |||||
* | |||||
* @param v double | |||||
* @return String 转换结果 | |||||
*/ | |||||
public static String toCapsAmountString(double v) { | |||||
if (v < MIN_VALUE || v > MAX_VALUE) return "参数非法!"; | |||||
boolean negative = isNegative(v); | |||||
if (negative) v = Math.abs(v); | |||||
long l = Math.round(v * 100); | |||||
if (l == 0) return "零元整"; | |||||
String strValue = String.valueOf(l); | |||||
// i用来控制数 | |||||
int i = 0; | |||||
// j用来控制单位 | |||||
int j = UNIT.length() - strValue.length(); | |||||
StringBuilder rs = new StringBuilder(32); | |||||
boolean isZero = false; | |||||
for (; i < strValue.length(); i++, j++) { | |||||
char ch = strValue.charAt(i); | |||||
if (ch == '0') { | |||||
isZero = true; | |||||
if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') { | |||||
rs.append(UNIT.charAt(j)); | |||||
isZero = false; | |||||
} | |||||
} else { | |||||
if (isZero) { | |||||
rs.append('零'); | |||||
isZero = false; | |||||
} | |||||
rs.append(DIGIT.charAt(ch - '0')).append(UNIT.charAt(j)); | |||||
} | |||||
} | |||||
if (rs.charAt(rs.length() - 1) != '分') | |||||
rs.append('整'); | |||||
i = rs.indexOf("亿万"); | |||||
if (i > 0) rs.delete(i + 1, i + 2); // i+1 ->万 | |||||
if (negative) | |||||
return rs.insert(0, '负').toString(); | |||||
else | |||||
return rs.toString(); | |||||
} | |||||
/** | |||||
* 返回0 到 maxvalue的随机数 | |||||
* | |||||
* @param maxvalue 随机数的最大值 | |||||
* @return int | |||||
*/ | |||||
public static int rnd(int maxvalue) { | |||||
return (int) (Math.random() * (maxvalue + 1)); | |||||
} | |||||
public static double chkDbNull(Double v) { | |||||
return v == null ? 0 : v; | |||||
} | |||||
public static double max(double d1, double d2) { | |||||
return compare(d1, d2) < 0 ? d2 : d1; | |||||
} | |||||
public static double min(double d1, double d2) { | |||||
return compare(d1, d2) < 0 ? d1 : d2; | |||||
} | |||||
/** | |||||
* double 去尾法 | |||||
* | |||||
* @param src 待处理数据 | |||||
* @param scale 保留小数位数 | |||||
* @return | |||||
*/ | |||||
public static double cutDouble(double src, int scale) { | |||||
String v = toStdNumberString(src, 6);//先到6位小数,再去计算,否则容易出错,如8.3成8.29999999999,舍位就成了8.29了 | |||||
DecimalFormat formater = new DecimalFormat(); | |||||
formater.setMaximumFractionDigits(scale); | |||||
formater.setGroupingSize(0); | |||||
formater.setRoundingMode(RoundingMode.FLOOR); | |||||
return new BigDecimal(formater.format(toDouble(v))).doubleValue(); | |||||
} | |||||
public static String getAmountStr(double amount) { | |||||
return df2Format.format(amount); | |||||
} | |||||
//数字转字符串,如无小数,则去掉.00 | |||||
public static String getDoubleStr(double d) { | |||||
return getAmountStr(d).replaceAll(",", "").replaceAll("\\.00", ""); | |||||
} | |||||
/** | |||||
* double 进位法 | |||||
* | |||||
* @param src 待处理数据 | |||||
* @param scale 保留小数位数 | |||||
* @return | |||||
*/ | |||||
public static double upDouble(double src, int scale) { | |||||
String v = toStdNumberString(src, 6);//先到6位小数,再去计算 | |||||
DecimalFormat formater = new DecimalFormat(); | |||||
formater.setMaximumFractionDigits(scale); | |||||
formater.setGroupingSize(0); | |||||
formater.setRoundingMode(RoundingMode.UP); | |||||
return new BigDecimal(formater.format(toDouble(v))).doubleValue(); | |||||
} | |||||
/** | |||||
* 计算公式 参数以Map方式传入 | |||||
* | |||||
* @param expr 表达式 | |||||
* @param mapVar 变量 | |||||
* @return 计算结果 | |||||
*/ | |||||
public static Object calcExprMapObject(String expr, Map<String, Object> mapVar) { | |||||
if (StringUtil.isEmpty(expr)) return ""; | |||||
JexlContext jc = new MapContext(); | |||||
jc.set("Math", Math.class); | |||||
jc.set("UtilPub", StringUtil.class); | |||||
for (String k : mapVar.keySet()) jc.set(k, mapVar.get(k)); | |||||
JexlExpression e = new Engine().createExpression(expr); | |||||
return e.evaluate(jc); | |||||
} | |||||
/** | |||||
* 计算公式,参数以数组方式传入,key、value交替 | |||||
* | |||||
* @param expr 表达式 | |||||
* @param vars 变量 | |||||
* @return | |||||
*/ | |||||
public static Object calcExprObjectEx(String expr, Object... vars) { | |||||
if (StringUtil.isEmpty(expr)) return ""; | |||||
JexlContext jc = new MapContext(); | |||||
jc.set("Math", Math.class); | |||||
jc.set("UtilPub", StringUtil.class); | |||||
for (int i = 0, len = vars.length; i < len; ) { | |||||
jc.set((String) vars[i++], vars[i++]); | |||||
} | |||||
JexlExpression e = new Engine().createExpression(expr); | |||||
return e.evaluate(jc); | |||||
} | |||||
public static double calcExprMapDouble(String expr, Map<String, Object> mapVar) { | |||||
Object o = calcExprMapObject(expr, mapVar); | |||||
if (o != null) return StringUtil.getDoubleIgnoreErr(o.toString()); | |||||
return 0.0; | |||||
} | |||||
public static double calcExprDoubleEx(String expr, Object... vars) { | |||||
Object o = calcExprObjectEx(expr, vars); | |||||
if (o != null) return StringUtil.getDoubleIgnoreErr(o.toString()); | |||||
return 0.0; | |||||
} | |||||
} |
@@ -5,6 +5,7 @@ import org.apache.commons.lang3.StringUtils; | |||||
import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||
import java.text.Collator; | import java.text.Collator; | ||||
import java.text.DecimalFormat; | |||||
import java.util.*; | import java.util.*; | ||||
/** | /** | ||||
@@ -15,6 +16,8 @@ import java.util.*; | |||||
*/ | */ | ||||
@SuppressWarnings("UnusedDeclaration") | @SuppressWarnings("UnusedDeclaration") | ||||
public class StringUtil { | public class StringUtil { | ||||
private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00"); | |||||
private static Collator chineseCollator = Collator.getInstance(Locale.CHINA); | private static Collator chineseCollator = Collator.getInstance(Locale.CHINA); | ||||
public static boolean isEmpty(String str) { | public static boolean isEmpty(String str) { | ||||
@@ -182,6 +185,52 @@ public class StringUtil { | |||||
} | } | ||||
/** | /** | ||||
* 获取浮点数(有错误默认为0),可以识别金额中的逗号格式 | |||||
* | |||||
* @param str 带转换的字符串 | |||||
* @return 浮点数 | |||||
*/ | |||||
public static double getDoubleIgnoreErr(String str) { | |||||
if (str == null) | |||||
return 0.0; | |||||
str = str.trim(); | |||||
if (str.equals("")) | |||||
return 0.0; | |||||
str = str.replaceAll(",", "").replaceAll(",", ""); | |||||
try { | |||||
return Double.valueOf(str); | |||||
} catch (Exception e) { | |||||
return 0.0; | |||||
} | |||||
} | |||||
/** | |||||
* 得到int 获取转换的int值,有错返回0 | |||||
* | |||||
* @param str 带转换的字符串 | |||||
* @return int | |||||
*/ | |||||
public static int getIntIgnoreErr(String str) { | |||||
return getIntIgnoreErr(str, 0); | |||||
} | |||||
public static int getIntIgnoreErr(String str, int defValue) { | |||||
if (str == null) | |||||
return defValue; | |||||
str = str.trim(); | |||||
if (str.equals("")) | |||||
return defValue; | |||||
str = str.replaceAll(",", "").replaceAll(",", ""); | |||||
if (str.contains(".")) | |||||
str = str.substring(0, str.indexOf('.')); | |||||
try { | |||||
return Integer.valueOf(str); | |||||
} catch (Exception e) { | |||||
return defValue; | |||||
} | |||||
} | |||||
/** | |||||
* 取得重复字串 | * 取得重复字串 | ||||
* | * | ||||
* @param repeatString 重复字串 | * @param repeatString 重复字串 | ||||