如何将JSON字符串导出为CSV文件?

时间:2016-11-21 13:29:11

标签: c# asp.net json csv

我有ASP.Net网站。我有JSON字符串需要导出到物理CSV文件。

 private String JsonToCsv(string jsonData, string delimiter)
    {
        try
        {
            StringWriter swObj = new StringWriter();
            using (var csv = new CsvWriter(swObj))
            {
                csv.Configuration.SkipEmptyRecords = true;
                csv.Configuration.WillThrowOnMissingField = false;
                csv.Configuration.Delimiter = delimiter;

                using (var dt = jsonStringToTable(jsonData))
                {
                    foreach (DataColumn col in dt.Columns)
                    {
                        csv.WriteField(col.ColumnName);
                    }
                    csv.NextRecord();

                    foreach(DataRow row in dt.Rows)
                    {
                        for (var i = 0; i < dt.Columns.Count; i++)
                        {
                            csv.WriteField(row[i]);
                        }
                        csv.NextRecord();
                    }
                }

            }
             return swObj.ToString();

        }
        catch (Exception ex)
        {
            //handle exception 
            return null;
        }
    }

    private  DataTable jsonStringToTable(string jsonContent)
    {
        DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
        return dt;
    }

    public HttpResponseMessage ExportToCSV(string jsonData)
    {
        string csv = JsonToCsv(jsonData, ",");

        HttpResponseMessage res = new HttpResponseMessage(HttpStatusCode.OK);
        res.Content = new StringContent(csv);
        res.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
        res.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "export.csv" };
        return res;
    }

但我既没有得到任何例外,也没有CSV文件获取任何数据。

Export.csv位于根文件夹中。

如何导出JSON&amp;自动下载文件??

2 个答案:

答案 0 :(得分:3)

看来你确实有一个错误,就是你在捕获中压制。

您的第一个错误是您的jsonContent实际上不是json。您的示例中有一个变量赋值jsonContent = [...][...]部分是你真正的json。

要处理这个问题,你只需要更好地编写它,不要将它分配给变量(推荐的方法),或者使用jsonContent.Split(new [] {'='}).Last()来处理实例。 (声明性与命令式方法/策略)。

此外,您正在尝试反序列化为不正确的类型,因为它不反映您的json数据结构。

虽然还有其他方式可以将一个字符串转换为另一个字符串。我同意在这里做正确的事情是反序列化你的对象(或者不事先序列化 - 推荐)。

我正在提供示例控制台应用程序,供您查看处理JsonToCsv操作的两个实现。

  • dynamic(势在必行)
  • 并在该类型上提供Type并使用System.Reflection。 (以Json.Convert.DeserializeObject<T>()方法声明,后续命令)

在此实现中依赖于NewtonSoft.Json程序集(通过NuGet程序包安装它);它反映了您提供的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Reflection;
using Newtonsoft;


namespace JsonToCsvTests
{
    using Newtonsoft.Json;
    using System.IO;
    using System.Threading.Tasks;

    class Program
    {

        static void Main(string[] args)
        {
            TestJsonToCsv();
            Console.ReadLine();
        }

        static void TestJsonToCsv()
        {
            string jsonData = @"jsonData = [
                        {
                            ""DocumentName"": ""Test Document"",
                            ""ActionDate"": ""2015-09-25T16:06:25.083"",
                            ""ActionType"": ""View"",
                            ""ActionPerformedBy"": ""Sreeja SJ""
                        },
                        {
                            ""DocumentName"": ""Test Document"",
                            ""ActionDate"": ""2015-09-25T16:12:02.497"",
                            ""ActionType"": ""View"",
                            ""ActionPerformedBy"": ""Sreeja SJ""
                        },
                        {
                            ""DocumentName"": ""Test Document"",
                            ""ActionDate"": ""2015-09-25T16:13:48.013"",
                            ""ActionType"": ""View"",
                            ""ActionPerformedBy"": ""Sreeja SJ""
                        }]";

            Console.WriteLine("...using System.Dynamic and casts");
            Console.WriteLine();
            Console.WriteLine(JsonToCsv(jsonData, ","));
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("...using a provided StrongType with System.Reflection.");
            Console.WriteLine();
            Console.WriteLine(JsonToCsv<JsonData>(jsonData, ","));
        }

        static private string JsonToCsv(string jsonContent, string delimiter)
        {
            var data = jsonStringToTable(jsonContent);
            var headers = ((IEnumerable<dynamic>)((IEnumerable<dynamic>)data).First()).Select((prop) => prop.Name).ToArray();
            var csvList = new List<string> 
            {
                string.Join(delimiter, headers.Select((prop) => string.Format(@"""{0}""", prop)).ToArray())
            };

            var lines = ((IEnumerable<dynamic>)data)
                .Select(row => row)
                .Cast<IEnumerable<dynamic>>()
                .Select((instance) => string.Join(delimiter, instance.Select((v) => string.Format(@"""{0}""", v.Value))))
                .ToArray();

            csvList.AddRange(lines);
            return string.Join(Environment.NewLine, csvList );
        }

        static private string JsonToCsv<T>(string jsonContent, string delimiter) where T : class
        {
            var data = jsonStringToTable<T>(jsonContent);

            var properties = data.First().GetType().GetProperties();

            var lines = string.Join(Environment.NewLine,
                string.Join(delimiter, properties.Select((propInfo) => string.Format(@"""{0}""", propInfo.Name))),
                string.Join(Environment.NewLine, data.Select((row) => string.Join(delimiter, properties.Select((propInfo) => string.Format(@"""{0}""", propInfo.GetValue(row)))))));

            return lines;
        }

        static private dynamic jsonStringToTable(string jsonContent)
        {
            var json = jsonContent.Split(new[] { '=' }).Last();
            return JsonConvert.DeserializeObject<dynamic>(json);
        }

        static private IEnumerable<T> jsonStringToTable<T>(string jsonContent) where T : class
        {
            var json = jsonContent.Split(new[] { '=' }).Last();
            return JsonConvert.DeserializeObject<IEnumerable<T>>(json);
        }

        public class JsonData
        {
            public string DocumentName { get; set; }
            public DateTime ActionDate { get; set; }
            public string ActionType { get; set; }
            public string ActionPerformedBy { get; set; }
        }
    }
}

Console.Output

...using System.Dynamic and casts

"DocumentName","ActionDate","ActionType","ActionPerformedBy"
"Test Document","9/25/2015 4:06:25 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:12:02 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:13:48 PM","View","Sreeja SJ"


...using a provided StrongType with System.Reflection.

"DocumentName","ActionDate","ActionType","ActionPerformedBy"
"Test Document","9/25/2015 4:06:25 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:12:02 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:13:48 PM","View","Sreeja SJ"

答案 1 :(得分:0)

这是我用来在我的ASP.NET网站上生成CSV文件

    public static class CSVUtils
{
    public static void AddCsvLine(bool isFrenchSeparator, StringBuilder csv, params object[] values)
    {
        foreach (var value in values)
        {
            csv.Append('"').Append(value).Append('"');
            if (isFrenchSeparator)
            {
                csv.Append(';');
            }
            else
            {
                csv.Append(',');
            }
        }
        csv.Append('\r'); // AppendLine() adds a double line break with UTF32Encoding
    }
}

    public FileContentResult ExportCSV()
    {
        StringBuilder csv = new StringBuilder();
        CSVUtils.AddCsvLine(false, csv, "Field1", "Field2", "Field3");
        CSVUtils.AddCsvLine(false, csv, "value1", "value2", "value3");

        return this.File(new UTF32Encoding().GetBytes(csv.ToString()), "text/csv", "myfile.csv");
    }

我基本上从我的网站调用ExportCSV操作,例如按下按钮,然后下载文件。确保事先从所有昏迷中清除你的JSON,否则会弄乱你的CSV文件。

编辑:特别是对于JSON,你也必须反斜杠每一个“否则会弄乱StringBuilder我猜