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>
相关推荐
琪露诺大湿3 分钟前
网页聊天系统——测试报告
java·软件测试·功能测试·websocket·html·项目·测试报告
小园子的小菜5 分钟前
生产实战|冷热数据转换:从识别、触发到落地全流程解析
java·开发语言·spring
开开心心就好7 分钟前
一款既是直播工具又是浏览器的软件
linux·运维·服务器·智能手机·逻辑回归·excel·最小二乘法
invicinble9 分钟前
对于线程的思路
java
iwS2o90XT18 分钟前
WebSocket编程:Java实现实时双向通信应用
java·websocket·网络协议
Highcharts.js21 分钟前
技术组合分析:Highcharts 的数据集成能力解析
java·前端·金融·echarts·saas·bi·highcharts
shaoFan11 小时前
关于java 调用阿里千问大模型,流式返回,并返回给前端
java·前端·状态模式
雪碧聊技术1 小时前
Java历史—沙箱安全机制
java·安全·沙箱机制
java1234_小锋1 小时前
Spring AI 2.0 开发Java Agent智能体 - Spring AI 2.0简介
java·人工智能·spring·spring ai
Hesionberger1 小时前
LeetCode72.编辑距离(多维动态规划)
java·开发语言·c++·python·算法