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
相关产品推荐
相关产品推荐

