You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java提取Excel第0列重复值对应记录并写入新文件

实现Excel重复值记录筛选与导出

没问题,我来帮你改造代码,实现提取第0列存在重复值的对应记录并写入新文件的需求。核心思路是先统计第0列每个值的出现频率,再筛选出值重复的整行记录,最后把这些记录导出到新Excel里。

完整代码实现

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.*;

public class ExcelDuplicateExtractor {
    public static void main(String[] args) {
        try {
            String sourceFilePath = "你的源文件路径.xlsx";
            String targetFilePath = "导出的重复记录文件.xlsx";
            
            // 读取源Excel文件
            FileInputStream fis = new FileInputStream(sourceFilePath);
            XSSFWorkbook sourceWorkbook = new XSSFWorkbook(fis);
            Sheet sourceSheet = sourceWorkbook.getSheetAt(0);
            
            // 第一步:统计第0列每个值的出现次数
            Map<String, Integer> valueCountMap = new HashMap<>();
            for (int rowIndex = 0; rowIndex <= sourceSheet.getLastRowNum(); rowIndex++) {
                Row row = sourceSheet.getRow(rowIndex);
                if (row == null) continue;
                
                Cell cell = row.getCell(0);
                String cellValue = getCellStringValue(cell);
                if (cellValue == null || cellValue.trim().isEmpty()) continue;
                
                // 更新计数
                valueCountMap.put(cellValue, valueCountMap.getOrDefault(cellValue, 0) + 1);
            }
            
            // 第二步:筛选出第0列值重复的整行记录
            List<Row> duplicateRows = new ArrayList<>();
            for (int rowIndex = 0; rowIndex <= sourceSheet.getLastRowNum(); rowIndex++) {
                Row row = sourceSheet.getRow(rowIndex);
                if (row == null) continue;
                
                Cell cell = row.getCell(0);
                String cellValue = getCellStringValue(cell);
                if (cellValue == null || cellValue.trim().isEmpty()) continue;
                
                // 如果该值出现次数大于1,说明是重复记录
                if (valueCountMap.get(cellValue) > 1) {
                    duplicateRows.add(row);
                }
            }
            
            // 第三步:将筛选后的记录写入新Excel文件
            XSSFWorkbook targetWorkbook = new XSSFWorkbook();
            Sheet targetSheet = targetWorkbook.createSheet("重复记录");
            
            // 复制表头(如果有)和重复行
            for (int i = 0; i < duplicateRows.size(); i++) {
                Row sourceRow = duplicateRows.get(i);
                Row targetRow = targetSheet.createRow(i);
                
                // 复制每一个单元格的值和样式
                for (int colIndex = 0; colIndex < sourceRow.getLastCellNum(); colIndex++) {
                    Cell sourceCell = sourceRow.getCell(colIndex);
                    if (sourceCell == null) continue;
                    
                    Cell targetCell = targetRow.createCell(colIndex);
                    copyCellValueAndStyle(sourceCell, targetCell);
                }
            }
            
            // 自动调整列宽
            for (int colIndex = 0; colIndex < sourceSheet.getLastCellNum(); colIndex++) {
                targetSheet.autoSizeColumn(colIndex);
            }
            
            // 写入文件
            FileOutputStream fos = new FileOutputStream(targetFilePath);
            targetWorkbook.write(fos);
            
            // 关闭资源
            fos.close();
            targetWorkbook.close();
            sourceWorkbook.close();
            fis.close();
            
            System.out.println("重复记录已成功导出到:" + targetFilePath);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    // 工具方法:安全获取单元格的字符串值,兼容不同单元格类型
    private static String getCellStringValue(Cell cell) {
        if (cell == null) return null;
        
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                // 处理数字和日期类型
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 如果是公式,计算后获取值
                try {
                    return String.valueOf(cell.getNumericCellValue());
                } catch (Exception e) {
                    return cell.getStringCellValue();
                }
            default:
                return null;
        }
    }
    
    // 工具方法:复制单元格的值和样式
    private static void copyCellValueAndStyle(Cell sourceCell, Cell targetCell) {
        // 复制样式
        targetCell.setCellStyle(sourceCell.getCellStyle());
        
        // 复制值
        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;
            default:
                targetCell.setCellValue("");
        }
    }
}

关键说明

  • 统计频率:用HashMap记录第0列每个值的出现次数,这样后续判断是否重复就很高效。
  • 单元格类型兼容:原代码直接用getStringCellValue容易报错,新增的getCellStringValue方法能处理数字、日期、布尔值等多种类型,避免类型转换异常。
  • 完整行复制:不仅复制单元格的值,还复制样式,保证导出的文件和原表格格式一致。
  • 资源关闭:最后记得关闭所有流和Workbook对象,避免资源泄漏。

内容的提问来源于stack exchange,提问作者Dolly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:23:29