代码之家  ›  专栏  ›  技术社区  ›  Joseph Hwang

如何用java从json数据生成csv文件?

  •  0
  • Joseph Hwang  · 技术社区  · 6 年前

    我尝试从json类型的数据生成csv文件。这些是我的json测试数据。

    {
      "realtime_start":"2020-09-25",
      "realtime_end":"2020-09-25",,
      "units": "Percent",
      "seriess": [
        {
          "name": "James",
          "age": 29,
          "house": "CA"
        },
        {
          "name": "Jina",
          "age": 39,
          "house": "MA",
          "notes": "Million tonne punch"
        },
    }
    

    问题是json数组类型 "seriess “不包含 "notes" 我编写了下面的java代码来将这个json数据更改为带有头列的csv文件

    JSONObject json = getJsonFileFromURL(...)
    
    JSONArray docsArray = json.getJSONArray("seriess");
    docsArray.put(json.get("realtime_start"));
    docsArray.put(json.get("realtime_end"));
    docsArray.put(json.get("units"));
    
    JsonNode jsonTree = new ObjectMapper().readTree(docsArray.toString());
            
    Builder csvSchemaBuilder = CsvSchema.builder();
    for(JsonNode node : jsonTree) {
        node.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} );
    }
    
    CsvSchema csvSchema = csvSchemaBuilder.build().withHeader();
    CsvMapper csvMapper = new CsvMapper();
    csvMapper.writerFor(JsonNode.class).with(csvSchema).writeValue(new File("test.csv"), jsonTree);
    

    但是错误的结果如下所示,

    realtime_start,realtime_end,units,names,age,house,realtime_start,realtime_end,units,names,age,house,notes, realtime_start,.....
    

    生成的标题列不包含不同的值。标题列将以两种形式添加。如何生成如下所示的不同头文件

    realtime_start,realtime_end,units,names,age,house, notes
    

    你知道吗?

    更新部件

    我试图从弗雷德(圣路易斯联邦储备银行)那里提取数据。FRED提供了简单方便的Python api,如下所示,

    from fredapi import Fred 
    import pandas as pd
    
    fred = Fred(api_key='abcdefghijklmnopqrstuvwxyz0123456789')
    data_unemploy = fred.search('Unemployment Rate in California')
    data_unemploy.to_csv("test_unemploy.csv")
    

    但是javaapi已经过时了,所以我不得不开发简单的javaapi,将json值转换成csv文件。我通过google找到了下面的Java代码

    JSONObject json = getJsonFileFromURL("https://api.stlouisfed.org/fred/series/search?search_text=Unemployment+Rate+in+California&api_key=abcdefghijklmnopqrstuvwxyz0123456789&file_type=json");
            
    JSONArray docsArray = json.getJSONArray("seriess");
    docsArray.put(json.get("realtime_start"));
    docsArray.put(json.get("realtime_end"));
    
    JsonNode jsonTree = new ObjectMapper().readTree(docsArray.toString());
    JsonNode firstObject = jsonTree.elements().next();  // I am struggling with this line 
    firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} );
    CsvSchema csvSchema = csvSchemaBuilder.build().withHeader();
            
    CsvMapper csvMapper = new CsvMapper();
    csvMapper.writerFor(JsonNode.class).with(csvSchema).writeValue(new File("test.csv"), jsonTree);
    

    从json数据中提取列 JsonNode firstObject = jsonTree.elements().next(); 返回第一个json节点。但这条线不会返回 notes 笔记 键值。

    for(JsonNode node : jsonTree) {
        node.fieldNames().forEachRemaining(fieldName -> {
            csvSchemaBuilder.addColumn(fieldName);
        } );
    }
    

    但是,这些线抛出的结果,我并不期待。重复的列如下所示

    实时开始,实时结束,单位,姓名,年龄,房子,实时开始,实时结束,单位,姓名,年龄,房子,笔记,实时开始,。。。。。
    

    我完全被这部分困住了。

    0 回复  |  直到 5 年前
        1
  •  1
  •   soumya-kole    6 年前

    public class CsvVo {
    
        private String realtime_start;
        private String realtime_end;
        private String units;
        private String name;
        private String age;
        private String house;
        private String notes;
    
        public void setRealtime_start(String realtime_start) {
            this.realtime_start = realtime_start;
        }
    
    //Other getters and Setters
    

    然后你可以写:

    public class ConvertJsonToCSVTest {
        public static void main(String[] args) throws JSONException {
            String jsonArrayString = "{\n" +
                    "\t\"realtime_start\": \"2020-09-25\",\n" +
                    "\t\"realtime_end\": \"2020-09-25\",\n" +
                    "\t\"units\": \"Percent\",\n" +
                    "\t\"seriess\": [{\n" +
                    "\t\t\t\"name\": \"James\",\n" +
                    "\t\t\t\"age\": 29,\n" +
                    "\t\t\t\"house\": \"CA\"\n" +
                    "\t\t},\n" +
                    "\t\t{\n" +
                    "\t\t\t\"name\": \"Jina\",\n" +
                    "\t\t\t\"age\": 39,\n" +
                    "\t\t\t\"house\": \"MA\",\n" +
                    "\t\t\t\"notes\": \"Million tonne punch\"\n" +
                    "\t\t}\n" +
                    "\t]\n" +
                    "}";
            JSONObject inJson;
                List<CsvVo> list = new ArrayList<>();
                inJson = new JSONObject(jsonArrayString);
                JSONArray inJsonSeries = inJson.getJSONArray("seriess");
                for (int i = 0, size = inJsonSeries.length(); i < size; i++){
                    CsvVo line = new CsvVo();
                    line.setRealtime_start(inJson.get("realtime_start").toString());
                    line.setRealtime_end(inJson.get("realtime_end").toString());
                    line.setUnits(inJson.get("units").toString());
                    JSONObject o = (JSONObject)inJsonSeries.get(i);
                    line.setName(o.get("name").toString());
                    line.setAge(o.get("age").toString());
                    line.setHouse(o.get("house").toString());
                    try {
                        line.setNotes(o.get("notes").toString());
                    }catch (JSONException e){
                        line.setNotes("");
                    }
                    list.add(line);
                }
                String[] cols = {"realtime_start", "realtime_end", "units", "name", "age", "house", "notes"};
                CsvUtils.csvWriterUtil(CsvVo.class, list, "in/EmpDetails.csv", cols);
    
            }
        }
    

    csvWriterUtil如下所示:

        public static <T> void csvWriterUtil(Class<T> beanClass, List<T> data, String outputFile, String[] columMapping){
            try{
                Writer writer = new BufferedWriter(new FileWriter(outputFile));
                ColumnPositionMappingStrategy<T> strategy = new ColumnPositionMappingStrategy<>();
                strategy.setType(beanClass);
                strategy.setColumnMapping(columMapping);
                StatefulBeanToCsv<T> statefulBeanToCsv =new StatefulBeanToCsvBuilder<T>(writer)
                        .withMappingStrategy(strategy)
                        .build();
                writer.write(String.join(",",columMapping)+"\n");
                statefulBeanToCsv.write(data);
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (CsvRequiredFieldEmptyException e) {
                e.printStackTrace();
            } catch (CsvDataTypeMismatchException e) {
                e.printStackTrace();
            }
        }
    

    GitRepo

        2
  •  1
  •   ArmDuke    6 年前

    你可以用ApacheCommonsIO库来实现

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>
    

    ConvertJsonToCSVTest.java文件

    import java.io.File;
    import org.apache.commons.io.FileUtils;
    import org.json.*;
    public class ConvertJsonToCSVTest {
       public static void main(String[] args) throws JSONException {
          String jsonArrayString = "{\"fileName\": [{\"first name\": \"Adam\",\"last name\": \"Smith\",\"location\": \"London\"}]}";
          JSONObject output;
          try {
             output = new JSONObject(jsonArrayString);
             JSONArray docs = output.getJSONArray("fileName");
             File file = new File("EmpDetails.csv");
             String csv = CDL.toString(docs);
             FileUtils.writeStringToFile(file, csv);
             System.out.println("Data has been Sucessfully Writeen to "+ file);
             System.out.println(csv);
          }
          catch(Exception e) {
             e.printStackTrace();
          }
       }
    }
    

    输出

    Data has been Sucessfully Writeen to EmpDetails.csv
    last name,first name,location
    Smith,Adam,London