All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kangaroohy.plugin.excel.aop.RequestExcelArgumentResolver Maven / Gradle / Ivy

package com.kangaroohy.plugin.excel.aop;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.annotation.ExcelProperty;
import com.kangaroohy.plugin.excel.handler.ListAnalysisEventListener;
import com.kangaroohy.plugin.excel.annotation.RequestExcel;
import com.kangaroohy.plugin.excel.converters.LocalDateStringConverter;
import com.kangaroohy.plugin.excel.converters.LocalDateTimeStringConverter;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;

/**
 * 上传excel 解析注解
 *
 * @author hy
 * @date 2021/4/16
 */
@Slf4j
public class RequestExcelArgumentResolver implements HandlerMethodArgumentResolver {

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return parameter.hasParameterAnnotation(RequestExcel.class);
	}

	@Override
	@SneakyThrows(Exception.class)
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer modelAndViewContainer,
			NativeWebRequest webRequest, WebDataBinderFactory webDataBinderFactory) {
		Class parameterType = parameter.getParameterType();
		if (!parameterType.isAssignableFrom(List.class)) {
			throw new IllegalArgumentException(
					"Excel upload request resolver error, @RequestExcel parameter is not List " + parameterType);
		}

		// 处理自定义 readListener
		RequestExcel requestExcel = parameter.getParameterAnnotation(RequestExcel.class);
		assert requestExcel != null;
		Class> readListenerClass = requestExcel.readListener();
		ListAnalysisEventListener readListener = BeanUtils.instantiateClass(readListenerClass);
		// 获取请求文件流
		HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
		assert request != null;
		InputStream inputStream;
		if (request instanceof MultipartRequest) {
			MultipartFile file = ((MultipartRequest) request).getFile(requestExcel.fileName());
			assert file != null;
			inputStream = file.getInputStream();
		}
		else {
			inputStream = request.getInputStream();
		}

		// 获取目标类型
		Class excelModelClass = ResolvableType.forMethodParameter(parameter).getGeneric(0).resolve();

		// 这里需要指定读用哪个 class 去读,然后读取第一个 sheet 文件流会自动关闭
		EasyExcelFactory.read(inputStream, excelModelClass, readListener)
			.registerConverter(LocalDateStringConverter.INSTANCE)
			.registerConverter(LocalDateTimeStringConverter.INSTANCE)
			.ignoreEmptyRow(requestExcel.ignoreEmptyRow())
			.sheet()
			.headRowNumber(headRowNumber(excelModelClass, requestExcel))
			.doRead();

		// 校验失败的数据处理 交给 BindResult
		WebDataBinder dataBinder = webDataBinderFactory.createBinder(webRequest, readListener.getErrors(), "excel");
		ModelMap model = modelAndViewContainer.getModel();
		model.put(BindingResult.MODEL_KEY_PREFIX + "excel", dataBinder.getBindingResult());

		return readListener.getList();
	}

	private Integer headRowNumber(Class clazz, RequestExcel requestExcel) {
		Field[] fields = clazz.getDeclaredFields();
		int headRowNumber = requestExcel.headRowNumber();
		for (Field field : fields) {
			if (field.isAnnotationPresent(ExcelProperty.class)) {
				ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
				headRowNumber = Math.max(excelProperty.value().length, headRowNumber);
			}
		}
		return headRowNumber;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy