zoukankan      html  css  js  c++  java
  • 【C#】读取Excel中嵌套的Json对象,Json带斜杠的问题(其一)

    策划填Excel表时,约定对于复杂类型的数据采用Json的格式填写。如下图,D列的内容是Json数据。

    单元格中的Json如下。

    {
        "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格式了,用Newtonsoft.json库无法正确反序列化它。

    办法:一种解决办法是在序列化Json时,就用一个C#类作为参照。通过反射C#类中对应属性的类型,来判断这个Json单元格对应的C#类(而不是string字符串)。

    对于上面嵌套的Json,可以用C#类来描述如下。

    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输出。

    反射C#类并做判断的关键代码类似下面这样的:

    // 存储一行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了。

    缺点是序列化Json阶段就需要C#类(正常来说是反序列化时才需要的),反射C#造成的性能效率问题。

  • 相关阅读:
    Android作业10/21
    Android作业10/07
    Android作业0930
    Android作业 0923
    第四周作业
    第七周
    第六周
    第四周作业
    3.10第二次
    jsp第一次作业
  • 原文地址:https://www.cnblogs.com/guxin/p/9600139.html
Copyright © 2011-2022 走看看