NIO-F3-Java/youchain-system/src/main/java/com/youchain/utils/FastExcelUtils.java

170 lines
6.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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());
}
}