【C#】讀取Excel中嵌套的Json對象,Json帶斜槓的問題(其一)

策劃填Excel表時,約定對於複雜類型的數據採用Json的格式填寫。以下圖,D列的內容是Json數據。git

單元格中的Json以下。github

{
    "name": "BeJson2",
    "url": "http://www.bejson.com",
    "page": 88,
    "isNonProfit": true,
    "address": {
        "street": "科技園路.",
        "city": "江蘇蘇州",
        "country": "中國"
    },
    "links": [{
        "name": "Google",
        "url": "http://www.google.com"
    }, {
        "name": "Baidu",
        "url": "http://www.baidu.com"
    }, {
        "name": "SoSo",
        "url": "http://www.SoSo.com"
    }]
}

擇使用ExcelDataReader這個庫讀Excel時,對於單元格是Json字符串的狀況,讀取獲得的Json會把這段嵌套的Json轉爲帶斜槓(轉義符)的字符串,相似下圖的狀況。json

問題來了:這種字符串已經再也不是Json格式了,用Newtonsoft.json庫沒法正確反序列化它。性能

辦法:一種解決辦法是在序列化Json時,就用一個C#類做爲參照。經過反射C#類中對應屬性的類型,來判斷這個Json單元格對應的C#類(而不是string字符串)。google

對於上面嵌套的Json,能夠用C#類來描述以下。url

public class User
{
    public string id { get; set; }
    public string name { get; set; }
    public string attribute { get; set; }
    public string ttr { get; set; }

    public UserConfig user_config { get; set; }
}

public class UserConfig
{
    public string Name { get; set; }
    public string url { get; set; }
    public int page { get; set; }
    public bool isNonProfit { get; set; }
    public Address address { get; set; }
    public Links[] links { get; set; }
}

public class Address
{
    public string street { get; set; }
    public string city { get; set; }
    public string country { get; set; }
}

public class Links
{
    public string name { get; set; }
    public string url { get; set; }
}

C#代碼在序列化Json時,就判斷每一個單元格cell中的內容的類型,把嵌套的Json強轉爲對應C#的class類型,不能讓它保持是string輸出。spa

反射C#類並作判斷的關鍵代碼相似下面這樣的:code

// 存儲一行Row數據。key是表頭屬性字段,value是單元格內容。
Dictionary<string, object> row = new Dictionary<string, object>();

Type fieldType = propertyInfo.PropertyType;
if (fieldType.IsPrimitive && fieldType.IsValueType)
{
    int value = int.Parse(cell.ToString()); // 值類型,如int等數值(約定不用枚舉)
    row[field] = value;
}
else if (fieldType == typeof(string))
{
    row[field] = cell.ToString(); // string
}
else if (fieldType.IsClass)
{
    object obj = JsonConvert.DeserializeObject(cell.ToString()); // object
    row[field] = obj;
}

這樣導出的嵌套Json就不帶斜槓了。由於它在輸出時不在是string類型,而是object了。blog

缺點是序列化Json階段就須要C#類(正常來講是反序列化時才須要的),反射C#形成的性能效率問題。ci

相關文章
相關標籤/搜索