【问题标题】:merging two csv file with different header合并两个具有不同标题的csv文件
【发布时间】:2017-10-24 10:38:49
【问题描述】:

我需要根据各自的部分合并两个具有相似标题但数据不同的 CSV 文件中的数据。 CSV 文件将包含两部分,第一部分包含根据部门的数据,第二部分包含来自住宅区的数据。这是我的第一个 CSV 文件

Sector,Total Number of Occurrence 
sector1,12
sector2,30
sector3,100

House,Total Number of Occurrence  
B12,80
A2,87


我的第二个 CSV 文件

Sector,Total Number of Occurrence 
sector 99,89
sector 11,9

House,Total Number of Occurrence 
Q11,22
Q22,67

我希望生成一个包含两个数据的 CSV 文件,但数据必须分配到正确的部分,如下所示

Sector,Total Number of Occurrence 
sector1,12
sector2,30
sector3,100
sector 99,89
sector 11,9    

House,Total Number of Occurrence  
B12,80
A2,87
Q11,22
Q22,67


但我想我目前开发的源代码无法做到这一点,因为它包含 CSV 中列出的第二个标头 House,Total Number of Occurrence。我可以知道如何实现我想要的输出吗?这就是我当前的 csv 输出的样子

Sector,Total Number of Occurrence 
sector1,12
sector2,30
sector3,100

House,Total Number of Occurrence  
B12,80
A2,87
sector 99,89
sector 11,9

House,Total Number of Occurrence  
B12,80
A2,87 


这是我目前开发的源代码

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SummarizeReport1
{
   static ArrayList<String> list1 = new ArrayList<>();
   static String line1;
   public static void main(String[] args) throws IOException 
   {
        List<Path> paths = Arrays.asList(Paths.get("C:\\Users\\user\\Desktop\\file\\log\\backup\\report12017-10-31.csv"), Paths.get("C:\\Users\\user\\Desktop\\file\\log\\backup\\report12017-10-31 - Copy.csv"));
        List<String> mergedLines = getMergedLines(paths);
        Path target = Paths.get("C:\\Users\\user\\Desktop\\file\\log\\backup\\SummarizedReport1.csv");
        Files.write(target, mergedLines, Charset.forName("UTF-8"));
    }

    private static List<String> getMergedLines(List<Path> paths) throws IOException 
    {
        List<String> mergedLines = new ArrayList<> ();
        for (Path p : paths)
        {
            List<String> lines = Files.readAllLines(p, Charset.forName("UTF-8"));
            if (!lines.isEmpty()) {
                if (mergedLines.isEmpty()) {
                    mergedLines.add(lines.get(0)); //add header only once
                }
                mergedLines.addAll(lines.subList(1, lines.size()));
            }
        }
        return mergedLines;
    }   
}

【问题讨论】:

    标签: java csv


    【解决方案1】:

    首先,创建一个类来存储标题和每一行。

    public class SubFile{
        private String headers;
        private List<String> lines
    }
    

    然后,每行读取文件行。 对于第一行,只需使用标题创建一个新的 SubFile 实例。以下每一行,在此实例中添加它们 (addLine)。

    您需要存储多个“子”csv,所以使用Collection,这里我将使用List,因为为什么不...

    List<SubFile> files;
    

    每次读取标题(第一行或空行之后)时,您需要检查该标题是否与 Collection 中的实例匹配以继续添加或创建实例。

    public SubFile getInstance(String headerLine){
         /*
         instance = search instance in collection 
         if (instance not found)
             create instance
             add it to the list
         return instance
         */
    }
    

    我相信这会很容易实现,所以我会让你先尝试,你有算法可以使用。

    【讨论】:

    • 感谢您的建议,您的意思是我需要在另一个程序中创建另一个类调用 subFile 并将 CSV 标头存储在已在 subFile 中声明的列表中吗?我不是java专家
    • @yumi 我会使用另一个类来保持代码的整洁和可读性,但是如果你不能使用一个类,那么没有它总是可以做到的,你可以简单地使用两个ListList&lt;String&gt; headers 和(不那么有趣的阅读)List&lt;List&lt;String&gt;&gt; rows。两个列表的长度相同,标题的索引将匹配他的行的索引。就像我说的,不再干净了;)当然,学习 OOP 以及如何在 Java 中使用简单的类并不需要太多(这里不需要继承,所以你只需要基础知识。
    猜你喜欢
    • 1970-01-01
    • 2016-03-20
    • 2019-12-19
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 2012-12-08
    • 2017-10-05
    • 2021-06-15
    相关资源
    最近更新 更多