1. LocalDateTime获取某月的第一天开始时间和最后一天的结束时间
/**
* 获取指定年和月的第一天和最后一天
* 应用:数据库同步,本地库和其他库按照月份分组统计后,两两比对后,得到不相同的月份,
* 根据月份的第一天和最后一天,查询两个库具体值,做交集或差集,然后得到未同步
* 的数据后同步数据
* 2022-12 xx
* 2022-11 xx
* @param month 2022-12
* @return
*/
public static Map<String, LocalDateTime> getDateOfMonth(String month){
Map<String,LocalDateTime> map = new HashMap<String, LocalDateTime>(2);
LocalDate date = LocalDate.parse(month +"-10", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//根据月份的随便一天获取这个月的第一天以及最后一天
LocalDate first = date.with(TemporalAdjusters.firstDayOfMonth());
LocalDate last = date.with(TemporalAdjusters.lastDayOfMonth());
//获取一天的第一秒和最后一秒
LocalTime beginTime = LocalTime.MIN;
LocalTime endTime = LocalTime.MAX;
//某月的第一天的第一秒
LocalDateTime beginDatetime = LocalDateTime.of(first, beginTime);
//某月的最后一天的最后一秒
LocalDateTime endDatetime = LocalDateTime.of(last, endTime);
map.put("firstDay", beginDatetime);
map.put("lastDay", endDatetime);
return map;
}
}
2.List集合切割
/**
* 集合切割成 count的集合
* 应用:当数据比较大的时候,大集合数据多比较慢还可能内存溢出,切割成小集合后,容易处理
* @param list
* @param count
* @param <T>
* @return
*/
public static <T> List<List<T>> splitList(List<T> list, int count) {
List<List<T>> listAll = new ArrayList<>();
if (list == null || list.isEmpty()) {
return listAll;
}
int size = list.size();
if (size > count) {
int num = size / count;
for (int i = 1; i < num + 1; i++) {
listAll.add(list.subList((i - 1) * count, i * count));
}
if (size - num * count > 0) {
listAll.add(list.subList(num * count, size));
}
} else {
listAll.add(list);
}
return listAll;
}
3.Stream流实现交集和差集
/**
* 交集
*
* @param list1
* @param list2
* @param <T>
* @return
*/
public static <T> List<T> intersection(List<T> list1, List<T> list2) {
if (list1 == null || list2 == null || list1.isEmpty() || list2.isEmpty()) {
return new ArrayList<>();
}
return list1.stream().filter(e -> list2.contains(e)).collect(Collectors.toList());
}
/**
* 差集 结果是list1的不在list2中的差集
*
* @param list1
* @param list2
* @param <T>
* @return
*/
public static <T> List<T> subtraction(List<T> list1, List<T> list2) {
if (list1 == null || list1.isEmpty()) {
if (list2 != null && !list2.isEmpty()) {
return list2;
} else {
return Collections.emptyList();
}
}
return list1.stream().filter(e -> !list2.contains(e)).collect(Collectors.toList());
}
4.检查url是否是有效网络地址的
/**
* 检查url是否是有效网络地址的
* @param fileUrl
* @return
*/
public static boolean checkURL(String fileUrl) {
try {
URL url = new URL(fileUrl);
URI uriObj = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
} catch (MalformedURLException | URISyntaxException e) {
return false;
}
return true;
}
5.项目启动后事件
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import static com.cdkttc.dchb.cache.DchbCache.DCHB_CACHE;
/**
* 项目启动做一些逻辑处理
*/
@Component
@RequiredArgsConstructor
public class xxx implements CommandLineRunner, Ordered {
private final IService service;
@Override
public void run(String... args) throws Exception {
//逻辑 service.xxx()
}
@Override
public int getOrder() {
return 99;
}
}
6.EasyExcel导出实现下拉选项
/**
*
* @param response
* @param fileName 导出文件名 不带后缀
* @param taskSheetName sheet 名称
* @param taskDataList 数据
* @param clazzTask 表头类
* @param <T>
*/
public static <T> void export(HttpServletResponse response, String fileName, String taskSheetName, List<T> taskDataList, Class<T> clazzTask) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding(Charsets.UTF_8.name());
fileName = URLEncoder.encode(fileName, Charsets.UTF_8.name());
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
Map<Integer, ExcelSelectedResolve> taskSelectedMap = resolveSelectedAnnotation(clazzTask);
ExcelWriter writer = EasyExcel.write(response.getOutputStream()).build();
WriteSheet taskSheet = EasyExcel.writerSheet(taskSheetName).head(clazzTask).registerWriteHandler(new SelectedSheetWriteHandler(taskSelectedMap)).build();
writer.write(taskDataList, taskSheet);
writer.finish();
} catch (IOException var6) {
throw new ServiceException("导出出错");
}
}
/**
* 解析表头类中的下拉注解
*
* @param head 表头类
* @param <T> 泛型
* @return Map<下拉框列索引, 下拉框内容> map
*/
private static <T> Map<Integer, ExcelSelectedResolve> resolveSelectedAnnotation(Class<T> head) {
Map<Integer, ExcelSelectedResolve> selectedMap = new HashMap<>();
// getDeclaredFields(): 返回全部声明的属性;getFields(): 返回public类型的属性
Field[] fields = head.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
// 解析注解信息
ExcelSelected selected = field.getAnnotation(ExcelSelected.class);
ExcelProperty property = field.getAnnotation(ExcelProperty.class);
if (selected != null) {
ExcelSelectedResolve excelSelectedResolve = new ExcelSelectedResolve();
String[] source = excelSelectedResolve.resolveSelectedSource(selected);
if (source != null && source.length > 0) {
excelSelectedResolve.setSource(source);
excelSelectedResolve.setFirstRow(selected.firstRow());
excelSelectedResolve.setLastRow(selected.lastRow());
if (property != null && property.index() >= 0) {
selectedMap.put(property.index(), excelSelectedResolve);
} else {
selectedMap.put(i, excelSelectedResolve);
}
}
}
}
return selectedMap;
}
import java.util.Map;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.springframework.stereotype.Component;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
@Component
public class SelectedSheetWriteHandler implements SheetWriteHandler {
private final Map<Integer, ExcelSelectedResolve> selectedMap;
private static char[] alphabet = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
/**
* Called before create the sheet
*/
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}
/**
* Called after the sheet is created
*/
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
// 这里可以对cell进行任何操作
Sheet sheet = writeSheetHolder.getSheet();
DataValidationHelper helper = sheet.getDataValidationHelper();
//定义sheet的名称
String dictSheetName = "字典sheet";
//1.创建一个隐藏的sheet 名称为 hidden
Workbook workbook = writeWorkbookHolder.getWorkbook();
int sheetIndex = workbook.getSheetIndex(dictSheetName);
Sheet dictSheet=null;
if (sheetIndex==-1) {
dictSheet = workbook.createSheet(dictSheetName);
Name category1Name = workbook.createName();
category1Name.setNameName(dictSheetName);
}else{
dictSheet= workbook.getSheet(dictSheetName);
}
for (Map.Entry<Integer, ExcelSelectedResolve> entry : selectedMap.entrySet()) {
// 设置下拉单元格的首行、末行、首列、末列
CellRangeAddressList rangeAddressList = new CellRangeAddressList(entry.getValue().getFirstRow(), entry.getValue().getLastRow(), entry.getKey(), entry.getKey());
int rowLen = entry.getValue().getSource().length;
DataValidationConstraint constraint=null;
if (rowLen>50){
// 设置字典sheet页的值 每一列一个字典项
for (int i = 0; i < rowLen; i++) {
Row row = dictSheet.getRow(i);
if (row == null) {
row = dictSheet.createRow(i);
}
row.createCell(entry.getKey()).setCellValue(entry.getValue().getSource()[i]);
}
String excelColumn = getExcelColumn(entry.getKey());
// 下拉框数据来源 eg:字典sheet!$B1:$B2
String refers = dictSheetName + "!$" + excelColumn + "$1:$" + excelColumn + "$" + rowLen;
// 创建可被其他单元格引用的名称
// Name name = workbook.createName();
Name name = workbook.getName("dict" + entry.getKey());
// DVConstraint constraint = DVConstraint.createExplicitListConstraint(list);
if (name==null){
name= workbook.createName();
// 设置名称的名字
name.setNameName("dict" + entry.getKey());
// 设置公式
name.setRefersToFormula(refers);
// 设置引用约束
}
constraint = helper.createFormulaListConstraint("dict" + entry.getKey());
} else{
// 设置下拉列表的值
constraint = helper.createExplicitListConstraint(entry.getValue().getSource());
}
// 设置约束
DataValidation validation = helper.createValidation(constraint, rangeAddressList);
validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
if (validation instanceof XSSFDataValidation) {
validation.setSuppressDropDownArrow(true);
validation.setShowErrorBox(true);
} else {
validation.setSuppressDropDownArrow(false);
}
validation.createErrorBox("提示", "此值与单元格定义格式不一致!");
// 阻止输入非下拉框的值
sheet.addValidationData(validation);
}
//设置列为隐藏
int hiddenIndex = workbook.getSheetIndex(dictSheetName);
if (!workbook.isSheetHidden(hiddenIndex)) {
workbook.setSheetHidden(hiddenIndex, true);
}
}
/**
* 将数字列转化成为字母列
*
* @param num
* @return
*/
private String getExcelColumn(int num) {
String column = "";
int len = alphabet.length - 1;
int first = num / len;
int second = num % len;
if (num <= len) {
column = alphabet[num] + "";
} else {
column = alphabet[first - 1] + "";
if (second == 0) {
column = column + alphabet[len] + "";
} else {
column = column + alphabet[second - 1] + "";
}
}
return column;
}
public static String getExcelLine(int num) {
String line = "";
int first = num/26;
int second = num % 26;
if (first>0) {
line = (char)('A'+first-1)+"";
}
line += (char)('A'+second)+"";
return line;
}
}
/**
* @author
*/
@Data
@ColumnWidth(15)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class XXXXExcel implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 污染类型
*/
@ApiModelProperty(value = "污染类型")
@ExcelProperty(value = "污染类型")
@ExcelSelected(sourceClass = {ExcelSelected.class})
private String polluteType;
}
public interface ExcelDynamicSelect {
/**
* 获取动态生成的下拉框可选数据
* @return 动态生成的下拉框可选数据
*/
String[] getSource();
}
import java.lang.annotation.*;
@Documented
@Target({ElementType.FIELD})//用此注解用在属性上。
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
public @interface ExcelSelected {
/**
* 固定下拉内容
*/
String[] source() default {};
/**
* 动态下拉内容
*/
Class<? extends ExcelDynamicSelect>[] sourceClass() default {};
/**
* 设置下拉框的起始行,默认为第二行
*/
int firstRow() default 1;
/**
* 设置下拉框的结束行,默认为最后一行
*/
int lastRow() default 0x10000;
}
import lombok.Data;
import lombok.RequiredArgsConstructor;
import java.util.List;
//动态下拉框中的数据配置类
@Data
@RequiredArgsConstructor
public class ExcelSelected implements ExcelDynamicSelect {
@Override
public String[] getSource() {
XXX xxx= SpringUtil.getBean("xxx", xxx.class);
List<String> list= xxx.list();
//当多列需要动态下拉框时,只需自定义类实现ExcelDynamicSelect中的方法,并在方法中查询数据即可。
return list.toArray(new String[list.size()]);
}
}
7.Mysql in用union优化
<select id="selectList" resultMap="BaseResultMap" parameterType="java.util.List" >
<foreach collection="list" item="item" index="index" separator="UNION" >
(select * from table where id = #{item} )
</foreach>
</select>