170 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Java
		
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Java
		
	
	
package com.youchain.utils;
 | 
						||
 | 
						||
import cn.idev.excel.FastExcel;
 | 
						||
import cn.idev.excel.write.metadata.style.WriteCellStyle;
 | 
						||
import cn.idev.excel.write.metadata.style.WriteFont;
 | 
						||
import cn.idev.excel.write.style.HorizontalCellStyleStrategy;
 | 
						||
import com.youchain.exception.BadRequestException;
 | 
						||
import lombok.extern.slf4j.Slf4j;
 | 
						||
import org.apache.commons.collections4.CollectionUtils;
 | 
						||
import org.apache.commons.lang3.StringUtils;
 | 
						||
import org.apache.poi.ss.usermodel.IndexedColors;
 | 
						||
import org.springframework.http.HttpHeaders;
 | 
						||
import org.springframework.http.MediaType;
 | 
						||
import org.springframework.http.MediaTypeFactory;
 | 
						||
import org.springframework.web.multipart.MultipartFile;
 | 
						||
 | 
						||
import javax.servlet.http.HttpServletResponse;
 | 
						||
import java.io.IOException;
 | 
						||
import java.io.UnsupportedEncodingException;
 | 
						||
import java.net.URLEncoder;
 | 
						||
import java.util.Collection;
 | 
						||
import java.util.List;
 | 
						||
import java.util.Map;
 | 
						||
import java.util.stream.Collectors;
 | 
						||
 | 
						||
import static cn.hutool.core.util.CharsetUtil.UTF_8;
 | 
						||
 | 
						||
@Slf4j
 | 
						||
public class FastExcelUtils {
 | 
						||
 | 
						||
    /**
 | 
						||
     * 设置下载文件消息头
 | 
						||
     *
 | 
						||
     * @param response 响应
 | 
						||
     * @param fileName 文件名
 | 
						||
     * @param fileSize 文件大小
 | 
						||
     */
 | 
						||
    public static void setDownloadFileHeader(HttpServletResponse response, String fileName, Long fileSize) {
 | 
						||
        response.setCharacterEncoding(UTF_8);
 | 
						||
        if (fileSize != null) {
 | 
						||
            response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileSize));
 | 
						||
        }
 | 
						||
 | 
						||
        if (StringUtils.isNotEmpty(fileName)) {
 | 
						||
            response.setHeader(HttpHeaders.CONTENT_TYPE, MediaTypeFactory.getMediaType(fileName).orElse(MediaType.APPLICATION_OCTET_STREAM) + ";charset=utf-8");
 | 
						||
            try {
 | 
						||
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(fileName, UTF_8).replaceAll("\\+", "%20"));
 | 
						||
            } catch (UnsupportedEncodingException e) {
 | 
						||
                throw new RuntimeException(e);
 | 
						||
            }
 | 
						||
            response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 获取样式
 | 
						||
     *
 | 
						||
     * @return horizontalCellStyleStrategy
 | 
						||
     */
 | 
						||
    public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
 | 
						||
 | 
						||
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
 | 
						||
        headWriteCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
 | 
						||
 | 
						||
        WriteFont headWriteFont = new WriteFont();
 | 
						||
        headWriteFont.setFontName("宋体");
 | 
						||
        headWriteFont.setColor(IndexedColors.WHITE.getIndex());
 | 
						||
        headWriteCellStyle.setWriteFont(headWriteFont);
 | 
						||
 | 
						||
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
 | 
						||
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.BLACK.getIndex());
 | 
						||
 | 
						||
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 通用单sheet导出
 | 
						||
     */
 | 
						||
    public static void exportExcel(HttpServletResponse response, String fileName, String sheetName, Class head, Collection<?> data) throws IOException {
 | 
						||
        // 设置下载消息头
 | 
						||
        setDownloadFileHeader(response, fileName, null);
 | 
						||
        //样式
 | 
						||
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
 | 
						||
        // 下载
 | 
						||
        FastExcel.write(response.getOutputStream(), head)
 | 
						||
                .autoCloseStream(Boolean.FALSE)
 | 
						||
                .sheet(sheetName)
 | 
						||
                .registerWriteHandler(horizontalCellStyleStrategy)
 | 
						||
                .doWrite(data);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 从 Excel 文件中读取指定类型的数据
 | 
						||
     *
 | 
						||
     * @param file  上传的 Excel 文件
 | 
						||
     * @param clazz 数据映射的类(如 Template1.class)
 | 
						||
     * @param <T>   数据类型
 | 
						||
     * @return 解析后的数据列表
 | 
						||
     */
 | 
						||
    public static <T> List<T> readExcelData(MultipartFile file, Class<T> clazz, int sheetNo, int headRowNumber) {
 | 
						||
        List<T> dataList;
 | 
						||
        try {
 | 
						||
            dataList = FastExcel.read(file.getInputStream()).head(clazz)
 | 
						||
                    .sheet(sheetNo)
 | 
						||
                    .headRowNumber(headRowNumber)
 | 
						||
                    .doReadSync();
 | 
						||
        } catch (IOException e) {
 | 
						||
            throw new BadRequestException("数据格式存在问题,无法读取");
 | 
						||
        }
 | 
						||
        if (CollectionUtils.isEmpty(dataList)) {
 | 
						||
            throw new BadRequestException("数据为空");
 | 
						||
        }
 | 
						||
        return dataList;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 读取Excel文件中指定位置的单元格值
 | 
						||
     *
 | 
						||
     * @param file   Excel文件
 | 
						||
     * @param reader 指定行和列
 | 
						||
     */
 | 
						||
    public static Map<String, String> readExcelCellValues(MultipartFile file, FastExcelCellListener reader) {
 | 
						||
        try {
 | 
						||
            FastExcel.read(file.getInputStream(), reader)
 | 
						||
                    .sheet()
 | 
						||
                    .doReadSync();
 | 
						||
        } catch (IOException e) {
 | 
						||
            throw new BadRequestException("Excel文件读取失败,请检查文件格式是否正确");
 | 
						||
        }
 | 
						||
        return reader.getAllCellValues();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 读取 Excel 指定目录指定行
 | 
						||
     *
 | 
						||
     * @param file Excel 文件
 | 
						||
     * @return 回返指定目录指定行返回的内容
 | 
						||
     */
 | 
						||
    public static List<String> readHeadContent(MultipartFile file, int sheetNo, int headRowNumber) {
 | 
						||
        List<Object> data;
 | 
						||
        try {
 | 
						||
            data = FastExcel.read(file.getInputStream())
 | 
						||
                    .sheet(sheetNo)
 | 
						||
                    .headRowNumber(headRowNumber)
 | 
						||
                    .doReadSync();
 | 
						||
        } catch (IOException e) {
 | 
						||
            throw new BadRequestException("Excel 文件读取失败: " + e.getMessage());
 | 
						||
        }
 | 
						||
 | 
						||
        // 检查是否有数据
 | 
						||
        if (CollectionUtils.isEmpty(data)) {
 | 
						||
            throw new BadRequestException("数据为空");
 | 
						||
        }
 | 
						||
 | 
						||
        // 获取并验证首行数据
 | 
						||
        Object firstRow = data.get(0);
 | 
						||
        if (!(firstRow instanceof Map)) {
 | 
						||
            throw new BadRequestException("读取Excel头部内容格式异常");
 | 
						||
        }
 | 
						||
 | 
						||
        // 将头部内容转换为字符串列表
 | 
						||
        Map<?, ?> rowMap = (Map<?, ?>) firstRow;
 | 
						||
        return rowMap.values().stream()
 | 
						||
                .map(value -> value == null ? "" : value.toString())
 | 
						||
                .collect(Collectors.toList());
 | 
						||
 | 
						||
    }
 | 
						||
}
 |