参考 

https://blog.csdn.net/jiaobuchong/article/details/84641668

https://gitee.com/y_project/RuoYi

 

pom.xml

        <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency>
Excel.java

/*** 自定义导出Excel数据注解** @author ruoyi*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{/*** 导出到Excel中的名字.*/public String name() default "";/*** 日期格式, 如: yyyy-MM-dd*/public String dateFormat() default "";/*** 读取内容转表达式 (如: 0=男,1=女,2=未知)*/public String readConverterExp() default "";/*** 导出类型(0数字 1字符串)*/public ColumnType cellType() default ColumnType.STRING;/*** 导出时在excel中每个列的高度 单位为字符*/public double height() default 14;/*** 导出时在excel中每个列的宽 单位为字符*/public double width() default 16;/*** 文字后缀,如% 90 变成90%*/public String suffix() default "";/*** 当值为空时,字段的默认值*/public String defaultValue() default "";/*** 提示信息*/public String prompt() default "";/*** 设置只能选择不能输入的列内容.*/public String[] combo() default {};/*** 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.*/public boolean isExport() default true;/*** 另一个类中的属性名称,支持多级获取,以小数点隔开*/public String targetAttr() default "";/*** 字段类型(0:导出导入;1:仅导出;2:仅导入)*/Type type() default Type.ALL;public enum Type{ALL(0), EXPORT(1), IMPORT(2);private final int value;Type(int value){this.value = value;}public int value(){return this.value;}}public enum ColumnType{NUMERIC(0), STRING(1);private final int value;ColumnType(int value){this.value = value;}public int value(){return this.value;}}
}

Excels.java

/*** Excel注解集** @author ruoyi*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{Excel[] value();
}
ExcelUtil.java

import Excel.Type;
import Excel.ColumnType;
import Excels;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;/*** @author sun 2020/3/23 17:36*/
@SuppressWarnings("all")
public class ExcelUtil<T> {private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);/*** Excel sheet最大行数,默认65536*/public static final int sheetSize = 65536;/*** 工作表名称*/private String sheetName;/*** 导出类型(EXPORT:导出数据;IMPORT:导入模板)*/private Type type;/*** 工作薄对象*/private Workbook wb;/*** 工作表对象*/private Sheet sheet;/*** 样式列表*/private Map<String, CellStyle> styles;/*** 导入导出数据列表*/private List<T> list;/*** 注解列表*/private List<Object[]> fields;DateUtils dateUtils = new DateUtils();ReflectUtils reflectUtils = new ReflectUtils();/*** 实体对象*/public Class<T> clazz;public ExcelUtil(Class<T> clazz) {this.clazz = clazz;}public void init(List<T> list, String sheetName, Type type) {if (list == null) {list = new ArrayList<T>();}this.list = list;this.sheetName = sheetName;this.type = type;createExcelField();createWorkbook();}/*** 对excel表单默认第一个索引名转换成list** @param is 输入流* @return 转换后集合*/public List<T> importExcel(InputStream is) throws Exception {return importExcel(StringUtils.EMPTY, is);}/*** 对excel表单指定表格索引名转换成list** @param sheetName 表格索引名* @param is        输入流* @return 转换后集合*/public List<T> importExcel(String sheetName, InputStream is) throws Exception {this.type = Type.IMPORT;this.wb = WorkbookFactory.create(is);List<T> list = new ArrayList<T>();Sheet sheet = null;if (StringUtils.isNotEmpty(sheetName)) {// 如果指定sheet名,则取指定sheet中的内容.sheet = wb.getSheet(sheetName);} else {// 如果传入的sheet名不存在则默认指向第1个sheet.sheet = wb.getSheetAt(0);}if (sheet == null) {throw new IOException("文件sheet不存在");}int rows = sheet.getPhysicalNumberOfRows();if (rows > 0) {// 定义一个map用于存放excel列的序号和field.Map<String, Integer> cellMap = new HashMap<String, Integer>();// 获取表头Row heard = sheet.getRow(0);for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) {Cell cell = heard.getCell(i);if (StringUtils.isNotNull(cell != null)) {String value = this.getCellValue(heard, i).toString();cellMap.put(value, i);} else {cellMap.put(null, i);}}// 有数据时才处理 得到类的所有field.Field[] allFields = clazz.getDeclaredFields();// 定义一个map用于存放列的序号和field.Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();for (int col = 0; col < allFields.length; col++) {Field field = allFields[col];Excel attr = field.getAnnotation(Excel.class);if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) {// 设置类的私有字段属性可访问.field.setAccessible(true);Integer column = cellMap.get(attr.name());fieldsMap.put(column, field);}}for (int i = 1; i < rows; i++) {// 从第2行开始取数据,默认第一行是表头.Row row = sheet.getRow(i);T entity = null;for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet()) {Object val = this.getCellValue(row, entry.getKey());// 如果不存在实例则新建.entity = (entity == null ? clazz.newInstance() : entity);// 从map中得到对应列的field.Field field = fieldsMap.get(entry.getKey());// 取得类型,并根据对象类型设置值.Class<?> fieldType = field.getType();if (String.class == fieldType) {String s = Convert.toStr(val);if (StringUtils.endsWith(s, ".0")) {val = StringUtils.substringBefore(s, ".0");} else {String dateFormat = field.getAnnotation(Excel.class).dateFormat();if (StringUtils.isNotEmpty(dateFormat)) {val = dateUtils.parseDateToStr(dateFormat, (Date) val);} else {val = Convert.toStr(val);}}} else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {val = Convert.toInt(val);} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {val = Convert.toLong(val);} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {val = Convert.toDouble(val);} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {val = Convert.toFloat(val);} else if (BigDecimal.class == fieldType) {val = Convert.toBigDecimal(val);} else if (Date.class == fieldType) {if (val instanceof String) {val = dateUtils.parseDate(val);} else if (val instanceof Double) {val = DateUtil.getJavaDate((Double) val);}}if (StringUtils.isNotNull(fieldType)) {Excel attr = field.getAnnotation(Excel.class);String propertyName = field.getName();if (StringUtils.isNotEmpty(attr.targetAttr())) {propertyName = field.getName() + "." + attr.targetAttr();} else if (StringUtils.isNotEmpty(attr.readConverterExp())) {val = reverseByExp(String.valueOf(val), attr.readConverterExp());}reflectUtils.invokeSetter(entity, propertyName, val);}}list.add(entity);}}return list;}/*** 对list数据源将其里面的数据导入到excel表单** @param list      导出数据集合* @param sheetName 工作表的名称* @return 结果*/public ResponseEntity<byte[]> exportExcel(List<T> list, String sheetName) {this.init(list, sheetName, Type.EXPORT);return exportExcel();}/*** 对list数据源将其里面的数据导入到excel表单** @param sheetName 工作表的名称* @return 结果*/public ResponseEntity<byte[]> importTemplateExcel(String sheetName) {this.init(null, sheetName, Type.IMPORT);return exportExcel();}/*** 对list数据源将其里面的数据导入到excel表单** @return 结果*/public ResponseEntity<byte[]> exportExcel() {try {// 取出一共有多少个sheet.double sheetNo = Math.ceil(list.size() / sheetSize);for (int index = 0; index <= sheetNo; index++) {createSheet(sheetNo, index);// 产生一行Row row = sheet.createRow(0);int column = 0;// 写入各个字段的列头名称for (Object[] os : fields) {Excel excel = (Excel) os[1];this.createCell(excel, row, column++);}if (Type.EXPORT.equals(type)) {fillExcelData(index, row);}}String fileName = new String((sheetName + " " + getDateStr() + ".xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();wb.write(byteArrayOutputStream);HttpHeaders headers = new HttpHeaders();headers.add("Cache-Control", "no-cache, no-store, must-revalidate");headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"; filename*=utf-8''" + fileName);headers.add("Pragma", "no-cache");headers.add("Expires", "0");headers.add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");return ResponseEntity.ok().headers(headers).body(byteArrayOutputStream.toByteArray());} catch (IOException ex) {ex.printStackTrace();}}private String getDateStr() {return dateUtils.parseDateToStr("yyyy-MM-dd", new Date());}/*** 填充excel数据** @param index 序号* @param row   单元格行*/public void fillExcelData(int index, Row row) {int startNo = index * sheetSize;int endNo = Math.min(startNo + sheetSize, list.size());for (int i = startNo; i < endNo; i++) {row = sheet.createRow(i + 1 - startNo);// 得到导出对象.T vo = (T) list.get(i);int column = 0;for (Object[] os : fields) {Field field = (Field) os[0];Excel excel = (Excel) os[1];// 设置实体类私有属性可访问field.setAccessible(true);this.addCell(excel, row, vo, field, column++);}}}/*** 创建表格样式** @param wb 工作薄对象* @return 样式列表*/private Map<String, CellStyle> createStyles(Workbook wb) {// 写入各条记录,每条记录对应excel表中的一行Map<String, CellStyle> styles = new HashMap<String, CellStyle>();CellStyle style = wb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setBorderRight(BorderStyle.THIN);style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderLeft(BorderStyle.THIN);style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderTop(BorderStyle.THIN);style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setBorderBottom(BorderStyle.THIN);style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());Font dataFont = wb.createFont();dataFont.setFontName("Arial");dataFont.setFontHeightInPoints((short) 10);style.setFont(dataFont);styles.put("data", style);style = wb.createCellStyle();style.cloneStyleFrom(styles.get("data"));style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());style.setFillPattern(FillPatternType.SOLID_FOREGROUND);Font headerFont = wb.createFont();headerFont.setFontName("Arial");headerFont.setFontHeightInPoints((short) 10);headerFont.setBold(true);headerFont.setColor(IndexedColors.WHITE.getIndex());style.setFont(headerFont);styles.put("header", style);return styles;}/*** 创建单元格*/public Cell createCell(Excel attr, Row row, int column) {// 创建列Cell cell = row.createCell(column);// 写入列信息cell.setCellValue(attr.name());setDataValidation(attr, row, column);cell.setCellStyle(styles.get("header"));return cell;}/*** 设置单元格信息** @param value 单元格值* @param attr  注解相关* @param cell  单元格信息*/public void setCellVo(Object value, Excel attr, Cell cell) {if (ColumnType.STRING == attr.cellType()) {cell.setCellType(CellType.NUMERIC);cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());} else if (ColumnType.NUMERIC == attr.cellType()) {cell.setCellType(CellType.NUMERIC);cell.setCellValue(Integer.parseInt(value + ""));}}/*** 创建表格样式*/public void setDataValidation(Excel attr, Row row, int column) {if (attr.name().indexOf("注:") >= 0) {sheet.setColumnWidth(column, 6000);} else {// 设置列宽sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));row.setHeight((short) (attr.height() * 20));}// 如果设置了提示信息则鼠标放上去提示.if (StringUtils.isNotEmpty(attr.prompt())) {// 这里默认设了2-101列提示.setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column);}// 如果设置了combo属性则本列只能选择不能输入if (attr.combo().length > 0) {// 这里默认设了2-101列只能选择不能输入.setXSSFValidation(sheet, attr.combo(), 1, 100, column, column);}}/*** 添加单元格*/public Cell addCell(Excel attr, Row row, T vo, Field field, int column) {Cell cell = null;try {// 设置行高row.setHeight((short) (attr.height() * 20));// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.if (attr.isExport()) {// 创建cellcell = row.createCell(column);cell.setCellStyle(styles.get("data"));// 用于读取对象中的属性Object value = getTargetValue(vo, field, attr);String dateFormat = attr.dateFormat();String readConverterExp = attr.readConverterExp();if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) {cell.setCellValue(dateUtils.parseDateToStr(dateFormat, (Date) value));} else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) {cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp));} else {// 设置列类型setCellVo(value, attr, cell);}}} catch (Exception e) {log.error("导出Excel失败{}", e);}return cell;}/*** 设置 POI XSSFSheet 单元格提示** @param sheet         表单* @param promptTitle   提示标题* @param promptContent 提示内容* @param firstRow      开始行* @param endRow        结束行* @param firstCol      开始列* @param endCol        结束列*/public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow,int firstCol, int endCol) {DataValidationHelper helper = sheet.getDataValidationHelper();DataValidationConstraint constraint = helper.createCustomConstraint("DD1");CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);DataValidation dataValidation = helper.createValidation(constraint, regions);dataValidation.createPromptBox(promptTitle, promptContent);dataValidation.setShowPromptBox(true);sheet.addValidationData(dataValidation);}/*** 设置某些列的值只能输入预制的数据,显示下拉框.** @param sheet    要设置的sheet.* @param textlist 下拉框显示的内容* @param firstRow 开始行* @param endRow   结束行* @param firstCol 开始列* @param endCol   结束列* @return 设置好的sheet.*/public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) {DataValidationHelper helper = sheet.getDataValidationHelper();// 加载下拉列表内容DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist);// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);// 数据有效性对象DataValidation dataValidation = helper.createValidation(constraint, regions);// 处理Excel兼容性问题if (dataValidation instanceof XSSFDataValidation) {dataValidation.setSuppressDropDownArrow(true);dataValidation.setShowErrorBox(true);} else {dataValidation.setSuppressDropDownArrow(false);}sheet.addValidationData(dataValidation);}/*** 解析导出值 0=男,1=女,2=未知** @param propertyValue 参数值* @param converterExp  翻译注解* @return 解析后值* @throws Exception*/public static String convertByExp(String propertyValue, String converterExp) throws Exception {try {String[] convertSource = converterExp.split(",");for (String item : convertSource) {String[] itemArray = item.split("=");if (itemArray[0].equals(propertyValue)) {return itemArray[1];}}} catch (Exception e) {throw e;}return propertyValue;}/*** 反向解析值 男=0,女=1,未知=2** @param propertyValue 参数值* @param converterExp  翻译注解* @return 解析后值* @throws Exception*/public static String reverseByExp(String propertyValue, String converterExp) throws Exception {try {String[] convertSource = converterExp.split(",");for (String item : convertSource) {String[] itemArray = item.split("=");if (itemArray[1].equals(propertyValue)) {return itemArray[0];}}} catch (Exception e) {throw e;}return propertyValue;}/*** 获取bean中的属性值** @param vo    实体对象* @param field 字段* @param excel 注解* @return 最终的属性值* @throws Exception*/private Object getTargetValue(T vo, Field field, Excel excel) throws Exception {Object o = field.get(vo);if (StringUtils.isNotEmpty(excel.targetAttr())) {String target = excel.targetAttr();if (target.indexOf(".") > -1) {String[] targets = target.split("[.]");for (String name : targets) {o = getValue(o, name);}} else {o = getValue(o, target);}}return o;}/*** 以类的属性的get方法方法形式获取值** @param o* @param name* @return value* @throws Exception*/private Object getValue(Object o, String name) throws Exception {if (StringUtils.isNotEmpty(name)) {Class<?> clazz = o.getClass();String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);Method method = clazz.getMethod(methodName);o = method.invoke(o);}return o;}/*** 得到所有定义字段*/private void createExcelField() {this.fields = new ArrayList<Object[]>();List<Field> tempFields = new ArrayList<>();tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));for (Field field : tempFields) {// 单注解if (field.isAnnotationPresent(Excel.class)) {putToField(field, field.getAnnotation(Excel.class));}// 多注解if (field.isAnnotationPresent(Excels.class)) {Excels attrs = field.getAnnotation(Excels.class);Excel[] excels = attrs.value();for (Excel excel : excels) {putToField(field, excel);}}}}/*** 放到字段集合中*/private void putToField(Field field, Excel attr) {if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) {this.fields.add(new Object[]{field, attr});}}/*** 创建一个工作簿*/public void createWorkbook() {this.wb = new SXSSFWorkbook(500);}/*** 创建工作表** @param sheetNo sheet数量* @param index   序号*/public void createSheet(double sheetNo, int index) {this.sheet = wb.createSheet();this.styles = createStyles(wb);// 设置工作表的名称.if (sheetNo == 0) {wb.setSheetName(index, sheetName);} else {wb.setSheetName(index, sheetName + index);}}/*** 获取单元格值** @param row    获取的行* @param column 获取单元格列号* @return 单元格值*/public Object getCellValue(Row row, int column) {if (row == null) {return row;}Object val = "";try {Cell cell = row.getCell(column);if (cell != null) {if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) {val = cell.getNumericCellValue();if (HSSFDateUtil.isCellDateFormatted(cell)) {val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换} else {if ((Double) val % 1 > 0) {val = new DecimalFormat("0.00").format(val);} else {val = new DecimalFormat("0").format(val);}}} else if (cell.getCellTypeEnum() == CellType.STRING) {val = cell.getStringCellValue();} else if (cell.getCellTypeEnum() == CellType.BOOLEAN) {val = cell.getBooleanCellValue();} else if (cell.getCellTypeEnum() == CellType.ERROR) {val = cell.getErrorCellValue();}}} catch (Exception e) {return val;}return val;}static class Convert {/*** 转换为字符串<br>* 如果给定的值为null,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static String toStr(Object value, String defaultValue) {if (null == value) {return defaultValue;}if (value instanceof String) {return (String) value;}return value.toString();}/*** 转换为字符串<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static String toStr(Object value) {return toStr(value, null);}/*** 转换为字符<br>* 如果给定的值为null,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Character toChar(Object value, Character defaultValue) {if (null == value) {return defaultValue;}if (value instanceof Character) {return (Character) value;}final String valueStr = toStr(value, null);return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);}/*** 转换为字符<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Character toChar(Object value) {return toChar(value, null);}/*** 转换为byte<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Byte toByte(Object value, Byte defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Byte) {return (Byte) value;}if (value instanceof Number) {return ((Number) value).byteValue();}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return Byte.parseByte(valueStr);} catch (Exception e) {return defaultValue;}}/*** 转换为byte<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Byte toByte(Object value) {return toByte(value, null);}/*** 转换为Short<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Short toShort(Object value, Short defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Short) {return (Short) value;}if (value instanceof Number) {return ((Number) value).shortValue();}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return Short.parseShort(valueStr.trim());} catch (Exception e) {return defaultValue;}}/*** 转换为Short<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Short toShort(Object value) {return toShort(value, null);}/*** 转换为Number<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Number toNumber(Object value, Number defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Number) {return (Number) value;}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return NumberFormat.getInstance().parse(valueStr);} catch (Exception e) {return defaultValue;}}/*** 转换为Number<br>* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Number toNumber(Object value) {return toNumber(value, null);}/*** 转换为int<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Integer toInt(Object value, Integer defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Integer) {return (Integer) value;}if (value instanceof Number) {return ((Number) value).intValue();}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return Integer.parseInt(valueStr.trim());} catch (Exception e) {return defaultValue;}}/*** 转换为int<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Integer toInt(Object value) {return toInt(value, null);}/*** 转换为Integer数组<br>** @param str 被转换的值* @return 结果*/public static Integer[] toIntArray(String str) {return toIntArray(",", str);}/*** 转换为Long数组<br>** @param str 被转换的值* @return 结果*/public static Long[] toLongArray(String str) {return toLongArray(",", str);}/*** 转换为Integer数组<br>** @param split 分隔符* @param split 被转换的值* @return 结果*/public static Integer[] toIntArray(String split, String str) {if (StringUtils.isEmpty(str)) {return new Integer[]{};}String[] arr = str.split(split);final Integer[] ints = new Integer[arr.length];for (int i = 0; i < arr.length; i++) {final Integer v = toInt(arr[i], 0);ints[i] = v;}return ints;}/*** 转换为Long数组<br>** @param split 分隔符* @param str   被转换的值* @return 结果*/public static Long[] toLongArray(String split, String str) {if (StringUtils.isEmpty(str)) {return new Long[]{};}String[] arr = str.split(split);final Long[] longs = new Long[arr.length];for (int i = 0; i < arr.length; i++) {final Long v = toLong(arr[i], null);longs[i] = v;}return longs;}/*** 转换为String数组<br>** @param str 被转换的值* @return 结果*/public static String[] toStrArray(String str) {return toStrArray(",", str);}/*** 转换为String数组<br>** @param split 分隔符* @param split 被转换的值* @return 结果*/public static String[] toStrArray(String split, String str) {return str.split(split);}/*** 转换为long<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Long toLong(Object value, Long defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Long) {return (Long) value;}if (value instanceof Number) {return ((Number) value).longValue();}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {// 支持科学计数法return new BigDecimal(valueStr.trim()).longValue();} catch (Exception e) {return defaultValue;}}/*** 转换为long<br>* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Long toLong(Object value) {return toLong(value, null);}/*** 转换为double<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Double toDouble(Object value, Double defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Double) {return (Double) value;}if (value instanceof Number) {return ((Number) value).doubleValue();}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {// 支持科学计数法return new BigDecimal(valueStr.trim()).doubleValue();} catch (Exception e) {return defaultValue;}}/*** 转换为double<br>* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Double toDouble(Object value) {return toDouble(value, null);}/*** 转换为Float<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Float toFloat(Object value, Float defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Float) {return (Float) value;}if (value instanceof Number) {return ((Number) value).floatValue();}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return Float.parseFloat(valueStr.trim());} catch (Exception e) {return defaultValue;}}/*** 转换为Float<br>* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Float toFloat(Object value) {return toFloat(value, null);}/*** 转换为boolean<br>* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static Boolean toBool(Object value, Boolean defaultValue) {if (value == null) {return defaultValue;}if (value instanceof Boolean) {return (Boolean) value;}String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}valueStr = valueStr.trim().toLowerCase();switch (valueStr) {case "true":return true;case "false":return false;case "yes":return true;case "ok":return true;case "no":return false;case "1":return true;case "0":return false;default:return defaultValue;}}/*** 转换为boolean<br>* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static Boolean toBool(Object value) {return toBool(value, null);}/*** 转换为Enum对象<br>* 如果给定的值为空,或者转换失败,返回默认值<br>** @param clazz        Enum的Class* @param value        值* @param defaultValue 默认值* @return Enum*/public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) {if (value == null) {return defaultValue;}if (clazz.isAssignableFrom(value.getClass())) {@SuppressWarnings("unchecked")E myE = (E) value;return myE;}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return Enum.valueOf(clazz, valueStr);} catch (Exception e) {return defaultValue;}}/*** 转换为Enum对象<br>* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>** @param clazz Enum的Class* @param value 值* @return Enum*/public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) {return toEnum(clazz, value, null);}/*** 转换为BigInteger<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static BigInteger toBigInteger(Object value, BigInteger defaultValue) {if (value == null) {return defaultValue;}if (value instanceof BigInteger) {return (BigInteger) value;}if (value instanceof Long) {return BigInteger.valueOf((Long) value);}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return new BigInteger(valueStr);} catch (Exception e) {return defaultValue;}}/*** 转换为BigInteger<br>* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static BigInteger toBigInteger(Object value) {return toBigInteger(value, null);}/*** 转换为BigDecimal<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value        被转换的值* @param defaultValue 转换错误时的默认值* @return 结果*/public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {if (value == null) {return defaultValue;}if (value instanceof BigDecimal) {return (BigDecimal) value;}if (value instanceof Long) {return new BigDecimal((Long) value);}if (value instanceof Double) {return new BigDecimal((Double) value);}if (value instanceof Integer) {return new BigDecimal((Integer) value);}final String valueStr = toStr(value, null);if (StringUtils.isEmpty(valueStr)) {return defaultValue;}try {return new BigDecimal(valueStr);} catch (Exception e) {return defaultValue;}}/*** 转换为BigDecimal<br>* 如果给定的值为空,或者转换失败,返回默认值<br>* 转换失败不会报错** @param value 被转换的值* @return 结果*/public static BigDecimal toBigDecimal(Object value) {return toBigDecimal(value, null);}/*** 将对象转为字符串<br>* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法** @param obj 对象* @return 字符串*/public static String utf8Str(Object obj) {return str(obj, Charset.forName("UTF-8"));}/*** 将对象转为字符串<br>* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法** @param obj         对象* @param charsetName 字符集* @return 字符串*/public static String str(Object obj, String charsetName) {return str(obj, Charset.forName(charsetName));}/*** 将对象转为字符串<br>* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法** @param obj     对象* @param charset 字符集* @return 字符串*/public static String str(Object obj, Charset charset) {if (null == obj) {return null;}if (obj instanceof String) {return (String) obj;} else if (obj instanceof byte[] || obj instanceof Byte[]) {return str((Byte[]) obj, charset);} else if (obj instanceof ByteBuffer) {return str((ByteBuffer) obj, charset);}return obj.toString();}/*** 将byte数组转为字符串** @param bytes   byte数组* @param charset 字符集* @return 字符串*/public static String str(byte[] bytes, String charset) {return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));}/*** 解码字节码** @param data    字符串* @param charset 字符集,如果此字段为空,则解码的结果取决于平台* @return 解码后的字符串*/public static String str(byte[] data, Charset charset) {if (data == null) {return null;}if (null == charset) {return new String(data);}return new String(data, charset);}/*** 将编码的byteBuffer数据转换为字符串** @param data    数据* @param charset 字符集,如果为空使用当前系统字符集* @return 字符串*/public static String str(ByteBuffer data, String charset) {if (data == null) {return null;}return str(data, Charset.forName(charset));}/*** 将编码的byteBuffer数据转换为字符串** @param data    数据* @param charset 字符集,如果为空使用当前系统字符集* @return 字符串*/public static String str(ByteBuffer data, Charset charset) {if (null == charset) {charset = Charset.defaultCharset();}return charset.decode(data).toString();}// ----------------------------------------------------------------------- 全角半角转换/*** 半角转全角** @param input String.* @return 全角字符串.*/public static String toSBC(String input) {return toSBC(input, null);}/*** 半角转全角** @param input         String* @param notConvertSet 不替换的字符集合* @return 全角字符串.*/public static String toSBC(String input, Set<Character> notConvertSet) {char c[] = input.toCharArray();for (int i = 0; i < c.length; i++) {if (null != notConvertSet && notConvertSet.contains(c[i])) {// 跳过不替换的字符continue;}if (c[i] == ' ') {c[i] = '\u3000';} else if (c[i] < '\177') {c[i] = (char) (c[i] + 65248);}}return new String(c);}/*** 全角转半角** @param input String.* @return 半角字符串*/public static String toDBC(String input) {return toDBC(input, null);}/*** 替换全角为半角** @param text          文本* @param notConvertSet 不替换的字符集合* @return 替换后的字符*/public static String toDBC(String text, Set<Character> notConvertSet) {char c[] = text.toCharArray();for (int i = 0; i < c.length; i++) {if (null != notConvertSet && notConvertSet.contains(c[i])) {// 跳过不替换的字符continue;}if (c[i] == '\u3000') {c[i] = ' ';} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {c[i] = (char) (c[i] - 65248);}}String returnString = new String(c);return returnString;}/*** 数字金额大写转换 先写个完整的然后将如零拾替换成零** @param n 数字* @return 中文大写数字*/public static String digitUppercase(double n) {String[] fraction = {"角", "分"};String[] digit = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};String[][] unit = {{"元", "万", "亿"}, {"", "拾", "佰", "仟"}};String head = n < 0 ? "负" : "";n = Math.abs(n);String s = "";for (int i = 0; i < fraction.length; i++) {s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");}if (s.length() < 1) {s = "整";}int integerPart = (int) Math.floor(n);for (int i = 0; i < unit[0].length && integerPart > 0; i++) {String p = "";for (int j = 0; j < unit[1].length && n > 0; j++) {p = digit[integerPart % 10] + unit[1][j] + p;integerPart = integerPart / 10;}s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;}return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");}}class ReflectUtils {private static final String SETTER_PREFIX = "set";private static final String GETTER_PREFIX = "get";private static final String CGLIB_CLASS_SEPARATOR = "$$";/*** 调用Getter方法.* 支持多级,如:对象名.对象名.方法*/@SuppressWarnings("unchecked")public  <E> E invokeGetter(Object obj, String propertyName) {Object object = obj;for (String name : StringUtils.split(propertyName, ".")) {String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);object = invokeMethod(object, getterMethodName, new Class[]{}, new Object[]{});}return (E) object;}/*** 调用Setter方法, 仅匹配方法名。* 支持多级,如:对象名.对象名.方法*/public  <E> void invokeSetter(Object obj, String propertyName, E value) {Object object = obj;String[] names = StringUtils.split(propertyName, ".");for (int i = 0; i < names.length; i++) {if (i < names.length - 1) {String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);object = invokeMethod(object, getterMethodName, new Class[]{}, new Object[]{});} else {String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);invokeMethodByName(object, setterMethodName, new Object[]{value});}}}/*** 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.*/@SuppressWarnings("unchecked")public  <E> E getFieldValue(final Object obj, final String fieldName) {Field field = getAccessibleField(obj, fieldName);if (field == null) {return null;}E result = null;try {result = (E) field.get(obj);} catch (IllegalAccessException e) {}return result;}/*** 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.*/public  <E> void setFieldValue(final Object obj, final String fieldName, final E value) {Field field = getAccessibleField(obj, fieldName);if (field == null) {// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");return;}try {field.set(obj, value);} catch (IllegalAccessException e) {}}/*** 直接调用对象方法, 无视private/protected修饰符.* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.* 同时匹配方法名+参数类型,*/@SuppressWarnings("unchecked")public  <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,final Object[] args) {if (obj == null || methodName == null) {return null;}Method method = getAccessibleMethod(obj, methodName, parameterTypes);if (method == null) {return null;}try {return (E) method.invoke(obj, args);} catch (Exception e) {String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";throw convertReflectionExceptionToUnchecked(msg, e);}}/*** 直接调用对象方法, 无视private/protected修饰符,* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.* 只匹配函数名,如果有多个同名函数调用第一个。*/@SuppressWarnings("unchecked")public  <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args) {Method method = getAccessibleMethodByName(obj, methodName, args.length);if (method == null) {// 如果为空不报错,直接返回空。return null;}try {// 类型转换(将参数数据类型转换为目标方法参数类型)Class<?>[] cs = method.getParameterTypes();for (int i = 0; i < cs.length; i++) {if (args[i] != null && !args[i].getClass().equals(cs[i])) {if (cs[i] == String.class) {args[i] = Convert.toStr(args[i]);if (StringUtils.endsWith((String) args[i], ".0")) {args[i] = StringUtils.substringBefore((String) args[i], ".0");}} else if (cs[i] == Integer.class) {args[i] = Convert.toInt(args[i]);} else if (cs[i] == Long.class) {args[i] = Convert.toLong(args[i]);} else if (cs[i] == Double.class) {args[i] = Convert.toDouble(args[i]);} else if (cs[i] == Float.class) {args[i] = Convert.toFloat(args[i]);} else if (cs[i] == Date.class) {if (args[i] instanceof String) {args[i] = dateUtils.parseDate(args[i]);} else {args[i] = DateUtil.getJavaDate((Double) args[i]);}}}}return (E) method.invoke(obj, args);} catch (Exception e) {String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";throw convertReflectionExceptionToUnchecked(msg, e);}}/*** 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.* 如向上转型到Object仍无法找到, 返回null.*/public  Field getAccessibleField(final Object obj, final String fieldName) {// 为空不报错。直接返回 nullif (obj == null) {return null;}Validate.notBlank(fieldName, "fieldName can't be blank");for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {Field field = superClass.getDeclaredField(fieldName);makeAccessible(field);return field;} catch (NoSuchFieldException e) {continue;}}return null;}/*** 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.* 如向上转型到Object仍无法找到, 返回null.* 匹配函数名+参数类型。* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)*/public  Method getAccessibleMethod(final Object obj, final String methodName,final Class<?>... parameterTypes) {// 为空不报错。直接返回 nullif (obj == null) {return null;}Validate.notBlank(methodName, "methodName can't be blank");for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {try {Method method = searchType.getDeclaredMethod(methodName, parameterTypes);makeAccessible(method);return method;} catch (NoSuchMethodException e) {continue;}}return null;}/*** 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.* 如向上转型到Object仍无法找到, 返回null.* 只匹配函数名。* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)*/public  Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) {// 为空不报错。直接返回 nullif (obj == null) {return null;}Validate.notBlank(methodName, "methodName can't be blank");for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {Method[] methods = searchType.getDeclaredMethods();for (Method method : methods) {if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) {makeAccessible(method);return method;}}}return null;}/*** 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。*/public  void makeAccessible(Method method) {if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))&& !method.isAccessible()) {method.setAccessible(true);}}/*** 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。*/public  void makeAccessible(Field field) {if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())|| Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {field.setAccessible(true);}}/*** 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处* 如无法找到, 返回Object.class.*/@SuppressWarnings("unchecked")public  <T> Class<T> getClassGenricType(final Class clazz) {return getClassGenricType(clazz, 0);}/*** 通过反射, 获得Class定义中声明的父类的泛型参数的类型.* 如无法找到, 返回Object.class.*/public  Class getClassGenricType(final Class clazz, final int index) {Type genType = clazz.getGenericSuperclass();if (!(genType instanceof ParameterizedType)) {return Object.class;}Type[] params = ((ParameterizedType) genType).getActualTypeArguments();if (index >= params.length || index < 0) {return Object.class;}if (!(params[index] instanceof Class)) {return Object.class;}return (Class) params[index];}public  Class<?> getUserClass(Object instance) {if (instance == null) {throw new RuntimeException("Instance must not be null");}Class clazz = instance.getClass();if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {Class<?> superClass = clazz.getSuperclass();if (superClass != null && !Object.class.equals(superClass)) {return superClass;}}return clazz;}/*** 将反射时的checked exception转换为unchecked exception.*/public  RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) {if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException|| e instanceof NoSuchMethodException) {return new IllegalArgumentException(msg, e);} else if (e instanceof InvocationTargetException) {return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());}return new RuntimeException(msg, e);}}static class StringUtils extends org.apache.commons.lang3.StringUtils {/*** 空字符串*/private static final String NULLSTR = "";/*** * 判断一个Collection是否为空, 包含List,Set,Queue** @param coll 要判断的Collection* @return true:为空 false:非空*/public static boolean isEmpty(Collection<?> coll) {return isNull(coll) || coll.isEmpty();}/*** * 判断一个对象数组是否为空** @param objects 要判断的对象数组*                * @return true:为空 false:非空*/public static boolean isEmpty(Object[] objects) {return isNull(objects) || (objects.length == 0);}/*** * 判断一个Map是否为空** @param map 要判断的Map* @return true:为空 false:非空*/public static boolean isEmpty(Map<?, ?> map) {return isNull(map) || map.isEmpty();}/*** * 判断一个字符串是否为空串** @param str String* @return true:为空 false:非空*/public static boolean isEmpty(String str) {return isNull(str) || NULLSTR.equals(str.trim());}/*** * 判断一个字符串是否为非空串** @param str String* @return true:非空串 false:空串*/public static boolean isNotEmpty(String str) {return !isEmpty(str);}/*** * 判断一个对象是否为空** @param object Object* @return true:为空 false:非空*/public static boolean isNull(Object object) {return object == null;}/*** * 判断一个对象是否非空** @param object Object* @return true:非空 false:空*/public static boolean isNotNull(Object object) {return !isNull(object);}/*** 去空格*/public static String trim(String str) {return (str == null ? "" : str.trim());}/*** 格式化文本, {} 表示占位符<br>* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>* 例:<br>* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>** @param template 文本模板,被替换的部分用 {} 表示* @param params   参数值* @return 格式化后的文本*/public static String format(String template, Object... params) {if (isEmpty(params) || isEmpty(template)) {return template;}return StrFormatter.format(template, params);}}static class StrFormatter {public static final String EMPTY_JSON = "{}";public static final char C_BACKSLASH = '\\';public static final char C_DELIM_START = '{';public static final char C_DELIM_END = '}';/*** 格式化字符串<br>* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>* 例:<br>* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>** @param strPattern 字符串模板* @param argArray   参数列表* @return 结果*/public static String format(final String strPattern, final Object... argArray) {if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) {return strPattern;}final int strPatternLength = strPattern.length();// 初始化定义好的长度以获得更好的性能StringBuilder sbuf = new StringBuilder(strPatternLength + 50);int handledPosition = 0;int delimIndex;// 占位符所在位置for (int argIndex = 0; argIndex < argArray.length; argIndex++) {delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);if (delimIndex == -1) {if (handledPosition == 0) {return strPattern;} else { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果sbuf.append(strPattern, handledPosition, strPatternLength);return sbuf.toString();}} else {if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) {if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) {// 转义符之前还有一个转义符,占位符依旧有效sbuf.append(strPattern, handledPosition, delimIndex - 1);sbuf.append(Convert.utf8Str(argArray[argIndex]));handledPosition = delimIndex + 2;} else {// 占位符被转义argIndex--;sbuf.append(strPattern, handledPosition, delimIndex - 1);sbuf.append(C_DELIM_START);handledPosition = delimIndex + 1;}} else {// 正常占位符sbuf.append(strPattern, handledPosition, delimIndex);sbuf.append(Convert.utf8Str(argArray[argIndex]));handledPosition = delimIndex + 2;}}}// 加入最后一个占位符后所有的字符sbuf.append(strPattern, handledPosition, strPattern.length());return sbuf.toString();}}class DateUtils extends org.apache.commons.lang3.time.DateUtils {public  String YYYY = "yyyy";public  String YYYY_MM = "yyyy-MM";public  String YYYY_MM_DD = "yyyy-MM-dd";public  String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";public  String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";private  String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM","yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM","yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};/*** 获取当前Date型日期** @return Date() 当前日期*/public  Date getNowDate() {return new Date();}/*** 获取当前日期, 默认格式为yyyy-MM-dd** @return String*/public  String getDate() {return dateTimeNow(YYYY_MM_DD);}public  final String getTime() {return dateTimeNow(YYYY_MM_DD_HH_MM_SS);}public  final String dateTimeNow() {return dateTimeNow(YYYYMMDDHHMMSS);}public  final String dateTimeNow(final String format) {return parseDateToStr(format, new Date());}public  final String dateTime(final Date date) {return parseDateToStr(YYYY_MM_DD, date);}public final String parseDateToStr(final String format, final Date date) {return new SimpleDateFormat(format).format(date);}public  final Date dateTime(final String format, final String ts) {try {return new SimpleDateFormat(format).parse(ts);} catch (ParseException e) {throw new RuntimeException(e);}}/*** 日期路径 即年/月/日 如2018/08/08*/public  final String datePath() {Date now = new Date();return DateFormatUtils.format(now, "yyyy/MM/dd");}/*** 日期路径 即年/月/日 如20180808*/public  final String dateTime() {Date now = new Date();return DateFormatUtils.format(now, "yyyyMMdd");}/*** 日期型字符串转化为日期 格式*/public  Date parseDate(Object str) {if (str == null) {return null;}try {return parseDate(str.toString(), parsePatterns);} catch (ParseException e) {return null;}}/*** 获取服务器启动时间*/public  Date getServerStartDate() {long time = ManagementFactory.getRuntimeMXBean().getStartTime();return new Date(time);}/*** 计算两个时间差*/public  String getDatePoor(Date endDate, Date nowDate) {long nd = 1000 * 24 * 60 * 60;long nh = 1000 * 60 * 60;long nm = 1000 * 60;// long ns = 1000;// 获得两个时间的毫秒时间差异long diff = endDate.getTime() - nowDate.getTime();// 计算差多少天long day = diff / nd;// 计算差多少小时long hour = diff % nd / nh;// 计算差多少分钟long min = diff % nd % nh / nm;// 计算差多少秒//输出结果// long sec = diff % nd % nh % nm / ns;return day + "天" + hour + "小时" + min + "分钟";}}}

 

 

用法

public class Hotel {private Long id;/*** 在需要导出的字段上加注解* 完整用法参照  https://gitee.com/y_project/RuoYi/blob/master/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java*/@Excel(name = "酒店名称")private String name;@Excel(name = "酒店标题")private String title;@Excel(name = "酒店电话")private String telephone;
 @ResponseBody@GetMapping("/export")public ResponseEntity export(int pageNum, int pageSize, String name) {List data = (List) hotelService.list(pageNum, pageSize, name).getData();return new ExcelUtil<>(Hotel.class).exportExcel(data, "酒店数据");}

 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 《财富》杂志评选出必读的75本最睿智的图书

    《财富》杂志评选出必读的75本最睿智的图书 博客分类: 推荐书籍/网址收藏《财富》杂志评选的75本必读的最睿智的图书 有机会一定要看看!!! 其中有一本叫“影响力” 《1929 年大崩盘》(The Great Crash 1929),加尔布雷思(John Kenneth Galbraith)著,1955 年出版。这…...

    2024/4/18 17:45:06
  2. Sin City 罪恶之城

    中文名称:罪恶之城英文名称:Sin City别名:原罪之城/罪恶都市资源类型:DVDRip发行时间:2005年04月01日电影导演:昆廷特拉蒂诺 Quentin Tarantino罗伯特罗德里格兹 Robert Rodriguez弗兰克米勒 Frank Mi电影演员:布鲁斯威利斯 Bruce Willis鲁特格尔哈尔 Rutger Hauer迈克尔…...

    2024/4/28 1:06:03
  3. Android中向ContactsProvider中插入大量联系人

    应用场景项目中存在这样的需求,通过设备之间通过蓝牙传输联系人,并且需要将获取过来的联系人插入到ContactsProvider中批量插入联系人的标准代码在Android的源码中,ContactsContract.java中为我们展示了批量插入联系人的方法。The batch method is by far preferred. It in…...

    2024/4/17 7:12:48
  4. 若依源码分析(12)——在线用户监控

    在线用户监控界面 /monitor/onlinepojo - sys_user_online 在线用户表package com.ruoyi.system.domain;import java.util.Date; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.…...

    2024/4/20 18:01:18
  5. Vue+Base64实现图片上传

    Vue+Base64实现图片上传base64介绍使用样例 base64介绍 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。通俗点来讲,它可以将不算大的文件或图片转为字符,这样就可以将文件或图片存到数据库中了。 使用样…...

    2024/4/17 7:12:42
  6. android api 完整翻译之Contacts Provider (学习安卓必知的api,中英文对照)

    Contacts Provider 电话簿(注:联系人,联络人、通信录)提供者 ------------------------------- QUICKVIEW 快速概览 * Androids repository of information about people. * Android的关于人的信息的仓库。 * Syncs with the web. * 与互联网同步。 * Integrates social st…...

    2024/4/28 1:22:02
  7. jenkins git配置

    #!/bin/bash export BUILD_ID=dontKillMe sudo fuser -k -n tcp 8080; nohup java -jar -Xms512m -Xmx1024m /home/rdp/jenkins/workspace/ruoyi/experimental/sysman/target/ruoyi.jar > ruoyi.text &...

    2024/3/31 20:33:36
  8. API Guides > Contacts Provider

    Contacts Provider Contacts Provider是Android的一个强大组件,它管理联系人的核心数据。你在手机联系人看到联系人信息,来源于Contact Provider。当然,你可以在自己的应用用访问ContactProvider的数据,也可以同步手机和服务器的的联系人数据。Contact Provider存储很…...

    2024/4/27 22:11:12
  9. bootstrap-fileinput多图上传

    这里用的ruoyi大佬的开源 由BUG大佬提供方法 废话不多说 上代码<input name="commodityImg" id="commodityImg" type="hidden"><div class="form-group"><label class="font-noraml">多文件上传</la…...

    2024/4/17 7:13:30
  10. Jeff Atwood倾情推荐——程序员必读之书

    英文版:《Code Complete 2》中文版:《代码大全(第二版)》作者:Steve McConnell译者:金戈 汤凌 陈硕 张菲出版社:电子工业出版社出版日期:2007 年8月Jeff Atwood的推荐:Steve McConnell的这本书是软件开发领域里的《烹饪的乐趣》。如果你对这本书感兴趣,说明你热爱…...

    2024/4/20 10:36:38
  11. base64 加密方式详解

    base64 加密方式详解base64编码表 命名 base64是用于传输8Bit字节代码,由上图的编码表可以知道,编码后的内容只包含这64个字符类型,所以称为base64编码(不足四个字符的时候会用 ‘=’ 来补足,下面会说明)。编码过程 首先将待编码的内容转换成8位二进制,每3个字符为一组…...

    2024/4/17 7:15:00
  12. SpringBoot2后端项目-定义Controller基类和返回结果集

    目录1、定义Controller基类2、日期处理工具类3、sql操作工具类4、引入分页插件依赖5、返回 表格分页数据对象6、表格数据处理1、定义Controller基类package com.ruoyi.framework.web.controller; /*** web层通用数据处理** @author ruoyi*/ public class BaseController {prote…...

    2024/4/17 7:14:36
  13. ContactsProvider的使用

    这个东西就是Android用来共享数据的,没啥太多的东西,我也只会用,简单的了解了下原理跟使用 先上个代码 public class ContactsProvider extends ContentProvider {//主机地址 当前类的完整路径public static final String AUTHORITIES = "com.yide.yide.provider.Con…...

    2024/4/22 8:46:57
  14. 那些你不知道的事儿:2001年中美黑客大战!

    今天,让我们来聊一点别的。如果你想听,那就坐稳了。这个世界上有的不只是你所能看到的,更多的是你所看不到的,这是一个恒定不变的真理。而对于那些神秘的看不到的东西,我或者我们有着很大的好奇心。这是一个很长的故事,其实早就想把之前读到的关于一些黑客的内容写出来,…...

    2024/4/17 7:14:30
  15. 12本互联网科技大佬推荐的必读书籍

    虽然每天发送高(hao)精(nan)专(dong)的资讯文章给大家,大家还是很给面子的都来阅读了,所以能看的出大家都是很爱学习的人喔,今天就特意给大家带来了几本互联网领域的经典好书,希望大家在成为" 砖家 "的道路上走的更远哦!1、《IT 不再重要》作者:尼古拉斯 卡尔内…...

    2024/4/27 5:57:50
  16. 知识图谱的概念

    随着互联网的发展,网络数据内容呈现爆炸式增长的态势。由于互联网内容的大规模、异质多元、组织结构松散的特点,给人们有效获取信息和知识提出了挑战。知识图谱(Knowledge Graph) 以其强大的语义处理能力和开放组织能力,为互联网时代的知识化组织和智能应用奠定了基础。最近…...

    2024/4/17 7:15:00
  17. base64码通过http传输 +号变 空格 问题解决

    通过七牛云base64上传图片,通过官方示例上传成功后,根据示例改了一个controller。通过前端往后端传base64码形式进行测试。死活不通过,七牛报400。仔细排查后发现,示例转换的base64码与前端传来的base64码稍有区别,前端通过post传入的base64码将 “+” 号改成了 空格 。…...

    2024/4/18 4:26:04
  18. Java之基于注解的Excel导出

    数据库Excel导出操作代码过于冗长惨不忍睹,无法复用。目录第一步:自定义注解:第二步:实体类:第三步:解析工具类:第四步:使用:注解配合工具类做了个小工具如下:第一步:自定义注解:package com.ruoyi.framework.aspectj.lang.annotation;import java.lang.annotation.Elemen…...

    2024/3/30 12:21:39
  19. 联系人存储ContactsProvider表分析

    ContactsProvider建表的都在 packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsDatabaseHelper.java 首先该文件中有个Tables接口,其中的常量定义了数据库中大部分的表public interface Tables {public static final String CONTACTS = "…...

    2024/4/19 0:56:04
  20. html base64 img 图片显示

    大家可能注意到了,网页上有些图片的src或css背景图片的url后面跟了一大串字符,比如:data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNo8zjsOxCAMBFB/ KEAUFFR0Cbng3nQPw68ArZdAlOZpp…...

    2024/4/17 7:14:30

最新文章

  1. 香港BTC、ETH现货ETF同时通过,对行业意义几何?

    香港比美国更快一步通过以太坊现货 ETF。 2024 年 4 月 15 日&#xff0c;香港嘉实国际资产管理有限公司&#xff08;Harvest Global Investments&#xff09;今天宣布&#xff0c;得到香港证监会的原则上批准&#xff0c;将推出两大数字资产&#xff08;比特币及以太坊&#…...

    2024/4/28 4:08:43
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. WPS二次开发专题:如何获取应用签名SHA256值

    作者持续关注WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;QQ:250325397&#xff09; 在申请WPS SDK授权版时候需要开发者提供应用包名和签…...

    2024/4/23 6:15:54
  4. 腾讯云轻量服务器流量不够用了会怎么样?

    腾讯云轻量应用服务器是限制月流量的&#xff0c;如果当月流量不够用了&#xff0c;流量超额了怎么办&#xff1f;流量超额后&#xff0c;需要另外支付流量费&#xff0c;如果你的腾讯云账号余额&#xff0c;就会自动扣除对应的流量费&#xff0c;如果余额不足&#xff0c;轻量…...

    2024/4/23 6:15:09
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/26 18:09:39
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/28 3:28:32
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/26 23:05:52
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/27 4:00:35
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/27 9:01:45
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/28 1:22:35
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/25 18:39:00
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/26 19:46:12
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/27 11:43:08
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/27 8:32:30
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57