Java处理excel

方法实现:

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>
相关推荐
一 乐36 分钟前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长1 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn1 小时前
Spring 注解使用详解
java·spring
一条小小yu1 小时前
Spring IoC的理解
java·后端·spring
落魄实习生2 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈2 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白3 小时前
核心功能(Service接口)
java·mybatis
乌暮4 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习
大猫和小黄4 小时前
深入理解 Java Optional:从设计哲学到工程实战
java