不多比比,上代码
pom.xml文件
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.0</version>
</dependency>
Utill.java
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.concurrent.ForkJoinPool;
/**
* @author Lucas-x
* date 2023-09-19
*/
@RestController
@RequestMapping(value = "/POI")
public class POIUtil {
/**
* 暂时使用普通流处理版本,因为文件数据不大
*/
@RequestMapping(value = "/poiTest")
public void poiTest() {
String filePath = "D:\\example\\example.xlsx";
try {
List<Map<String, String>> records = readExcelWithStream(filePath);
System.out.println(records);
// 在这里,你可以对 records 列表进行操作,例如插入到数据库
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 普通版本的(for循环版本)
*/
public static List<Map<String, String>> readExcelWithFor(String filePath) throws IOException {
List<Map<String, String>> records = new ArrayList<>();
FileInputStream fis = new FileInputStream(new File(filePath));
XSSFWorkbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
// 读取表头,保存为 List<String>
Row headerRow = sheet.getRow(0);
List<String> headers = new ArrayList<>();
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
Cell cell = headerRow.getCell(i);
headers.add(getCellValue(cell));
}
// 读取数据
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row != null) {
Map<String, String> record = new HashMap<>();
for (int j = 0; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
String header = headers.get(j);
String value = getCellValue(cell);
record.put(header, value);
}
records.add(record);
}
}
workbook.close();
fis.close();
return records;
}
private static String getCellValue(Cell cell) {
String cellValue = "";
if (cell != null) {
switch (cell.getCellType()) {
case STRING:
cellValue = cell.getStringCellValue();
break;
case NUMERIC:
cellValue = String.valueOf((int) cell.getNumericCellValue());
break;
case BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
default:
break;
}
}
return cellValue;
}
/**
* 普通流处理版本
*/
public static List<Map<String, String>> readExcelWithStream(String filePath) throws IOException {
FileInputStream fis = new FileInputStream(new File(filePath));
XSSFWorkbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
// 读取表头,保存为 List<String>
Row headerRow = sheet.getRow(0);
List<String> headers = IntStream.range(0, headerRow.getLastCellNum())
.mapToObj(headerRow::getCell)
.map(Cell::getStringCellValue)
.collect(Collectors.toList());
List<Map<String, String>> records = IntStream.range(1, sheet.getPhysicalNumberOfRows())
.mapToObj(sheet::getRow)
.filter(Objects::nonNull)
.map(row -> IntStream.range(0, row.getLastCellNum())
.boxed()
.collect(Collectors.toMap(
headers::get,
j -> {
Cell cell = row.getCell(j);
return cell != null ? cell.toString() : "";
}
)))
.collect(Collectors.toList());
workbook.close();
fis.close();
return records;
}
/**
* 多线程流处理版
*/
private static ForkJoinPool forkJoinPool = new ForkJoinPool();
public static List<Map<String, String>> readExcelWiththread(String filePath) throws IOException {
FileInputStream fis = new FileInputStream(new File(filePath));
XSSFWorkbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
// 读取表头,保存为 List<String>
Row headerRow = sheet.getRow(0);
List<String> headers = IntStream.range(0, headerRow.getLastCellNum())
.mapToObj(headerRow::getCell)
.map(Cell::getStringCellValue)
.collect(Collectors.toList());
List<Map<String, String>> records = forkJoinPool.submit(() ->
IntStream.range(1, sheet.getPhysicalNumberOfRows())
.parallel()
.mapToObj(sheet::getRow)
.filter(Objects::nonNull)
.map(row -> IntStream.range(0, row.getLastCellNum())
.boxed()
.collect(Collectors.toMap(
headers::get,
j -> {
Cell cell = row.getCell(j);
return cell != null ? cell.toString() : "";
}
)))
.collect(Collectors.toList())
).join();
workbook.close();
fis.close();
return records;
}
}
以上代码的作用,读取excel文件,并返回一个List<Map<String, String>>
对上述不同版本进行一下说明:
- 普通for循环版本,low,for循环多,慢,效率低,基础
- 普通流处理(Stream API),通常情况想,比for循环优雅。对于不熟悉Stream API的人,可读性低。
- 多线程流处理版本,基于2(Stream API),数据量很大,机器性能比较高的情况下,可最高效。
以上三个版本代码放在一起了,根据需要可以自行解封任一版本,import都在,根据需求可自行删改。