c # datatable เป็น csv


113

ใครช่วยบอกฉันหน่อยได้ไหมว่าทำไมโค้ดต่อไปนี้ไม่ทำงาน ข้อมูลจะถูกบันทึกลงในไฟล์ csv อย่างไรก็ตามข้อมูลจะไม่แยกออกจากกัน ทั้งหมดนี้มีอยู่ในเซลล์แรกของแต่ละแถว

StringBuilder sb = new StringBuilder();

foreach (DataColumn col in dt.Columns)
{
    sb.Append(col.ColumnName + ',');
}

sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);

foreach (DataRow row in dt.Rows)
{
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        sb.Append(row[i].ToString() + ",");
    }

    sb.Append(Environment.NewLine);
}

File.WriteAllText("test.csv", sb.ToString());

ขอบคุณ


คุณสามารถตรวจสอบgist.github.com/riyadparvez/4467668
ผู้ใช้

ฉันพัฒนา Extention ประสิทธิภาพสูง ตรวจสอบคำตอบนี้
Nigje

คำตอบ:


229

เวอร์ชันที่สั้นกว่าต่อไปนี้เปิดได้ดีใน Excel ปัญหาของคุณอาจเกิดจากเครื่องหมายจุลภาคต่อท้าย

.net = 3.5

StringBuilder sb = new StringBuilder(); 

string[] columnNames = dt.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName).
                                  ToArray();
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt.Rows)
{
    string[] fields = row.ItemArray.Select(field => field.ToString()).
                                    ToArray();
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText("test.csv", sb.ToString());

.net> = 4.0

และตามที่ Tim ชี้ให้เห็นหากคุณอยู่บน. net> = 4 คุณสามารถทำให้สั้นลงได้:

StringBuilder sb = new StringBuilder(); 

IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText("test.csv", sb.ToString());

ตามที่ Christian แนะนำหากคุณต้องการจัดการอักขระพิเศษที่หลบหนีในฟิลด์ให้แทนที่บล็อกลูปโดย:

foreach (DataRow row in dt.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => 
      string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));
    sb.AppendLine(string.Join(",", fields));
}

และข้อเสนอแนะสุดท้ายคุณสามารถเขียนเนื้อหา csv ทีละบรรทัดแทนที่จะเป็นเอกสารทั้งหมดเพื่อหลีกเลี่ยงการมีเอกสารขนาดใหญ่ในหน่วยความจำ


2
ไม่จำเป็นต้องคัดลอกItemArrayไปที่ใหม่String[]คุณสามารถละเว้น.ToArray()ด้วย. NET 4 และใช้การString.Joinโอเวอร์โหลดที่ใช้IEnumerable<T>(แก้ไข)
Tim Schmelter

2
@TimSchmelter ใช่ แต่โอเวอร์โหลดเหล่านี้ถูกนำมาใช้ใน. net4 โค้ดจะไม่คอมไพล์หาก OP ใช้. net <4
vc 74

18
วิธีนี้ไม่คำนึงถึงเครื่องหมายจุลภาคภายในค่าคอลัมน์
Christian

2
แทน IEnumerable <string> fields = row.IemArray.Select (field => field ToString (). Replace ("\" "," \ "\" ")); sb.AppendLine (" \ "" + string.Join ("\", \ "", fields) + "\" ");
Christian

2
@ Si8 หมายความว่าไง? คำตอบนี้ใช้คอมโพเนนต์ db เท่านั้นและ&nbspเป็นเรื่องปกติของเอกสาร HTML / XML ไม่ใช่รหัสด้านบนที่สร้างขึ้นเว้นแต่ว่าตารางจะมี&nbsp;อย่างชัดเจน
vc 74

37

ฉันรวมสิ่งนี้ไว้ในคลาสส่วนขยายซึ่งช่วยให้คุณสามารถโทร:

myDataTable.WriteToCsvFile("C:\\MyDataTable.csv");

บน DataTable ใด ๆ

public static class DataTableExtensions 
{
    public static void WriteToCsvFile(this DataTable dataTable, string filePath) 
    {
        StringBuilder fileContent = new StringBuilder();

        foreach (var col in dataTable.Columns) 
        {
            fileContent.Append(col.ToString() + ",");
        }

        fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);

        foreach (DataRow dr in dataTable.Rows) 
        {
            foreach (var column in dr.ItemArray) 
            {
                fileContent.Append("\"" + column.ToString() + "\",");
            }

            fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
        }

        System.IO.File.WriteAllText(filePath, fileContent.ToString());
    }
}

25

ฟังก์ชั่นส่วนขยายใหม่ตามคำตอบของ Paul Grimshaw ฉันทำความสะอาดและเพิ่มความสามารถในการจัดการข้อมูลที่ไม่คาดคิด (ข้อมูลว่างเปล่าอัญประกาศแบบฝังและลูกน้ำในหัวเรื่อง ... )

นอกจากนี้ยังส่งคืนสตริงที่มีความยืดหยุ่นมากขึ้น จะส่งคืนค่า Null หากวัตถุตารางไม่มีโครงสร้างใด ๆ

    public static string ToCsv(this DataTable dataTable) {
        StringBuilder sbData = new StringBuilder();

        // Only return Null if there is no structure.
        if (dataTable.Columns.Count == 0)
            return null;

        foreach (var col in dataTable.Columns) {
            if (col == null)
                sbData.Append(",");
            else
                sbData.Append("\"" + col.ToString().Replace("\"", "\"\"") + "\",");
        }

        sbData.Replace(",", System.Environment.NewLine, sbData.Length - 1, 1);

        foreach (DataRow dr in dataTable.Rows) {
            foreach (var column in dr.ItemArray) {
                if (column == null)
                    sbData.Append(",");
                else
                    sbData.Append("\"" + column.ToString().Replace("\"", "\"\"") + "\",");
            }
            sbData.Replace(",", System.Environment.NewLine, sbData.Length - 1, 1);
        }

        return sbData.ToString();
    }

คุณเรียกมันว่า:

var csvData = dataTableOject.ToCsv();

1
อันนี้ดีที่สุดจากที่เหลือที่นี่ ทำได้ดี. ขอบคุณ
Fandango68

ทางออกที่ยอดเยี่ยม เพิ่มความคิดเห็นในเครื่อง แต่สามารถใช้งานนอกกรอบได้โดยไม่ต้องปีนภูเขา ขอบคุณ.
ก.ค.

ชอบสิ่งนี้! ฉันใช้มันเป็นวิธีที่ไม่คงที่และเพิ่งส่ง DataTable ของฉันเป็นพารามิเตอร์ ทำงานได้ดีขอบคุณ
Kid Koder

9

หากรหัสการโทรของคุณอ้างถึงSystem.Windows.Formsแอสเซมบลีคุณอาจพิจารณาแนวทางที่แตกต่างไปจากเดิมอย่างสิ้นเชิง กลยุทธ์ของฉันคือการใช้ฟังก์ชั่นที่เฟรมเวิร์กจัดเตรียมไว้ให้เพื่อทำสิ่งนี้ให้สำเร็จโดยใช้โค้ดไม่กี่บรรทัดและไม่ต้องวนซ้ำคอลัมน์และแถว สิ่งที่โค้ดด้านล่างทำคือสร้างโปรแกรมได้DataGridViewทันทีและตั้งค่าเป็นDataGridView.DataSourceไฟล์DataTable. ต่อไปผมจะเขียนโปรแกรมเลือกเซลล์ทั้งหมด (รวมทั้งส่วนหัว) ในDataGridViewและโทรวางผลลงในวินโดวส์DataGridView.GetClipboardContent() Clipboardแล้วฉัน 'วาง' เนื้อหาของคลิปบอร์ดลงในการเรียกร้องให้File.WriteAllText()ตรวจสอบให้แน่ใจเพื่อระบุการจัดรูปแบบของ 'วาง' TextDataFormat.CommaSeparatedValueเป็น

นี่คือรหัส:

public static void DataTableToCSV(DataTable Table, string Filename)
{
    using(DataGridView dataGrid = new DataGridView())
    {
        // Save the current state of the clipboard so we can restore it after we are done
        IDataObject objectSave = Clipboard.GetDataObject();

        // Set the DataSource
        dataGrid.DataSource = Table;
        // Choose whether to write header. Use EnableWithoutHeaderText instead to omit header.
        dataGrid.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
        // Select all the cells
        dataGrid.SelectAll();
        // Copy (set clipboard)
        Clipboard.SetDataObject(dataGrid.GetClipboardContent());
        // Paste (get the clipboard and serialize it to a file)
        File.WriteAllText(Filename,Clipboard.GetText(TextDataFormat.CommaSeparatedValue));              

        // Restore the current state of the clipboard so the effect is seamless
        if(objectSave != null) // If we try to set the Clipboard to an object that is null, it will throw...
        {
            Clipboard.SetDataObject(objectSave);
        }
    }
}

โปรดสังเกตด้วยว่าฉันต้องเก็บรักษาเนื้อหาของคลิปบอร์ดไว้ก่อนที่จะเริ่มและกู้คืนเมื่อทำเสร็จแล้วดังนั้นผู้ใช้จะไม่ได้รับขยะที่ไม่คาดคิดมากมายในครั้งต่อไปที่ผู้ใช้พยายามวาง คำเตือนหลักของแนวทางนี้คือ 1) คลาสของคุณต้องอ้างอิงSystem.Windows.Formsซึ่งอาจไม่ใช่กรณีในเลเยอร์นามธรรมข้อมูล 2) แอสเซมบลีของคุณจะต้องกำหนดเป้าหมายสำหรับเฟรมเวิร์ก. NET 4.5 เนื่องจาก DataGridView ไม่มีใน 4.0 และ 3) วิธีนี้จะล้มเหลวหากกระบวนการอื่นใช้คลิปบอร์ด

อย่างไรก็ตามแนวทางนี้อาจไม่เหมาะกับสถานการณ์ของคุณ แต่ก็น่าสนใจไม่น้อยและอาจเป็นเครื่องมืออื่นในกล่องเครื่องมือของคุณ


1
ไม่จำเป็นต้องใช้คลิปบอร์ดstackoverflow.com/questions/40726017/… . นอกจากนี้ยังจัดการกรณีขอบไม่กี่ของค่าที่ประกอบด้วย.GetClipboardContent , (มันแปลงแท็บเป็นช่องว่าง),"\t
Slai

2
นี่เป็นสิ่งที่ดี แต่จะเกิดอะไรขึ้นถ้ามีคนใช้เครื่องในเวลาเดียวกันและใส่บางอย่างลงในคลิปบอร์ดในช่วงเวลาสำคัญ
Ayo Adesina

7

ฉันเพิ่งทำสิ่งนี้เมื่อไม่นานมานี้ แต่มีเครื่องหมายคำพูดคู่รอบค่าของฉัน

ตัวอย่างเช่นเปลี่ยนสองบรรทัดนี้:

sb.Append("\"" + col.ColumnName + "\","); 
...
sb.Append("\"" + row[i].ToString() + "\","); 

ขอบคุณสำหรับคำแนะนำ แต่ข้อมูลทั้งหมดยังอยู่ในเซลล์แรกของแต่ละแถว?
Darren Young

7

ลองเปลี่ยนsb.Append(Environment.NewLine);เป็นsb.AppendLine();.

StringBuilder sb = new StringBuilder();          
foreach (DataColumn col in dt.Columns)         
{             
    sb.Append(col.ColumnName + ',');         
}          

sb.Remove(sb.Length - 1, 1);         
sb.AppendLine();          

foreach (DataRow row in dt.Rows)         
{             
    for (int i = 0; i < dt.Columns.Count; i++)             
    {                 
        sb.Append(row[i].ToString() + ",");             
    }              

    sb.AppendLine();         
}          

File.WriteAllText("test.csv", sb.ToString());

จากนั้นจะให้ผลตอบแทนสอง carraige
Darren Young

@alexl: นั่นคือสิ่งที่ตอนแรกฉันจะไปด้วย แต่มันอยู่ด้านบนของหัวของฉันจนกระทั่ง VS ยิงขึ้น: o)
นีลไนท์


5

อ่านสิ่งนี้และสิ่งนี้ ?


การใช้งานที่ดีขึ้นจะเป็น

var result = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
    result.Append(table.Columns[i].ColumnName);
    result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
}

foreach (DataRow row in table.Rows)
{
    for (int i = 0; i < table.Columns.Count; i++)
    {
        result.Append(row[i].ToString());
        result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
    }
}
 File.WriteAllText("test.csv", result.ToString());

5

ข้อผิดพลาดคือตัวคั่นรายการ

แทนที่จะเขียนsb.Append(something... + ',')คุณควรใส่สิ่งที่ต้องการsb.Append(something... + System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator);

คุณต้องใส่อักขระตัวคั่นรายการที่กำหนดค่าไว้ในระบบปฏิบัติการของคุณ (เช่นในตัวอย่างด้านบน) หรือตัวคั่นรายการในเครื่องไคลเอนต์ที่จะดูไฟล์ อีกทางเลือกหนึ่งคือกำหนดค่าใน app.config หรือ web.config เป็นพารามิเตอร์ของแอปพลิเคชันของคุณ


5

รหัส 4 บรรทัด:

public static string ToCSV(DataTable tbl)
{
    StringBuilder strb = new StringBuilder();

    //column headers
    strb.AppendLine(string.Join(",", tbl.Columns.Cast<DataColumn>()
        .Select(s => "\"" + s.ColumnName + "\"")));

    //rows
    tbl.AsEnumerable().Select(s => strb.AppendLine(
        string.Join(",", s.ItemArray.Select(
            i => "\"" + i.ToString() + "\"")))).ToList();

    return strb.ToString();
}

โปรดทราบว่าToList()ตอนท้ายมีความสำคัญ ฉันต้องการบางสิ่งเพื่อบังคับให้มีการประเมินนิพจน์ ถ้าฉันตีกอล์ฟฉันสามารถใช้Min()แทนได้

AppendLine()นอกจากนี้ยังทราบว่าผลที่จะมีขึ้นบรรทัดใหม่ในตอนท้ายเพราะสายสุดท้ายที่จะ คุณอาจไม่ต้องการสิ่งนี้ คุณสามารถเรียกTrimEnd()เพื่อลบออก


3

นี่คือการปรับปรุงโพสต์ของ vc-74 ที่จัดการลูกน้ำแบบเดียวกับที่ Excel ทำ Excel ใส่เครื่องหมายคำพูดไว้รอบ ๆ ข้อมูลหากข้อมูลมีเครื่องหมายจุลภาค แต่ไม่ได้ใส่เครื่องหมายจุลภาคหากข้อมูลไม่มีเครื่องหมายจุลภาค

    public static string ToCsv(this DataTable inDataTable, bool inIncludeHeaders = true)
    {
        var builder = new StringBuilder();
        var columnNames = inDataTable.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
        if (inIncludeHeaders)
            builder.AppendLine(string.Join(",", columnNames));
        foreach (DataRow row in inDataTable.Rows)
        {
            var fields = row.ItemArray.Select(field => field.ToString().WrapInQuotesIfContains(","));
            builder.AppendLine(string.Join(",", fields));
        }

        return builder.ToString();
    }

    public static string WrapInQuotesIfContains(this string inString, string inSearchString)
    {
        if (inString.Contains(inSearchString))
            return "\"" + inString+ "\"";
        return inString;
    }

2

ในการเขียนลงไฟล์ฉันคิดว่าวิธีต่อไปนี้มีประสิทธิภาพและตรงไปตรงมาที่สุด: (คุณสามารถเพิ่มคำพูดได้หากต้องการ)

public static void WriteCsv(DataTable dt, string path)
{
    using (var writer = new StreamWriter(path)) {
        writer.WriteLine(string.Join(",", dt.Columns.Cast<DataColumn>().Select(dc => dc.ColumnName)));
        foreach (DataRow row in dt.Rows) {
            writer.WriteLine(string.Join(",", row.ItemArray));
        }
    }
}

2

ในการเลียนแบบ Excel CSV:

public static string Convert(DataTable dt)
{
    StringBuilder sb = new StringBuilder();

    IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                        Select(column => column.ColumnName);
    sb.AppendLine(string.Join(",", columnNames));

    foreach (DataRow row in dt.Rows)
    {
        IEnumerable<string> fields = row.ItemArray.Select(field =>
        {
            string s = field.ToString().Replace("\"", "\"\"");
            if(s.Contains(','))
                s = string.Concat("\"", s, "\"");
            return s;
        });
        sb.AppendLine(string.Join(",", fields));
    }

    return sb.ToString().Trim();
}

1
StringBuilder sb = new StringBuilder();
        SaveFileDialog fileSave = new SaveFileDialog();
        IEnumerable<string> columnNames = tbCifSil.Columns.Cast<DataColumn>().
                                          Select(column => column.ColumnName);
        sb.AppendLine(string.Join(",", columnNames));

        foreach (DataRow row in tbCifSil.Rows)
        {
            IEnumerable<string> fields = row.ItemArray.Select(field =>string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));
            sb.AppendLine(string.Join(",", fields));
        }

        fileSave.ShowDialog();
        File.WriteAllText(fileSave.FileName, sb.ToString());

ยินดีต้อนรับสู่ StackOverflow! คำตอบจะดีที่สุดเมื่อมีคำอธิบายของข้อมูลโค้ด ฉันพบเป็นการส่วนตัวว่าเมื่อชื่อตัวแปรเรียงกันระหว่างคำถามและคำตอบพวกเขาจะเป็นประโยชน์กับฉันมากขึ้น
AWinkle

1
public void ExpoetToCSV(DataTable dtDataTable, string strFilePath)
{

    StreamWriter sw = new StreamWriter(strFilePath, false);
    //headers   
    for (int i = 0; i < dtDataTable.Columns.Count; i++)
    {
        sw.Write(dtDataTable.Columns[i].ToString().Trim());
        if (i < dtDataTable.Columns.Count - 1)
        {
            sw.Write(",");
        }
    }
    sw.Write(sw.NewLine);
    foreach (DataRow dr in dtDataTable.Rows)
    {
        for (int i = 0; i < dtDataTable.Columns.Count; i++)
        {
            if (!Convert.IsDBNull(dr[i]))
            {
                string value = dr[i].ToString().Trim();
                if (value.Contains(','))
                {
                    value = String.Format("\"{0}\"", value);
                    sw.Write(value);
                }
                else
                {
                    sw.Write(dr[i].ToString().Trim());
                }
            }
            if (i < dtDataTable.Columns.Count - 1)
            {
                sw.Write(",");
            }
        }
        sw.Write(sw.NewLine);
    }
    sw.Close();
}

1

อาจเป็นไปได้ว่าวิธีที่ง่ายที่สุดคือการใช้:

https://github.com/ukushu/DataExporter

โดยเฉพาะอย่างยิ่งในกรณีที่ข้อมูลของคุณเป็นข้อมูลที่มี/r/nอักขระหรือสัญลักษณ์ตัวคั่นภายในเซลล์ dataTable ของคุณ คำตอบอื่น ๆ เกือบทั้งหมดจะใช้ไม่ได้กับเซลล์ดังกล่าว

คุณต้องเขียนโค้ดต่อไปนี้:

Csv csv = new Csv("\t");//Needed delimiter 

var columnNames = dt.Columns.Cast<DataColumn>().
    Select(column => column.ColumnName).ToArray();

csv.AddRow(columnNames);

foreach (DataRow row in dt.Rows)
{
    var fields = row.ItemArray.Select(field => field.ToString()).ToArray;
    csv.AddRow(fields);   
}

csv.Save();

0

ในกรณีที่คนอื่นสะดุดกับเรื่องนี้ผมก็ใช้File.ReadAllTextเพื่อให้ได้ข้อมูล CSV และแล้วผมปรับเปลี่ยนมันและเขียนมันกลับมาพร้อมกับFile.WriteAllText CRLF ของ \ r \ n นั้นใช้ได้ดี แต่แท็บจะถูกละเว้นเมื่อ Excel เปิดขึ้น (วิธีแก้ปัญหาทั้งหมดในเธรดนี้ใช้ตัวคั่นลูกน้ำ แต่ก็ไม่สำคัญ) Notepad แสดงรูปแบบเดียวกันในไฟล์ผลลัพธ์เช่นเดียวกับแหล่งที่มา ความแตกต่างยังแสดงให้เห็นว่าไฟล์เหมือนกัน แต่ฉันได้เบาะแสเมื่อเปิดไฟล์ใน Visual Studio ด้วยตัวแก้ไขไบนารี แฟ้มแหล่งที่มาที่เป็น Unicode แต่เป้าหมายเป็นASCII ในการแก้ไขฉันได้แก้ไขทั้ง ReadAllText และ WriteAllText ด้วยอาร์กิวเมนต์ที่สามที่ตั้งค่าเป็นSystem.Text.Encoding.Unicodeและจากนั้น Excel ก็สามารถเปิดไฟล์ที่อัปเดตได้


0

FYR

private string ExportDatatableToCSV(DataTable dtTable)
{
    StringBuilder sbldr = new StringBuilder();
    if (dtTable.Columns.Count != 0)
    {
        foreach (DataColumn col in dtTable.Columns)
        {
            sbldr.Append(col.ColumnName + ',');
        }
        sbldr.Append("\r\n");
        foreach (DataRow row in dtTable.Rows)
        {
            foreach (DataColumn column in dtTable.Columns)
            {
                sbldr.Append(row[column].ToString() + ',');
            }
            sbldr.Append("\r\n");
        }
    }
    return sbldr.ToString();
}

0

นี่คือวิธีการแก้ปัญหาของผมขึ้นอยู่กับคำตอบก่อนโดยพอลกริมชอว์และแอนโธนี VO ฉันได้ส่งรหัสในโครงการ C # บน Githubแล้ว

ผลงานหลักของฉันคือการกำจัดอย่างชัดเจนการสร้างและจัดการและแทนที่จะทำงานเฉพาะกับStringBuilder IEnumerableซึ่งจะหลีกเลี่ยงการจัดสรรบัฟเฟอร์ขนาดใหญ่ในหน่วยความจำ

public static class Util
{
    public static string EscapeQuotes(this string self) {
        return self?.Replace("\"", "\"\"") ?? "";
    }

    public static string Surround(this string self, string before, string after) {
        return $"{before}{self}{after}";
    }

    public static string Quoted(this string self, string quotes = "\"") {
        return self.Surround(quotes, quotes);
    }

    public static string QuotedCSVFieldIfNecessary(this string self) {
        return (self == null) ? "" : self.Contains('"') ? self.Quoted() : self; 
    }

    public static string ToCsvField(this string self) {
        return self.EscapeQuotes().QuotedCSVFieldIfNecessary();
    }

    public static string ToCsvRow(this IEnumerable<string> self){
        return string.Join(",", self.Select(ToCsvField));
    }

    public static IEnumerable<string> ToCsvRows(this DataTable self) {          
        yield return self.Columns.OfType<object>().Select(c => c.ToString()).ToCsvRow();
        foreach (var dr in self.Rows.OfType<DataRow>())
            yield return dr.ItemArray.Select(item => item.ToString()).ToCsvRow();
    }

    public static void ToCsvFile(this DataTable self, string path) {
        File.WriteAllLines(path, self.ToCsvRows());
    }

}

วิธีการนี้จะรวมไว้เป็นอย่างดีกับการแปลงIEnumerableไป DataTable เป็นถามที่นี่


0
        DataTable dt = yourData();
        StringBuilder csv = new StringBuilder();
        int dcCounter = 0;

        foreach (DataColumn dc in dt.Columns)
        {
            csv.Append(dc);
            if (dcCounter != dt.Columns.Count - 1)
            {
                csv.Append(",");
            }
            dcCounter++;
        }
        csv.AppendLine();

        int numOfDc = dt.Columns.Count;
        foreach (DataRow dr in dt.Rows)
        {
            int colIndex = 0;
            while (colIndex <= numOfDc - 1)
            {
                var colVal = dr[colIndex].ToString();
                if (colVal != null && colVal != "")
                {
                    DateTime isDateTime;
                    if (DateTime.TryParse(colVal, out isDateTime))
                    {
                        csv.Append(Convert.ToDateTime(colVal).ToShortDateString());
                    }
                    else
                    {
                        csv.Append(dr[colIndex]);
                    }
                }
                else
                {
                    csv.Append("N/A");
                }
                if (colIndex != numOfDc - 1)
                {
                    csv.Append(",");
                }
                colIndex++;
            }
            csv.AppendLine();

ฉันยังต้องทำการลบล้างข้อมูลบางอย่างซึ่งเป็นสาเหตุที่มีคำสั่ง "if else" บางส่วน ฉันต้องตรวจสอบให้แน่ใจว่าหากช่องว่างเปล่าให้ป้อน "N / A" แทนหรือหากช่องวันที่อยู่ในรูปแบบ "01/01/1900: 00" จะได้รับการบันทึกเป็น "01/01/1900" แทน.


0
StringBuilder sb = new StringBuilder();

        foreach (DataColumn col in table.Columns)
        {
            sb.Append(col.ColumnName + ";");
        }

        foreach (DataRow row in table.Rows)
        {
            sb.AppendLine();
            foreach (DataColumn col in table.Columns)
            {
                sb.Append($@"{Convert.ToString(row[col])}" + ";");
            }
        }
        File.WriteAllText(path, sb.ToString());

-1

หากข้อมูลทั้งหมดยังอยู่ในเซลล์แรกแสดงว่าแอปพลิเคชันที่คุณเปิดไฟล์นั้นคาดว่าจะมีตัวคั่นอื่น MSExcel สามารถจัดการกับเครื่องหมายจุลภาคเป็นตัวคั่นเว้นแต่คุณจะระบุไว้เป็นอย่างอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.