策劃填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