[檔案輸出]如何正確將List輸出為Csv (使用ServiceStack)

很多人直覺認為輸出CSV檔是很簡單的事情

不就是一堆由逗號,分隔欄位 再一行一行輸出即可

但若考慮到內容值本身含有, => 剛好與Csv預設用來分隔欄位的符號一樣呢?

或者是內容值本身含有" => 原本期待字串可用" "包覆

當然這些都不難處理 只是處理這種小事很勞民傷財而已

我們可以更優雅的使用ServiceStack來處理

 

其實ServiceStack還能幫我們優雅的達到以下需求

1.  輸出的欄位名稱 (所以就可以輸出中文欄名、空白、特殊符號...等)

2. 自定Model中哪些欄位要輸出

3. 自訂輸出的時間格式

 

回到剛剛的例子

 

實際上會被編碼為

 

開始!

先到Nuget把ServiceStack安裝

 

程式碼如下

namespace MySample.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            var model = new List<MyModel>
            {
                new MyModel { STR = "A,,,,   B", INT = 1, DT = DateTime.Parse("2001/1/1"), NOTE = "程式用得到、但沒要輸出" },
                new MyModel { STR = "  '  \" ", INT = 2, DT = DateTime.Parse("2001/1/2"), NOTE = "程式用得到、但沒要輸出"  },
                new MyModel { STR = null, INT = 3, DT = DateTime.Parse("2001/1/3"), NOTE = "程式用得到、但沒要輸出"  },
                new MyModel { STR = "中文,。", INT = 4, DT = DateTime.Parse("2001/1/4"), NOTE = "程式用得到、但沒要輸出"  },
            };

            ExportObj(model, "D:/temp.csv");
        }

        public static void ExportObj<T>(IEnumerable<T> obj, string fullPath)
        {
            //如果想針對DateTime型別有自己想要的輸出格式
            JsConfig<DateTime>.SerializeFn = time => new DateTime(time.Ticks).ToString("yyyy/MM/dd HH:mm:ss");

            try
            {
                File.WriteAllText(fullPath, CsvSerializer.SerializeToCsv<T>(obj), new UTF8Encoding(true));
            }
            catch
            {

            }
        }
    }

    [DataContract] //當有DataContract時,DataMember才會生效
    class MyModel
    {
        [DataMember(Name = "新名子Str")]  //使用 DataMember 自訂最後要輸出到 CSV 中的欄位名稱
        public string STR { get; set; }

        [DataMember(Name = "空 白 也 可 以")]
        public int INT { get; set; }

        [DataMember(Name = "這個-也可以")]
        public DateTime DT { get; set; }

        public string NOTE { get; set; } //不想輸出的欄位,就不要加 DataMember 即可
    }
}