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

Java读取3个CSV文件并实现类Excel排序及文件对比技术问询

实现类Excel的控制台CSV排序及后续对比优化

我已经用Java实现了读取3个CSV文件的功能,现在想优化代码,实现类似Excel的控制台排序效果。我的最终目标是从第一个文件(QR.csv)中校验问题是否存在,选定问题后对比另外两个结构相似的文件(PivotSegmentQuestion.csv和PivotSegmentQuestionNCL.csv)找出差异,现在先咨询如何实现初始的排序功能。

现有代码

package readAndPrint;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class read3file {

    public static void main(String[] args) {
        // 定义文件路径
        String sPathDirectory ="C:\\Users\\...\\Downloads\\";
        String pathFileQR = sPathDirectory + "QR.csv";
        String pathFilePivot = sPathDirectory + "PivotSegmentQuestion.csv";
        String pathFileNCL = sPathDirectory + "PivotSegmentQuestionNCL.csv";
        
        
        // 读取并打印QR.csv
        readAndPrintFile(pathFileQR);
        
        // 读取并打印PivotSegmentQuestion.csv
        readAndPrintFile(pathFilePivot);
        
        // 读取并打印PivotSegmentQuestionNCL.csv
        readAndPrintFile(pathFileNCL);
        }
    
        // 读取并打印文件的方法
        private static void readAndPrintFile(String filePath) {
            String line = "";
            
            try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
                while ((line = br.readLine()) !=null)
                    System.out.println(line);
                
                System.out.println("找到文件: " + filePath); // 确认信息
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                System.out.println("未找到文件:" + filePath); // 错误提示
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

优化思路与实现

要实现类Excel的排序和格式化输出,核心是把CSV行数据转换成可操作的对象,再实现排序逻辑,最后格式化输出对齐。

1. 定义CSV数据实体类

假设你的CSV包含问题ID,问题内容,分类这类列(可根据实际结构调整),先定义实体类存储每行数据:

package readAndPrint;

public class QuestionRecord {
    private String questionId;
    private String questionContent;
    private String category;

    // 构造方法
    public QuestionRecord(String questionId, String questionContent, String category) {
        this.questionId = questionId;
        this.questionContent = questionContent;
        this.category = category;
    }

    // Getter方法(排序需要用到)
    public String getQuestionId() {
        return questionId;
    }

    public String getQuestionContent() {
        return questionContent;
    }

    public String getCategory() {
        return category;
    }

    // 格式化输出,模拟Excel列对齐
    @Override
    public String toString() {
        // 可根据实际内容调整字段宽度
        return String.format("%-15s %-50s %-20s", questionId, questionContent, category);
    }
}

2. 重构CSV读取方法,返回对象列表

把原来的打印方法改成读取并解析为对象列表的方法:

import java.util.ArrayList;
import java.util.List;

private static List<QuestionRecord> readCsvToRecords(String filePath) {
    List<QuestionRecord> records = new ArrayList<>();
    String line = "";
    String csvSplitBy = ","; // CSV分隔符,实际如果是分号等可调整

    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
        // 跳过表头(如果CSV有表头的话)
        br.readLine();
        
        while ((line = br.readLine()) != null) {
            String[] data = line.split(csvSplitBy);
            // 确保数据列数符合要求,避免数组越界
            if (data.length >= 3) {
                records.add(new QuestionRecord(data[0].trim(), data[1].trim(), data[2].trim()));
            }
        }
        System.out.println("成功读取文件: " + filePath + ",共" + records.size() + "条数据");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.out.println("未找到文件:" + filePath);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return records;
}

3. 实现排序功能

通过Collections.sort实现按指定字段排序,支持多规则扩展:

import java.util.Collections;
import java.util.Comparator;

// 按问题ID升序排序
private static void sortRecordsById(List<QuestionRecord> records) {
    Collections.sort(records, Comparator.comparing(QuestionRecord::getQuestionId));
}

// 按问题内容降序排序
private static void sortRecordsByContent(List<QuestionRecord> records) {
    Collections.sort(records, Comparator.comparing(QuestionRecord::getQuestionContent).reversed());
}

4. 整合逻辑,格式化输出排序后的数据

在main方法中整合读取、排序、打印流程:

public static void main(String[] args) {
    String sPathDirectory ="C:\\Users\\...\\Downloads\\";
    String pathFileQR = sPathDirectory + "QR.csv";
    String pathFilePivot = sPathDirectory + "PivotSegmentQuestion.csv";
    String pathFileNCL = sPathDirectory + "PivotSegmentQuestionNCL.csv";

    // 处理QR.csv:读取+排序+打印
    List<QuestionRecord> qrRecords = readCsvToRecords(pathFileQR);
    System.out.println("\n--- 按问题ID排序后的QR.csv数据 ---");
    // 打印表头
    System.out.println(String.format("%-15s %-50s %-20s", "问题ID", "问题内容", "分类"));
    sortRecordsById(qrRecords);
    qrRecords.forEach(System.out::println);

    // 处理PivotSegmentQuestion.csv
    List<QuestionRecord> pivotRecords = readCsvToRecords(pathFilePivot);
    System.out.println("\n--- 按问题ID排序后的PivotSegmentQuestion.csv数据 ---");
    System.out.println(String.format("%-15s %-50s %-20s", "问题ID", "问题内容", "分类"));
    sortRecordsById(pivotRecords);
    pivotRecords.forEach(System.out::println);

    // 处理PivotSegmentQuestionNCL.csv
    List<QuestionRecord> nclRecords = readCsvToRecords(pathFileNCL);
    System.out.println("\n--- 按问题ID排序后的PivotSegmentQuestionNCL.csv数据 ---");
    System.out.println(String.format("%-15s %-50s %-20s", "问题ID", "问题内容", "分类"));
    sortRecordsById(nclRecords);
    nclRecords.forEach(System.out::println);
}

5. 后续对比差异的思路

排序完成后,可按以下步骤实现目标:

  • 遍历QR.csv的记录,校验问题合法性(比如ID是否为空、内容是否合规)
  • 选定目标问题ID后,在另外两个文件的记录列表中通过ID匹配找到对应记录
  • 对比两个记录的各个字段,输出差异内容

注意事项

  • 如果CSV字段包含逗号或引号,建议使用OpenCSV等成熟库解析,避免手动分割出错
  • 可扩展排序逻辑,实现多列排序(比如先按分类,再按问题ID)
  • 控制台输出的字段宽度可根据实际数据长度调整String.format中的参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:04:54