第一步,导入poi的Maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
第二步,实现自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelColumn {
String value() default "";
}
第三步,编写导出的工具类
/**
* 类上面的字段 -> 加上 @ExcelColumn("表头") 的注解
* @author 木池
*/
@Slf4j
public class ExcelUtil {
public static <T> void write(List<T> objectList, OutputStream fileOut) {
Workbook workbook = new XSSFWorkbook();
try {
Sheet sheet = workbook.createSheet("Sheet1");
createHeader(sheet, objectList.get(0).getClass());
createRows(sheet, objectList);
workbook.write(fileOut);
} catch (IOException e) {
log.error("Error writing to Excel file: {}", e.getMessage());
} finally {
try {
fileOut.close();
workbook.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* 写入Excel文件 Sheet1 中
* @param objectList 存储对象的集合
* @param filePath 文件路径 为空 则是桌面路径
* @return 文件路径
* @param <T> 泛型
*/
public static <T> String writeToExcel(List<T> objectList, String filePath) {
if (filePath == null || filePath.isEmpty()) {
filePath = getDefaultDesktopPath() + "\\" + objectList.get(0).getClass().getSimpleName() + ".xlsx";
}
byte[] utf8Bytes = filePath.getBytes(StandardCharsets.UTF_8);
String newFileName = new String(utf8Bytes, StandardCharsets.UTF_8);
try (Workbook workbook = new XSSFWorkbook(); FileOutputStream fileOut = new FileOutputStream(newFileName)) {
Sheet sheet = workbook.createSheet("Sheet1");
Font font = getFont(sheet);
createHeader(sheet, objectList.get(0).getClass(), font);
createRows(sheet, objectList);
// autoSizeColumns(sheet);
workbook.write(fileOut);
} catch (IOException e) {
log.error("Error writing to Excel file: {}", e.getMessage());
}
return newFileName;
}
/**
* 创建表头
* @param sheet 表单对象
* @param clazz 类对象
* @param <T> 泛型
*/
private static <T> void createHeader(Sheet sheet, Class<T> clazz) {
createHeader(sheet, clazz, null);
}
private static <T> void createHeader(Sheet sheet, Class<T> clazz, Font headerFont) {
CellStyle headerCellStyle = sheet.getWorkbook().createCellStyle();
if (null != headerFont) {
headerCellStyle.setFont(headerFont);
}
Row headerRow = sheet.createRow(0);
List<String> propertyNames = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
ExcelColumn excelColumnAnnotation = field.getAnnotation(ExcelColumn.class);
if (excelColumnAnnotation != null) {
propertyNames.add(excelColumnAnnotation.value());
}
}
int cellNum = 0;
for (String propertyName : propertyNames) {
Cell headerCell = headerRow.createCell(cellNum++);
headerCell.setCellValue(propertyName);
headerCell.setCellStyle(headerCellStyle);
}
}
private static @NotNull Font getFont(Sheet sheet) {
Font headerFont = sheet.getWorkbook().createFont();
headerFont.setBold(true);
headerFont.setFontHeightInPoints((short) 14);
return headerFont;
}
/**
* 创建每行的数据
* @param sheet 表单
* @param objectList 对象集合
* @param <T> 泛型
*/
private static <T> void createRows(Sheet sheet, List<T> objectList) {
int rowNum = 1;
for (T object : objectList) {
Row row = sheet.createRow(rowNum++);
int cellNum = 0;
for (Field field : object.getClass().getDeclaredFields()) {
ExcelColumn excelColumnAnnotation = field.getAnnotation(ExcelColumn.class);
if (excelColumnAnnotation != null) {
field.setAccessible(true);
try {
Object value = field.get(object);
Cell cell = row.createCell(cellNum++);
if (value != null) {
if (value instanceof String) {
cell.setCellValue((String) value);
} else if (value instanceof Number) {
cell.setCellValue(((Number) value).doubleValue());
} else if (value instanceof Boolean) {
cell.setCellValue((Boolean) value);
} else {
cell.setCellValue(value.toString());
}
} else {
cell.setCellValue("");
}
} catch (IllegalAccessException e) {
log.error("Error accessing field: {}", e.getMessage());
}
}
}
}
}
private static void autoSizeColumns(Sheet sheet) {
for (int i = 0; i < sheet.getRow(0).getLastCellNum(); i++) {
sheet.autoSizeColumn(i);
}
}
private static String getDefaultDesktopPath() {
return System.getProperty("user.home") + "\\Desktop";
}
/**
* kimi 不能超过 131072 字数
* 计算Excel文件中的字数,只适合 Excel文件格式,不包含空格 和 特殊符号
* @param filePath 文件路径
* @return 字数
*/
public static int getWordCount(String filePath) {
Path excelPath = Paths.get(filePath);
try (InputStream fis = Files.newInputStream(excelPath);
Workbook workbook = new XSSFWorkbook(fis)) {
int wordCount = 0;
for (Sheet sheet : workbook) {
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.STRING) {
String cellValue = cell.getStringCellValue();
if (cellValue != null) {
wordCount += cellValue.length();
}
}
}
}
}
return wordCount;
} catch (IOException e) {
return 0;
}
}
}