【问题标题】:How to extract data from a text file and write into CSV file in Java如何从文本文件中提取数据并用 Java 写入 CSV 文件
【发布时间】:2013-12-24 00:55:52
【问题描述】:

我有一个文本文件,其中包含参考、姓名、地址、金额、dateTo、dateFrom 和必填列,格式如下:

"120030125 J Blog  23, SOME HOUSE,                 259.44  21-OCT-2013  17-NOV-2013"
"                  SQUARE, STREET, LEICESTER,"
                   LE1 2BB

"120030318 R Mxx   37, WOOD CLOSE, BIRMINGHAM,     121.96  16-OCT-2013  17-NOV-2013  Y"                      
"                  STREET, NN18 8DF"

"120012174 JE xx   25, SOME HOUSE, QUEENS          259.44  21-OCT-2013  17-NOV-2013"
"                  SQUARE, STREET, LEICESTER,"
                   LE1 2BB

"100154992 DL x    23, SOME HOUSE, QUEENS          270.44  21-OCT-2013  17-NOV-2013  Y"             
"                  SQUARE, STREET, LEICESTER,"
                   LE1 2BC

我只对每个字符串的第一行感兴趣,想提取reference、name、amount、dateTo 和dateFrom 列中的数据,并希望将它们写入CSV 文件。目前我只能编写以下代码并提取第一行并去掉开始和结束的双引号。输入文件包含空格,输出文件也包含空格。

public class ReadTxt {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("C:/Users/me/Desktop/input.txt"));
        String pattern = "\"\\d\\d\\d\\d";

        // Create a Pattern object
        Pattern r = Pattern.compile(pattern);
        int i;
        ArrayList<String> list = new ArrayList<String>();

        boolean a = true;
        PrintWriter out = new PrintWriter(new PrintWriter("C:/Users/me/Desktop/Output.txt"), a);

        try {
            String line = br.readLine();

            while (line != null) {
                Matcher m = r.matcher(line);

                if (m.find()) {
                    String temp;
                    temp = line.substring(1, line.length() - 1);
                    list.add(temp);
                }
                else {
                // do nothing
                }

                line = br.readLine();
            }
        }
        finally {
            br.close();
        }

        for (i = 0; i < list.size(); i++) {
            out.println(list.get(i));
        }

        out.flush();
        out.close();
    }
}

上面的代码将创建一个带有以下输出的文本文件:

120030125  J Blog   23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013
120030318  R Mxx    37, WOOD CLOSE, BIRMINGHAM,  121.96  16-OCT-2013  17-NOV-2013  Y                      
120012174  JE xx    25, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013
100154992  DL x     23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013  Y

我的预期输出如下,但在 csv 文件中:

120030125  J Blog  259.44  21-OCT-2013  17-NOV-2013
120030318  R Mxx   121.96  16-OCT-2013  17-NOV-2013                        
120012174  JE xx   259.44  21-OCT-2013  17-NOV-2013
100154992  DL x    259.44  21-OCT-2013  17-NOV-2013  

任何建议、教程链接或帮助将不胜感激,因为我不是 Java 专家。我确实尝试在互联网上查找教程,但找不到任何对我有用的教程。

【问题讨论】:

  • 您向我们展示了您的实际输出,您也可以向我们展示您的预期输出吗?
  • 您想要一个教程来帮助您了解如何将这些数据写入 csv 文件?
  • @tieTYT - 我已经编辑了我的帖子以显示预期的输出。
  • 每个数据的长度是固定的吗?
  • @Adarsh - 除了第一列和日期列中的参考编号外,数据长度不固定。我希望能够提取所需的数据并用逗号分隔它们并将它们写入 CSV 文件。由于数据的长度不固定,输入文件包含空格,我不知道如何提取所需的数据。

标签: java csv export-to-csv


【解决方案1】:

在这里,测试一下。我只是使用了一个数组,但你可以在你的数组中实现必要的代码。我更改了一些地址(查看数组中的第 2 和第 3 个地址)以在不同的位置有空格和没有空格进行测试。

public class SplitData {

    public static void main(String[] args) {
        String[] array = {"120030125  J Blog   23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013",
            "120030318  R Mxx    37,WOODCLOSE,BIRMINGHAM,  121.96  16-OCT-2013  17-NOV-2013  Y 0",
            "120012174  JE xx    25, SOME HOUSE,QUEENS       259.44  21-OCT-2013  17-NOV-2013",
            "100154992  DL x     23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013  Y"  
        };

        String s1 = null;
        String s2 = null;
        String s3 = null;
        String s4 = null;
        String s5 = null;
        for (String s : array) {
            String[] split = s.split("\\s+");
            s1 = split[0];
            s2 = split[1] + " " + split[2];
            for (String string: split) {
                if (string.matches("\\d+\\.\\d{2}")) {
                    s3 = string;
                    break;
                }
            }
            String[] newArray = s.substring(s.indexOf(s3)).split("\\s+");
            s4 = newArray[1];
            s5 = newArray[2];

            System.out.printf("%s\t%s\t%s\t%s\t%s\n", s1, s2, s3, s4, s5);
        }
    }  
}

输出

120030125   J Blog  259.44  21-OCT-2013 17-NOV-2013
120030318   R Mxx   121.96  16-OCT-2013 17-NOV-2013
120012174   JE xx   259.44  21-OCT-2013 17-NOV-2013
100154992   DL x    259.44  21-OCT-2013 17-NOV-2013

【讨论】:

  • 地址可能有也可能没有空格。这不会造成问题。
  • 地址格式无关紧要。不可能没有地址。此代码忽略地址位置中的所有内容。它从数字的索引创建一个子字符串。并使用它
  • 在地址部分使用不同的字符串进行测试。这段代码是可运行的,所以你可以玩弄它。
  • @peeskillet - 感谢您的代码。它就像一个魅力。我用逗号分隔输出,如下所示:120030318,R Mxx,121.96,16-OCT-2013,17-NOV-2013。您能否指出我在 CSV 文件中输出数据的方向。再次感谢。
  • System.out.printf() 在哪里,用你的 println to file 语句替换它
【解决方案2】:
public static void main (String[] args) throws IOException {
  BufferedReader br = new BufferedReader (new FileReader ("D:/input.txt"));
  String pattern = "\"\\d\\d\\d\\d";

  // Create a Pattern object
  Pattern r = Pattern.compile (pattern);
  int i;
  ArrayList<String> list = new ArrayList<String> ();

  boolean a = true;
  PrintWriter out = new PrintWriter (new PrintWriter ("D:/Output.csv"), a);

  try {
      String line = br.readLine ();
      line= line.trim ();
      while (line != null) {
      Matcher m = r.matcher (line);
      if (m.find ()) {
          String temp;
          temp = line.substring (0, 19) + " "
                + line.substring (51, line.length () - 1);          
          temp = temp.replaceAll ("[ ]+", " ").replace ("\"", "");
          String[] array = temp.split ("[ ]");
          temp = array[0] +","+ array[1] +" "+ array[2]+","+ array[3]+","+ array[4]+","+ array[5];
          list.add (temp);
      } else {
          // do nothing
      }

      line = br.readLine ();
      }
  }   finally {
      br.close ();
  }

  for (i = 0; i < list.size (); i++) {
      out.println (list.get (i));
  }

  out.flush ();
  out.close ();
  }

输出

120030125,J Blog,259.44,21-OCT-2013,17-NOV-2013
120030318,R Mxx,121.96,16-OCT-2013,17-NOV-2013
120012174,JE xx,259.44,21-OCT-2013,17-NOV-2013
100154992,DL x,270.44,21-OCT-2013,17-NOV-2013

【讨论】:

  • Luis 所说的“除了第一列和日期列中的参考编号外,数据的长度不固定”。所以我不认为使用固定索引(51, line.length () - 1); 会起作用。我所做的是使用与数字(259.44)匹配的字符串的索引
  • 我已经在 cmets 部分与他清除了这一点。他说每个元素总是从一个固定的索引开始。所以地址部分总是从索引 19 开始,金额总是在索引 51。
  • 哦,好吧,我没听懂。 +1
  • 您仍然可能希望根据 OP 所需的输出来格式化输出。另外,您可能想使用Y :)
  • 我想要最后的 CSV 输出。感谢您指出 Y。我没有注意到它不是必需的:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多