使用com.alibaba.fastjson 將 json轉換爲csv,同時指定表頭順序。/解決org.json轉換csv順序變了

引言:

fastjson目前我瞭解好像是沒有支持將 json 轉爲 csv 的,網上大多是用org.jsonCDL.toString 來將json數組轉化爲csv的,但是在我這出現兩個問題:

1. 表頭指定的順序會變:

我的json數組:
[{"name":"LiMing","age":"28","gender":"man"},{"name":"LiPing","age":"26","gender":"women"}]
我用CDL.toString 結果得到的是:

gender,name,age
women,LiPing,26
man,LiMing,28

但我們其實想要,名字在前面:

name,age,gender
LiMing,28,man
LiPing,26,women

這是因爲,CDL.toString 是根據 傳入的json數組中的JSONObject來處理的,而org.jsonJSONObject又是按a-z順序來排序,那麼問題就變成了,如何讓org.jsonJSONObject 有序,可以看到他的構造方法中,默認是HashMap, 將其改爲LinkedHashMap即可保持有序,

    public JSONObject() {
        this.map = new LinkedHashMap();
    }

但是改源碼很不方便,並且還要自己打包使用,不知道爲什麼org.json自己不出一個orderJSONObject呢。

2. 項目中都是用的fastjson,用兩個容易混亂

即使按上一步所說的修改了源碼,也會在同一個項目中用到兩個json包,特別不利於維護以及引用時容易搞錯。並且fastjson支持傳入參數指定一個有序的JSONObject,這一點比org.json好多了,但是fastjson不支持轉化爲csv,所以要寫一個將com.alibaba.fastjson.JSONArray轉化爲csv的方法,主要就是參考org.jsonCDL.java了。

解決:

以下是代碼:
使用示例:

         JSONArray array = new JSONArray();
         
        JSONObject object2 = new JSONObject(new LinkedHashMap<>()); // 傳入LinkedHashMap指定有序
        object2.put("name","LiMing");
        object2.put("age","28");
        object2.put("gender","man");
        
        JSONObject object = new JSONObject(new LinkedHashMap<>());
        object.put("name","LiPing");
        object.put("age","26");
        object.put("gender","women");
        
        array.add(object);
        array.add(object2);

        String s = ConvertCsv.toString(array);
        FileUtils.writeStringToFile(new File("E:\\hello.csv"), s);

ConcertCsv.java 工具類

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Set;

public class ConvertCsv {
    public ConvertCsv() {
    }
    public static String toString(JSONArray ja) {

        JSONObject jo = ja.getJSONObject(0);
        if (jo != null) {
            Set<String> strings = jo.keySet();
            JSONArray names = JSONArray.parseArray(JSON.toJSONString(strings));
            if (names != null) {
                return rowToString(names) + toString(names, ja);
            }
        }

        return null;
    }
    public static String rowToString(JSONArray jsonArray) {
        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < jsonArray.size() ; ++i) {
            if (i > 0) {
                sb.append(',');
            }
            Object object = jsonArray.get(i);
            if (object != null) {
                String string = object.toString();
                if (string.length() > 0 && (string.indexOf(44) >= 0 || string.indexOf(10) >= 0 || string.indexOf(13) >= 0 || string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
                    sb.append('"');
                    int length = string.length();

                    for(int j = 0; j < length; ++j) {
                        char c = string.charAt(j);
                        if (c >= ' ' && c != '"') {
                            sb.append(c);
                        }
                    }

                    sb.append('"');
                } else {
                    sb.append(string);
                }
            }
        }

        sb.append('\n');
        return sb.toString();
    }

    public static String toString(JSONArray names, JSONArray ja) {
        if (names != null && names.size() != 0) {
            StringBuilder sb = new StringBuilder();

            for(int i = 0; i < ja.size(); ++i) {
                JSONObject jo = ja.getJSONObject(i);
                if (jo != null) {
                    sb.append(rowToString(toJSONArray(jo, names)));
                }
            }

            return sb.toString();
        } else {
            return null;
        }
    }
    public static JSONArray toJSONArray(JSONObject obj, JSONArray names)  {
        if (names != null && !names.isEmpty()) {
            JSONArray ja = new JSONArray();

            for(int i = 0; i < names.size(); ++i) {
                ja.add(obj.get(names.getString(i)));
            }

            return ja;
        } else {
            return null;
        }
    }

得到數組的方式有很多,這裏就不一一介紹了,如果類型是統一的可以定義成一個class來轉換json,來指定順序,我這邊是表頭不確定。

發佈了40 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章