【问题标题】:Creating CSV File from string array从字符串数组创建 CSV 文件
【发布时间】:2014-03-26 08:33:49
【问题描述】:

我正在尝试将数据从对象列表导出到 csv 文件。我设法创建了文件并创建了第一行,但是我需要为每个循环创建某种类型的循环来遍历每个对象。

这是我的代码:

string pathDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = pathDesktop + "\\mycsvfile.csv";

if (!File.Exists(filePath))
{
    File.Create(filePath).Close();
}

string delimter = ",";
string[][] output = new string[][] { 
  new string[] {"TEST1","TEST2"} 
};

int length = output.GetLength(0);
StringBuilder sb = new StringBuilder();

for (int index = 0; index < length; index++)
{
    sb.AppendLine(string.Join(delimter, output[index]));
    File.AppendAllText(filePath, sb.ToString());
}

有什么方法可以创建这个文件并使用循环遍历我所有的对象并将它们显示在文件中。

【问题讨论】:

  • 您的标题具有误导性,您使用的不是 List 而是二维字符串数组。
  • 我有来自列表的数据
  • @user3430861,您的数据到底是如何构成的?你说你有一个List,但你显示的是一个二维数组。下定决心。
  • @Flater: 这是一个锯齿状数组,不是二维数组

标签: c# arrays csv export-to-csv


【解决方案1】:

解决办法如下:

string pathDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filePath = pathDesktop + "\\mycsvfile.csv";

if (!File.Exists(filePath))
{
    File.Create(filePath).Close();
}
string delimter = ",";
List<string[]> output = new List<string[]>();

//flexible part ... add as many object as you want based on your app logic
output.Add(new string[] {"TEST1","TEST2"});
output.Add(new string[] {"TEST3","TEST4"});

int length = output.Count;

using (System.IO.TextWriter writer = File.CreateText(filePath))
{
    for (int index = 0; index < length; index++)
    {
        writer.WriteLine(string.Join(delimter, output[index]));
    }
}

【讨论】:

  • 如果您希望它灵活,只需将输出变量转换为 string[] 的列表 ... 比如 List = new List() 然后添加任意数量的对象...
  • 刚刚编辑了我的答案以使用列表而不是数组
【解决方案2】:

假设 obj 是一个字符串列表,我通常使用这个

System.IO.File.WriteAllLines(stringFilePath, obj.ToArray());

【讨论】:

    【解决方案3】:

    如果您想要一个通用扩展,它将遍历列表中的每个项目,将其添加到新行并使用 getter 遍历每个公共属性,并为该行上的每个属性创建一个逗号分隔的字段列表,您可以使用我的按照my tip, heremy Gist, here 的扩展名,调用列表中的扩展名,如下所示:

    MyList.ToDelimitedText(",", true);
    

    完整代码如下

    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    
    namespace Gists.Extensions.ListOfTExtentions
    {
        public static class ListOfTExtentions
        {
            /// <summary>
            /// Converst this instance to delimited text.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="instance">The instance.</param>
            /// <param name="delimiter">The delimiter.</param>
            /// <param name="trimTrailingNewLineIfExists">
            /// If set to <c>true</c> then trim trailing new line if it exists.
            /// </param>
            /// <returns></returns>
            public static string ToDelimitedText<T>(this List<T> instance, 
                string delimiter, 
                bool trimTrailingNewLineIfExists = false)
                where T : class, new()
            {
                int itemCount = instance.Count;
                if (itemCount == 0) return string.Empty;
    
                var properties = GetPropertiesOfType<T>();
                int propertyCount = properties.Length;
                var outputBuilder = new StringBuilder();
    
                for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
                {
                    T listItem = instance[itemIndex];
                    AppendListItemToOutputBuilder(outputBuilder, listItem, properties, propertyCount, delimiter);
    
                    AddNewLineIfRequired(trimTrailingNewLineIfExists, itemIndex, itemCount, outputBuilder);
                }
    
                var output = TrimTrailingNewLineIfExistsAndRequired(outputBuilder.ToString(), trimTrailingNewLineIfExists);
                return output;
            }
    
            private static void AddDelimiterIfRequired(StringBuilder outputBuilder, int propertyCount, string delimiter,
                int propertyIndex)
            {
                bool isLastProperty = (propertyIndex + 1 == propertyCount);
                if (!isLastProperty)
                {
                    outputBuilder.Append(delimiter);
                }
            }
    
            private static void AddNewLineIfRequired(bool trimTrailingNewLineIfExists, int itemIndex, int itemCount,
                StringBuilder outputBuilder)
            {
                bool isLastItem = (itemIndex + 1 == itemCount);
                if (!isLastItem || !trimTrailingNewLineIfExists)
                {
                    outputBuilder.Append(Environment.NewLine);
                }
            }
    
            private static void AppendListItemToOutputBuilder<T>(StringBuilder outputBuilder, 
                T listItem, 
                PropertyInfo[] properties,
                int propertyCount,
                string delimiter)
                where T : class, new()
            {
    
                for (int propertyIndex = 0; propertyIndex < properties.Length; propertyIndex += 1)
                {
                    var property = properties[propertyIndex];
                    var propertyValue = property.GetValue(listItem);
                    outputBuilder.Append(propertyValue);
    
                    AddDelimiterIfRequired(outputBuilder, propertyCount, delimiter, propertyIndex);
                }
            }
    
            private static PropertyInfo[] GetPropertiesOfType<T>() where T : class, new()
            {
                Type itemType = typeof (T);
                var properties = itemType.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public);
                return properties;
            }
    
            private static string TrimTrailingNewLineIfExistsAndRequired(string output, bool trimTrailingNewLineIfExists)
            {
                if (!trimTrailingNewLineIfExists || !output.EndsWith(Environment.NewLine)) return output;
    
                int outputLength = output.Length;
                int newLineLength = Environment.NewLine.Length;
                int startIndex = outputLength - newLineLength;
                output = output.Substring(startIndex, newLineLength);
                return output;
            }
        }
    }
    

    在这些测试中可以找到调用代码的示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Gists.Extensions.ListOfTExtentions;
    
    namespace Gists_Tests.ExtensionTests.ListOfTExtentionTests
    {
        [TestClass]
        public class ListOfT_ToDelimitedTextTests
        {
            #region Mock Data
    
            private class SimpleObject
            {
                public int Id { get; set; }
            }
    
            private class ComplextObject : SimpleObject
            {
                public string Name { get; set; }
                public bool Active { get; set; }
            }
    
            #endregion
    
            #region Tests
    
            [TestMethod]
            public void ToDelimitedText_ReturnsCorrectNumberOfRows()
            {
                // ARRANGE
                var itemList = new List<ComplextObject>
                {
                    new ComplextObject {Id = 1, Name = "Sid", Active = true},
                    new ComplextObject {Id = 2, Name = "James", Active = false},
                    new ComplextObject {Id = 3, Name = "Ted", Active = true},
                };
                const string delimiter = ",";
                const int expectedRowCount = 3;
                const bool trimTrailingNewLineIfExists = true;
    
                // ACT
                string result = itemList.ToDelimitedText(delimiter, trimTrailingNewLineIfExists);
                var lines = result.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                var actualRowCount = lines.Length;
    
                // ASSERT
                Assert.AreEqual(expectedRowCount, actualRowCount);
            }
    
            [TestMethod]
            public void ToDelimitedText_ReturnsCorrectNumberOfProperties()
            {
                // ARRANGE
                var itemList = new List<ComplextObject>
                {
                    new ComplextObject {Id = 1, Name = "Sid", Active = true}
                };
                const string delimiter = ",";
                const int expectedPropertyCount = 3;
    
                // ACT
                string result = itemList.ToDelimitedText(delimiter);
                var lines = result.Split(Environment.NewLine.ToCharArray());
                var properties = lines.First().Split(delimiter.ToCharArray());
                var actualPropertyCount = properties.Length;
    
                // ASSERT
                Assert.AreEqual(expectedPropertyCount, actualPropertyCount);
            }
    
            [TestMethod]
            public void ToDelimitedText_RemovesTrailingNewLine_WhenSet()
            {
                // ARRANGE
                var itemList = new List<ComplextObject>
                {
                    new ComplextObject {Id = 1, Name = "Sid", Active = true},
                    new ComplextObject {Id = 2, Name = "James", Active = false},
                    new ComplextObject {Id = 3, Name = "Ted", Active = true},
                };
                const string delimiter = ",";
                const bool trimTrailingNewLineIfExists = true;
    
                // ACT
                string result = itemList.ToDelimitedText(delimiter, trimTrailingNewLineIfExists);
                bool endsWithNewLine = result.EndsWith(Environment.NewLine);
    
                // ASSERT
                Assert.IsFalse(endsWithNewLine);
            }
    
            [TestMethod]
            public void ToDelimitedText_IncludesTrailingNewLine_WhenNotSet()
            {
                // ARRANGE
                var itemList = new List<ComplextObject>
                {
                    new ComplextObject {Id = 1, Name = "Sid", Active = true},
                    new ComplextObject {Id = 2, Name = "James", Active = false},
                    new ComplextObject {Id = 3, Name = "Ted", Active = true},
                };
                const string delimiter = ",";
                const bool trimTrailingNewLineIfExists = false;
    
                // ACT
                string result = itemList.ToDelimitedText(delimiter, trimTrailingNewLineIfExists);
                bool endsWithNewLine = result.EndsWith(Environment.NewLine);
    
                // ASSERT
                Assert.IsTrue(endsWithNewLine);
            }
    
            #endregion
        }
    }
    

    【讨论】:

      【解决方案4】:

      将每个字符串数组集合传递给此函数,这将返回一个 CSV 格式的字符串,您可以将其保存到大字符串缓冲区或逐行写入文件。

      C#

      public string CSVout(string[] strArray)
      {
          string sOut = "";
      
          foreach (void s_loopVariable in strArray) {
              s = s_loopVariable;
              if (s.Contains(","))
                  s = Strings.Chr(34) + s + Strings.Chr(34);
              sOut += s + ",";
          }
      
          if (Strings.Right(sOut, 1) == ",")
              sOut = Strings.Left(@out, @out.Length - 1);
      
          return sOut;
      }
      

      VB.NET:

        Function CSVout(strArray() As String) As String
          Dim out As String = ""
      
          For Each s In strArray
              If s.Contains(",") Then s = Chr(34) + s + Chr(34)
              out &= s + ","
          Next
      
          If Strings.Right(out, 1) = "," Then out = Strings.Left(out, out.Length - 1)
      
          Return out
      End Function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-19
        • 2019-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-02
        • 2016-12-02
        相关资源
        最近更新 更多