java - 如何在 Java 中合并 CSV 文件

标签 java csv

我的第一个 CSV 文件看起来像这样包含标题(标题仅包含在顶部而不是在每个条目之后):

NAME,SURNAME,AGE
Fred,Krueger,Unknown
.... n records

我的第二个文件可能如下所示:

NAME,MIDDLENAME,SURNAME,AGE
Jason,Noname,Scarry,16
.... n records with this header template

合并后的文件应该是这样的:

NAME,SURNAME,AGE,MIDDLENAME
Fred,Krueger,Unknown,
Jason,Scarry,16,Noname
....

基本上,如果 header 不匹配,所有新的 header 标题(列)都应添加到原始 header 之后,并根据该顺序添加它们的值。

更新

上面的 CSV 变小了,所以我可以说明我想要实现的目标,实际上 CSV 文件是在此(合并)之前的一步生成的,最多可以有 100 列

我该怎么做?

最佳答案

我将为“更大”格式创建一个模型(一个具有四个字段的简单类和一个此类实例的集合)并实现两个解析器,一个用于第一个模型,一个用于第二个模型。为两个 csv 文件的所有行创建记录,并实现编写器以正确的格式输出 csv。简而言之:

 public void convert(File output, File...input) {

   List<Record> records = new ArrayList<Record>();
   for (File file:input) {
     if (input.isThreeColumnFormat()) {
        records.addAll(ThreeColumnFormatParser.parse(file));
     } else {
        records.addAll(FourColumnFormatParser.parse(file));
     }
   }
   CsvWriter.write(output, records);
 }

从你的评论中我看到,你有很多不同的 csv 格式和一些常见的列。

您可以像这样为各种 csv 文件中的任何行定义模型:

public class Record {
  Object id; // some sort of unique identifier
  Map<String, String> values; // all key/values of a single row
  public Record(Object id) {this.id=id;}
  public void put(String key, String value){
    values.put(key, value);
  }
  public void get(String key) {
    values.get(key);
  }
}

要解析任何文件,您首先要读取标题并将列标题添加到全局 keystore (稍后需要用于输出),然后为所有行创建记录,例如:

//...
List<Record> records = new ArrayList<Record>()

for (File file:getAllFiles()) {
  List<String> keys = getColumnsHeaders(file);
  KeyStore.addAll(keys);  // the store is a Set
  for (String line:file.getLines()) {
    String[] values = line.split(DELIMITER);
    Record record = new Record(file.getName()+i);  // as an example for id
    for (int i = 0; i < values.length; i++) {
      record.put(keys.get(i), values[i]);
    }
    records.add(record);
  }
}
// ...

现在 keystore 已使用所有列标题名称,我们可以遍历所有记录的集合,获取所有键的所有值(如果此记录的文件未使用,则获取 null key ),组装 csv 行并将所有内容写入新文件。

关于java - 如何在 Java 中合并 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3307072/

相关文章:

java - Retrofit2 POST 方法获取代码 400,但适用于 ReSTLet 客户端

java - 为什么这个 AngularJS 调用会导致 400 错误请求错误(Spring 后端)

java - 字符串列表到 double java列表

java - 创建用于管理和解析命令参数的参数处理程序

python 导入 csv 列表

python - Matplotlib 根据日期时间而不是时间绘制日期

powershell - 从字符串而不是从文件导入-Csv?

java - 无法将参数传递给 super();在扩展 RealmBaseAdapter (Realm) 的类的构造函数中

node.js - 以每秒 1 行的速度解析 CSV

function - VBScript BrowseForFile() 函数 - 如何指定文件类型?