方法实现:
2个excel表格,假设表格A的b列代表姓名,表格B中的c列代表姓名。
对比2个表格,将既在A表又在B表的数据称为重复的数据.
将表格A和表格B重复的数据,分别另存为表格C和表格D
java
package org.example;
/**
* @author :pq
* @date : 2024/10/8
*/
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
/**
* 方法实现:
* 2个excel表格,假设表格A的b列代表姓名,表格B中的c列代表姓名。
* 对比2个表格,将既在A表又在B表的数据称为重复的数据.
* 将表格A和表格B重复的数据,分别另存为表格C和表格D
*/
public class ExcelComparator {
public static void main(String[] args) {
//A: 用表3 姓名在E列 标题行有1行
//B: 用表1 姓名在A列 标题行有2行
String filePathA = "C:\\Users\\Administrator\\Desktop\\pq\\20241009\\excelA.xlsx"; // 替换为你的Excel文件A的路径
String filePathB = "C:\\Users\\Administrator\\Desktop\\pq\\20241009\\excelB.xlsx"; // 替换为你的Excel文件B的路径
String filePathC = "C:\\Users\\Administrator\\Desktop\\pq\\excelC.xlsx"; // 替换为你希望保存A表重复数据的路径
String filePathD = "C:\\Users\\Administrator\\Desktop\\pq\\excelD.xlsx"; // 替换为你希望保存B表重复数据的路径
//用哪个sheet
int Asheet = 2;
int Bsheet = 0;
//用那个列
int AIndex = 4;
int BIndex = 0;
//标题行有几行
int Atitle = 0;
int Btitle = 1;
try (FileInputStream fisA = new FileInputStream(filePathA);
FileInputStream fisB = new FileInputStream(filePathB);
Workbook workbookA = new XSSFWorkbook(fisA);
Workbook workbookB = new XSSFWorkbook(fisB);
Workbook workbookC = new XSSFWorkbook();
Workbook workbookD = new XSSFWorkbook()) {
Sheet sheetA = workbookA.getSheetAt(Asheet); // 假设处理第一个工作表
Sheet sheetB = workbookB.getSheetAt(Bsheet); // 假设处理第一个工作表,依次类推,第二个工作表应该填写"1".
Set<String> namesA = new HashSet<>();
Set<String> namesB = new HashSet<>();
Set<String> commonNames = new HashSet<>();
// 读取表格B的姓名
for (Row row : sheetB) {
if (row.getRowNum() > Btitle) { // 跳过标题行,一般情况下,标题行为一行,这里为1行。所以大于0,要是2行就大于1
Cell cell = row.getCell(BIndex); // D列(索引为3)是姓名
if (cell != null && cell.getCellType() == CellType.STRING) {
namesB.add(cell.getStringCellValue());
}
}
}
// 读取表格A的姓名并找出重复项
Sheet sheetC = workbookC.createSheet("Sheet1");
Sheet sheetD = workbookD.createSheet("Sheet1");
Row headerC = sheetC.createRow(0);
Row headerD = sheetD.createRow(0);
Row headerD1 = sheetD.createRow(1);
// 根据实际情况,你可能需要调整标题行的复制逻辑
for (Cell cell : sheetA.getRow(0)) {
headerC.createCell(cell.getColumnIndex()).setCellValue(cell.getStringCellValue());
// headerD.createCell(cell.getColumnIndex()).setCellValue(cell.getStringCellValue());
}
for (Cell cell : sheetB.getRow(0)){
headerD.createCell(cell.getColumnIndex()).setCellValue(cell.getStringCellValue());
}
for (Cell cell : sheetB.getRow(1)){
headerD1.createCell(cell.getColumnIndex()).setCellValue(cell.getStringCellValue());
}
int rowIndexC = Atitle+1;
int rowIndexD = Btitle+1;
for (Row row : sheetA) {
if (row.getRowNum() > Atitle) { // 跳过标题行
Cell cell = row.getCell(AIndex); // A列(索引为0)
if (cell != null && cell.getCellType() == CellType.STRING) {
String name = cell.getStringCellValue();
if (namesB.contains(name)) {
commonNames.add(name);
// 将重复项添加到表格D
Row newRowC = sheetC.createRow(rowIndexC++);
copyRow(row, newRowC, sheetA); // 假设你想要复制整行数据到表格C
} else {
// 如果需要,也可以将B表中不在A表中的姓名保存到另一个表格(此处省略)
}
// 添加到namesA集合,用于后续判断A表的重复项
namesA.add(name);
// 如果需要找出B表中重复但A表中没有的姓名,可以在此处添加逻辑
}
}
}
// 由于commonNames已经包含了所有重复项,我们可以再次遍历B表来找出B表中的重复项并保存到表
// 但注意,这里我们其实已经知道B表中的重复项就是commonNames里的所有项,所以可以直接处理
for (Row row : sheetB) {
if (row.getRowNum() > Btitle && commonNames.contains(row.getCell(BIndex).getStringCellValue())) {
//赋值单元格
// Row newRowD = sheetD.createRow(rowIndexD++);
// for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
// Cell newCellD = newRowD.createCell(i);
// copyCellValue(row.getCell(i), newCellD);
// }
// 将重复项添加到表格D
Row newRowD = sheetD.createRow(rowIndexD++);
copyRow(row, newRowD, sheetB); // 假设你想要复制整行数据到表格D
}
}
//判断新文件是否存在,不存在则新建。
Path pathC = Paths.get(filePathC);
Path pathD = Paths.get(filePathD);
if (!Files.exists(pathC)){
Files.createFile(pathC);
}
if (!Files.exists(pathD)){
Files.createFile(pathD);
}
// 写入新的Excel文件
try (FileOutputStream fosC = new FileOutputStream(filePathC);
FileOutputStream fosD = new FileOutputStream(filePathD)) {
workbookC.write(fosC);
workbookD.write(fosD);
}
System.out.println("处理完成,重复数据已保存到指定文件。");
System.out.println("重复项:"+commonNames.size());
} catch (IOException e) {
e.printStackTrace();
}
}
// 辅助方法,用于复制单元格内容
private static void copyCellValue(Cell oldCell, Cell newCell) {
if (oldCell == null) {
return;
}
switch (oldCell.getCellType()) {
case STRING:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(oldCell)) {
newCell.setCellValue(oldCell.getDateCellValue());
} else {
newCell.setCellValue(oldCell.getNumericCellValue());
}
break;
case BOOLEAN:
newCell.setCellValue(oldCell.getBooleanCellValue());
break;
case FORMULA:
newCell.setCellFormula(oldCell.getCellFormula());
break;
case BLANK:
newCell.setBlank();
break;
// 根据需要添加其他类型的处理
default:
break;
}
}
// 辅助方法:复制一行数据(根据需要调整列的对齐)
private static void copyRow(Row sourceRow, Row targetRow, Sheet sourceSheet) {
for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
Cell sourceCell = sourceRow.getCell(i);
Cell targetCell = targetRow.createCell(i);
if (sourceCell != null) {
switch (sourceCell.getCellType()) {
case STRING:
targetCell.setCellValue(sourceCell.getStringCellValue());
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(sourceCell)) {
targetCell.setCellValue(sourceCell.getDateCellValue());
} else {
targetCell.setCellValue(sourceCell.getNumericCellValue());
}
break;
case BOOLEAN:
targetCell.setCellValue(sourceCell.getBooleanCellValue());
break;
case FORMULA:
targetCell.setCellFormula(sourceCell.getCellFormula());
break;
case BLANK:
targetCell.setBlank();
break;
case ERROR:
targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
break;
default:
break;
}
}
}
}
}
xml
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>