【问题标题】:Converting Nested Json files to CSV in java在java中将嵌套的Json文件转换为CSV
【发布时间】:2013-08-03 04:34:44
【问题描述】:
    {
    "Employee": [
        {
            "empMID": "mock:1",
            "comments": [],
            "col1": "something",
            "contact": [{"address":"2400 waterview", "freetext":true}
                         ],
            "gender": "male"
        },
        {
            "empMID": "mock:2",
            "comments": [],
            "col1": "something",
            "contact": [{"address":"2200 waterview", "freetext":true}
                         ],
            "gender": "female"
        }
    ],
    "cola": false,
    "colb": false
}

这就是我的 Json 文件的外观。我需要将此 json 转换为 csv。(我正在尝试将多维数据转换为 2d)。我将 gson 用于我的目的。我不能使用 gson。 fromgson() 函数使用模板映射到对象,因为它应该是通用的。

我知道我们可以使用 CDL 将 jsonarray 转换为 csv 格式,但在我的情况下它不起作用。

我的 csv 格式看起来像

Employee*
empMID,comment.$,contact.address,contact.freetext,gender
mock:1,,2400 waterview,TRUE,male
mock:123,,2200 waterview,TRUE,female
colA#
TRUE
colB#
FALSE

我尝试使用 google-GSON api 转换为这种格式。但我无法转换为这种格式。我使用 * 来表示它的 json 数组和 # 来表示它的原始类型和 contact.address 到表示另一个 json 数组中的嵌套数组。我在关联这个嵌套结构时遇到问题。我能够像列一样递归地遍历所有内容。在此先感谢

public static void main(String[] args) throws IOException{

        BufferedReader reader=null;
        StringBuilder content=null;
        String result=null;

            reader = new BufferedReader(new FileReader("temp.json"));

            String line = null;
            content= new StringBuilder();

            while ((line = reader.readLine()) != null) {
            content.append(line);
            }
            reader.close();
            result= content.toString();

            JsonElement jelement = new JsonParser().parse(result);

            printJsonRecursive(jelement);


        }


    public static void printJsonRecursive(JsonElement jelement){


        if(jelement.isJsonPrimitive()){

            System.out.println(jelement.getAsString());
            return;
        }
        if(jelement.isJsonArray()){

            JsonArray jarray= jelement.getAsJsonArray();
            for(int i=0;i<jarray.size();i++){
                JsonElement element= jarray.get(i);
                printJsonRecursive(element);
            }
            return;

        }
        JsonObject  jobject= jelement.getAsJsonObject();

        Set<Entry<String, JsonElement>> set= jobject.entrySet();

        for (Entry<String, JsonElement> s : set) {

            printJsonRecursive(s.getValue());


        }

    }



}

【问题讨论】:

    标签: java json csv gson


    【解决方案1】:

    如果你有一个映射到 json 的对象,你可以通过反射来实现这个。

    1. 使用gson/jackson将json转成java对象

    2. 通过迭代类并使用反射附加字段并获取您感兴趣的任何字段。

    3. 通过从目标对象获取值来使用反射附加值。

    更多详情请看我下面的博文:

    vcfvct.wordpress.com/2015/06/30/converting-nested-json-files-to-csv-in-java-with-reflection/

    【讨论】:

      【解决方案2】:

      您没有打印key。这应该解决它。

          for (Entry<String, JsonElement> s : set) {
      
              System.out.println(s.getKey());            //Added
              printJsonRecursive(s.getValue());
      
          }
      

      你可以从这里照顾\ns。

      编辑

      如果您只想为重复的 json 对象打印一次键,请在递归期间创建一个 Java bean 来保存数据和 populate it。 bean 完成后,在其中添加一个方法以您想要的格式打印所有数据(仅打印一次键,依此类推)。

      【讨论】:

      • 我确实尝试过。但问题是我可以为数组中的每一行获取密钥。我只希望它打印一次。
      • 我无法创建 java bean,因为我不知道 json 的架构。例如,我不知道 json 将包含哪些结构。它应该是通用的
      【解决方案3】:

      您可以使用库 json2flat 将您的 JSON 转换为 CSV

      此库不需要任何 POJO。它只是将您的 JSON 作为字符串 并以 List&lt;Object[]&gt; 的格式返回它的 2D 表示

      例如对于 JSON:

      {
          "Employee": [
              {
                  "empMID": "mock:1",
                  "comments": [],
                  "col1": "something",
                  "contact": [{"address":"2400 waterview", "freetext":true}
                               ],
                  "gender": "male"
              },
              {
                  "empMID": "mock:2",
                  "comments": [],
                  "col1": "something",
                  "contact": [{"address":"2200 waterview", "freetext":true}
                               ],
                  "gender": "female"
              }
          ],
          "cola": false,
          "colb": false
      }
      

      它给出一个输出:

      /cola,/colb,/Employee/empMID,/Employee/col1,/Employee/gender,/Employee/contact/address,/Employee/contact/freetext
      ,,"mock:1","something",,"2400 waterview",true
      ,,"mock:2","something",,"2200 waterview",true
      false,false,,,,,
      

      【讨论】:

        【解决方案4】:
        /**
         * Get separated comlumns used a separator (comma, semi column, tab).
         *
         * @param headers The CSV headers
         * @param map     Map of key-value pairs contains the header and the value
         *
         * @return a string composed of columns separated by a specific separator.
         */
        private static String getSeperatedColumns(Set<String> headers, Map<String, String> map, String separator) {
            List<String> items = new ArrayList<String>();
            for (String header : headers) {
                String value = map.get(header) == null ? "" : map.get(header).replaceAll("[\\,\\;\\r\\n\\t\\s]+", " "); 
                items.add(value);
            }
        
            return StringUtils.join(items.toArray(), separator);
        }
        

        【讨论】:

          猜你喜欢
          • 2022-09-30
          • 2017-05-02
          • 1970-01-01
          • 1970-01-01
          • 2014-09-06
          • 1970-01-01
          • 2019-02-13
          • 1970-01-01
          相关资源
          最近更新 更多