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>
相关推荐
无敌の星仔1 分钟前
一个月学会Java 第7天 字符串与键盘输入
java·开发语言·python
GGBondlctrl9 分钟前
【JavaEE初阶】多线程案列之定时器的使用和内部原码模拟
java·开发语言·定时器·timer的使用·定时器代码模拟
多多*17 分钟前
OJ在线评测系统 微服务高级 Gateway网关接口路由和聚合文档 引入knife4j库集中查看管理并且调试网关项目
java·运维·微服务·云原生·容器·架构·gateway
惜.己1 小时前
java中日期时间类的api
java·开发语言·intellij-idea·idea·intellij idea
微刻时光1 小时前
影刀RPA实战:Excel密码与字典功能指令
笔记·低代码·自动化·excel·rpa·影刀·影刀rpa
qq_506534221 小时前
【python】追加写入excel
python·excel
bin91531 小时前
【EXCEL数据处理】000021 案例 保姆级教程,附多个操作案例。EXCEL文档安全性设置。
excel·excel数据·excel 数据分析·excel 函数·excel数据处理·excel安全性·excel数据保护
橘子海全栈攻城狮2 小时前
【源码+文档+调试讲解】基于Android的固定资产借用管理平台
android·java·spring boot·后端·python·美食
@haihi2 小时前
每天一道面试题5——Linux内核包含哪些部分?
java·linux·运维·服务器