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>
相关推荐
月亮不月亮22 分钟前
月亮商场购物打折Java
java·eclipse
guozhetao32 分钟前
【ST表、倍增】P7167 [eJOI 2020] Fountain (Day1)
java·c++·python·算法·leetcode·深度优先·图论
技术思考者32 分钟前
基础很薄弱如何规划考研
java·经验分享·考研
●VON1 小时前
重生之我在暑假学习微服务第二天《MybatisPlus-下篇》
java·学习·微服务·架构·mybatis-plus
老华带你飞1 小时前
口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)
java·数据库·微信小程序·小程序·论文·毕设·口腔小程序
hqxstudying1 小时前
J2EE模式---服务层模式
java·数据库·后端·spring·oracle·java-ee
GM_8281 小时前
【最新最完整】SpringAI-1.0.0开发MCP Server,搭建MCP Client 实战笔记(进阶+详细+完整代码)
java·后端·ai编程·springai·mcp
都叫我大帅哥1 小时前
Java DelayQueue:时间管理大师的终极武器
java
秋千码途1 小时前
小架构step系列27:Hibernate提供的validator
java·spring·架构·hibernate
都叫我大帅哥1 小时前
TOGAF迁移规划阶段全解密:从菜鸟到达人的通关秘籍
java