亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將數據從 List 導出到具有不同 CSV 格式的 CSV 文件

如何將數據從 List 導出到具有不同 CSV 格式的 CSV 文件

C#
慕容708150 2022-01-15 17:17:04
我需要將報告上傳到其他不同的系統,系統有他們自己接受的報告的預定義結構。我們系統上的這些報告是根據用戶選擇的代碼生成的。用戶不關心他們想要在報告中導出的列,他們只需code要從 UI 中選擇。我們的系統將生成、下載正確格式的 CSV,并參考code并將其用作報告以上傳到另一個系統。CSV 文件的標題和列數因用戶選擇的代碼類型而異。到目前為止我是如何接近的:public ActionResult GetFileResult(string code){    var record = new Employee().GetEmployeeData(code);    var csvResult = GetCSVResult(code, record);    return csvResult;}private string GetCSVResult(string code, List<Employee> employees){    //How can i model here the GetCSVResult to convert     //the List of employees to CSV with refrence to code    //the value on the code will determine which format to used for the csv result.}在GetCSVResult方法中,我可以使用多個iforswitch-case語句來調用不同的方法,它有自己的將列表轉換為 CSV 的實現,但是至少有 20 種不同的 CSV 配置會導致多個 if 語句和很多方法。public class Employee{    public string FirstName { get; set; }    public string LastName { get; set; }    public string DOB { get; set; }    public string StartDate { get; set; }    public string SSN { get; set; }    public bool PreviousEmployee { get; set; }     public List<Employee> GetEmployeeData(string code)    {        return new List<Employee>();    }}初始數據的格式如下所示。即從返回的值GetEmployeeDataFirstName | LastName    |   SSN         |   StartDate   |   DOB         | PreviousEmployee------------------------------------------------------------------------------------------ Jane      | Smith       |   111111121   |   01/03/2018  |   01/01/1983  | trueJohn      | Smith       |   111111111   |   01/01/2018  |   01/01/1970  | trueJeff      | Smith       |   111111122   |   01/03/2018  |   01/01/1983  | false現在我必須將此數據轉換為具有不同文件配置的 CSV(或一些轉換為 XML)文件。像例子:一些格式可能是這樣的:格式一:FirstName,LastName,SSN,AppStartDate,AppDOB Jane,Smith,111111121,01/03/2018,01/01/1983 John,Smith,111111111,01/01/2018,01/01/1970 Jeff,Smith,111111122,01/03/2018,01/01/1983示例中的格式因Code. 格式的結構由代碼上的值定義。那么,對于這種場景的一些通用方法是否有任何建議?或對某種模式有什么建議?為了轉換為 CSV,我正在查看這個線程https://medium.com/@utterbbq/c-serializing-list-of-objects-to-csv-9dce02519f6b
查看完整描述

2 回答

?
慕沐林林

TA貢獻2016條經驗 獲得超9個贊

我不是 CSV 導出方面的專家,有一個您在 GetCSVResult 中嘗試過的示例會很棒。但是,我的猜測是:


以防萬一誤解了您的問題,您是否查看過這些鏈接? 將對象列表轉換為 csv 的最快方法,每個對象值都在新行中 ,并將 通用列表轉換為 CSV 字符串


現在,如果我理解得很好,用戶可以決定要導出或不導出哪一列,并在需要時更改其名稱。所以你可以有一個對象來描述這樣一個列。例如:


public class ColumnCSV

{

    public int OriginalColumnIndex{ get; set; }

    public string Name { get; set; }

    public bool ExpectedInCSV { get; set; } 

}

然后,您根據用戶輸入存儲這些列的列表,您可以輕松編寫一個可愛的開關來處理基于列索引的導出。


查看完整回答
反對 回復 2022-01-15
?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

如果你不喜歡 switch 語句并且你有一些靜態類型的鍵,你可能想要使用這樣的東西:


static readonly string _divider = ",";


static readonly Dictionary<string, (string header, Func<Employee, string[]> employee)> _configurations

            = new Dictionary<string, (string, Func<Employee, string[]>)>() {

                ["code1"] = ("FirstName,LastName,SSN,AppStartDate,AppDOB",

                        employee => new string[] {

                                    employee.FirstName,

                                    employee.LastName,

                                    employee.SSN,

                                    employee.StartDate,

                                    employee.DOB }),

                ["code2"] = ("EMP_FIRST_NAME,EMP_LAST_NAME,EMP_SSN,EMP_DOB,EMP_JOB_START_DATE,PREV_EMPLOYED_BY_EMPLOYER",

                        employee => new string[] {

                                    employee.FirstName,

                                    employee.LastName,

                                    employee.SSN,

                                    employee.DOB,

                                    employee.StartDate,

                                    employee.PreviousEmployee ? "Y" : "N" })

                    //...

                };


private string GetCSVResult( string code, List<Employee> employees )

        => _configurations[code].header

            + Environment.NewLine

            + employees.Select( e => _configurations[code]

                                     .employee( e )

                                     .Join( _divider ) )

                       .Join( Environment.NewLine );

我在這里使用這個自定義擴展:


public static class Extensions {

    public static string Join<T>( this IEnumerable<T> array, string divider = "," ) => string.Join( divider, array );

}

還要注意靜態只讀字典。您可能想改用 Concurrent 或使用某種鎖定機制來復制然后執行(不確定所有這些,tbh)。并且它可能被包裝到某種類中以獲得更清晰的視圖(用法有點干凈,當我們談論C SV 時,您可能想擺脫 _divider)。


它不是最佳的(無論是在內存上還是在 cpu 上),對于相同的結果和所有這些東西都沒有緩存(而且我很確定 string[] 結果不是連接的最佳方法,無論連接是否可以字符串;另請注意, string.Join 的通用版本并不是最優的)。這完全取決于你,我希望你能理解字典。


另一種方法是使用反射。這樣做并不是那么快和好。帶有精神分裂癥氣味的OOD殺戮魔法。是的,您可以分配屬性,然后以某種方式執行它,但無論如何它都很丑陋(每個配置都有幾個屬性或很多參數)。


還有其他幾種方法可以“編譯”這個函數,使用純 IL 或委托作為簽名 + System.Linq.Expressions(它也涉及反射,但僅在第一次使用時)。


如果你想要一些真正干凈的解決方案,你應該考慮使用注入實現和自定義腳本語言進行結構描述的抽象轉換工廠,而不是硬編碼。但為什么?此代碼將返回有點正確的 CSV。希望它會有所幫助。


查看完整回答
反對 回復 2022-01-15
  • 2 回答
  • 0 關注
  • 301 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號