>source

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" 모든 노드의 노드. 이 json 데이터를 헤더 열이있는 csv 파일로 변경하기 위해 아래 Java 코드를 만들었습니다.

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 (FEDERAL RESERVE BANK OF ST. LOUIS)에서 데이터를 추출하려고합니다. 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")

하지만 자바 API는 더 이상 사용되지 않으므로 json 값을 csv 파일로 변환하는 간단한 자바 API를 개발해야합니다. 인터넷 검색으로 아래 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 기둥. 첫 번째 줄에는 notes 핵심 가치.

그래서이 코드 줄을 다음 줄로 변경합니다.

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

그러나이 선은 내가 예상하지 못한 결과를 낳습니다. 아래와 같이 반복되는 중복 열

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

나는이 부분에 완전히 붙어 있습니다.

  • 답변 # 1

    아마도 아래와 같이 bin 유형 클래스를 작성하는 것이 가장 쉽습니다.

    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

    라이브러리 Apache Commons IO로 할 수 있습니다.

    pom.xml

    <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
    
    

  • 이전 amazon iam - AWS Lambda에 서버리스 배포를 수행하는 IAM 사용자에게 필요한 정책은 무엇입니까?
  • 다음 Twilio SMS 서비스의 SmartEncoding이 C # API를 통해 éÉÑñ과 같은 GSM-7 문자를 보낼 수 있습니까?