前天,被產品經理要求我將原本二十多個excel合併成一個excel,合併後的一個excel大概30W+左右的數據量,於是我使用poi對excel進行合併,我直接貼代碼。實驗數據大概15W左右,耗時大概35秒
合併excel代碼
public static void mergeExcel(String path, String outputPath) throws IOException {
//1.校驗文件是否符合要求
File targetFile = new File(path);
if (!targetFile.exists() || !targetFile.isDirectory()) {
LOGGER.info("文件不存在或者文件不是文件夾");
return;
}
File[] files = targetFile.listFiles(p -> p.getName().endsWith(".xlsx"));
if (files == null || files.length <= 0) {
LOGGER.info("文件夾沒有excel文件");
return;
}
String startTime = DateUtil.getCurrentTimeStr();
//2.數據合併
//目前默認只合並第一個sheet,對於第一個excel文件,所有數據皆寫入,對於後面的excel,從第二行數據開始拿起
int sourceValidRows = 0;
SXSSFWorkbook srcSXSSWb = null;
for (int i = 0; i < files.length; i++) {
if (i == 0) {
InputStream is = new FileInputStream(files[i]);
XSSFWorkbook headXssfWb = new XSSFWorkbook(is);
XSSFSheet sourceSheet = headXssfWb.getSheetAt(DEFAULT_SHEEET_INDEX);
sourceValidRows = sourceSheet.getPhysicalNumberOfRows();
//3.寫入新文件
srcSXSSWb = new SXSSFWorkbook(headXssfWb);
} else {
InputStream is = new FileInputStream(files[i]);
XSSFWorkbook targetXssfWb = new XSSFWorkbook(is);
SXSSFSheet sourceSheet = srcSXSSWb.getSheetAt(DEFAULT_SHEEET_INDEX);
XSSFSheet targetSheet = targetXssfWb.getSheetAt(DEFAULT_SHEEET_INDEX);
for (int targetSheetRow = 1; targetSheetRow < targetSheet.getPhysicalNumberOfRows(); targetSheetRow++) {
LOGGER.info(i + "--" + targetSheetRow + " | sourceValidRows -- " + (sourceValidRows + targetSheetRow));
XSSFRow targetRow = targetSheet.getRow(targetSheetRow);
SXSSFRow sourceRow = sourceSheet.createRow(sourceValidRows + targetSheetRow);
for (int cellIndex = 0; cellIndex < targetRow.getPhysicalNumberOfCells(); cellIndex++) {
XSSFCell targetCell = targetRow.getCell(cellIndex);
SXSSFCell sourceCell = sourceRow.createCell(cellIndex);
sourceCell.setCellValue(targetCell.getStringCellValue());
}
}
sourceValidRows = sourceValidRows + targetSheet.getPhysicalNumberOfRows();
LOGGER.info("有效行數:" + sourceSheet.getPhysicalNumberOfRows());
is.close();
targetXssfWb.close();
}
}
//3.寫入新文件
FileOutputStream out = new FileOutputStream(outputPath);
srcSXSSWb.write(out);
out.close();
srcSXSSWb.dispose();
LOGGER.info("開始時間:" + startTime + ",結束時間:" + DateUtil.getCurrentTimeStr());
}
main方法
public static void main(String[] args) {
try {
mergeExcel("C:/Users/xxx/Desktop/asd", "C:/Users/xxx/Desktop/ae.xlsx");
} catch (IOException e) {
e.printStackTrace();
}
}