【问题标题】:Generating Excel file by using LoadFromCollection from a JSON object使用来自 JSON 对象的 LoadFromCollection 生成 Excel 文件
【发布时间】:2019-10-04 09:41:05
【问题描述】:

我需要从 JSON 对象生成 excel 表。 我的 JSON 对象是未知的,并且可能因调用而异。它具有简单的结构(多行中的相同字段)。

我想使用下面的代码。

workSheet.Cells[2, 1].LoadFromCollection(dataList, false);

dataList 输入为 List(动态)

由于我的 JSON 未知,我无法为此列表定义类(参数名称和类型)

我的问题是如何将 JSON 对象动态转换为 List?

例如,我有 3 行要导出的 json 对象:

dataJson -> [{"FirstName":"Yaniv","LastName":"Test","Age": 30,"SubmitDate":"2019-10-04"},{....},{....}]   

我需要它是一个列表dataList -> Count 3

第一项:

Age 30
FirstName "Yaniv"
LastName "Test"
SubmitDate [2019-10-04]

【问题讨论】:

    标签: c# json list


    【解决方案1】:

    您可以将 JSON 反序列化为 List<Dictionary<string, object>>。例如:

    var json = "[{\"FirstName\":\"Yaniv\",\"LastName\":\"Test\",\"Age\": ......]"; 
    var data = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);
    

    现在您可以从此列表中提取一些详细信息。所以要获取列名:

    var columnNames = data.First().Keys.ToList();
    

    然后像这样循环您的数据。这基本上会以 CSV 格式输出,但应该足以根据您的需要进行修改:

    // Write out the column headers
    foreach (var columnName in columnNames)
    {
        Console.Write(columnName + ",");
    }
    Console.WriteLine();
    
    // Write out each element
    foreach (var item in data)
    {
        foreach (var columnName in columnNames)
        {
            Console.Write(item[columnName] + ",");
        }
    
        Console.WriteLine();
    }
    

    这将给出如下输出:

    FirstName,LastName,Age,SubmitDate,
    Yaniv,Test,30,2019-10-04,
    Yaniv,Test,30,2019-10-04,
    Yaniv,Test,30,2019-10-04,
    

    【讨论】:

    • 您不需要将其反序列化为对象字典列表。所有这些转换都已由 Newtonsoft.Json 自己处理。
    • @Vyacheslav 好的,这仍然是 Newtonsoft 进行反序列化,并且以比您的方法更安全的方式进行。对于代码的其他读者来说,预期的内容也非常清楚,而使用JArray 则不是。此外,您的方法要求您事先知道属性的类型,OP 明确表示不知道。我的回答错了吗?
    • 是的。这是错误的。第一个 - JArray 本身就像 List&lt;Dictionary&lt;string, object&gt;&gt; 一样(因为 JObject 继承了 IDictionary&lt;string, JToken&gt;);第二 - 访问属性名称(又名“列”)更难。您可以在我的解决方案中轻松做到这一点,您必须通过索引访问其他数组才能获取属性名称;第三 - 您无法正确解构对象中包含的对象。如果它会发生 - 您必须将对象转换回 JProperty 并遍历底层属性。在我的解决方案中 - 一切都已转换为 Newtonsoft.Json 的开发人员打算使用的类型。
    • 4th - 您可以通过访问 JProperty.Type 属性来确定字段类型,而不是像在您的解决方案中那样盲目猜测(这是 OP 的需要所要求的)。 @大卫G
    • 怎么回事?该代码有效,因此,它必须是正确的。
    【解决方案2】:

    如果您使用的是 Newtonsoft.Json,您可以将其反序列化为动态结构:

    var dyn = JArray.Parse("{jsonhere...}");
    

    然后你可以读取这样的属性:

    const string json =
    "[{\"prop\": 1, \"test\": \"test!\"}, {\"prop\": 2, \"test\": \"test again!\"}, {\"prop\": 3, \"test\": \"one more!\"}]";
    
    var parsed = JArray.Parse(json);
    
    foreach (var value in parsed)
    {
         var prop = value.Value<int>("prop");
         var test = value.Value<string>("test");
    
         Console.WriteLine($"Prop: [{prop}] | Test: [{test}]");
    }
    

    结果输出将是:

    Prop: [1] | Test: [test!]
    Prop: [2] | Test: [test again!]
    Prop: [3] | Test: [one more!]
    

    【讨论】:

      【解决方案3】:

      LoadFromCollection 的 JSON 输入生成 excel 是个坏主意。

      最简单最简单的解决方案是LoadFromDataTable,将 JSON 转换为 DataTable

      1. DataTable data = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;DataTable&gt;(dataJson);

      2. workSheet.Cells[1, 1].LoadFromDataTable(data,true);

      就这么简单?

      【讨论】:

      • 在不声明静态结构的情况下可能无法将 JSON 转换为集合。
      猜你喜欢
      • 2017-02-18
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多