2013-04-04 64 views
2

我需要用兩個excel文件填充兩個數據表。這些文件可以是逗號分隔值文件(.csv),也可以是Excel文檔(.xlsx)文件。我用一個函數來我的.csv轉換爲數據表:發生將.csv轉換爲數據表時的額外引號


public DataTable GetDataTableFromCsv(string path) 
{ 
    DataTable dataTable = new DataTable(); 
    String[] values; 

    values = File.ReadAllLines(path); 

    string[] csvRows = System.IO.File.ReadAllLines(path); 
    string[] headers = csvRows[0].Split(','); 

    // Adding columns name 
    foreach (var item in headers) 
     dataTable.Columns.Add(new DataColumn(item)); 

    string[] fields = null; 

    foreach (string csvRow in csvRows) 
    { 
     fields = csvRow.Split(','); 
     DataRow row = dataTable.NewRow(); 
     row.ItemArray = fields; 
     dataTable.Rows.Add(row); 
    } 
    return dataTable; 
} 

的問題,當我嘗試我的兩個DataTable具有比較:

ieDiff = dt1.AsEnumerable().Except(dt2.AsEnumerable(), DataRowComparer.Default); 

我的第一個數據表被獲得。 xlsx文件包含正確的值,而通過.csv文件獲得的第二個數據表包含正確的值,但帶有一些額外的引號。

例如:

dt1.Rows [10](從數據表的.csv)意願包含:

  1. 的Item1
  2. 項目2
  3. 「」
  4. 「項目4」

dt2.Rows [10](數據表從.XLSX)意願包含:

  1. 的Item1
  2. 項目2
  3. 項目4

我知道我可以修剪所有這些,但肯定是有執行此更好的辦法?

+0

csv文件,爲什麼不能與Excel文件處理直接跳過該.csv階段?即使在最好的日子裏,CSV也是一種非常愚蠢的格式。 – 2013-04-04 15:22:08

+0

我知道這一點,但我不能那樣做。我需要與此不幸地合作。 – Sebastien 2013-04-04 15:23:37

+0

你需要報價嗎?如果沒有,那麼只需在foreach循環中添加這一行fields = fields.Replace(「\」「,」「); – 2013-04-04 15:30:29

回答

0

最簡單的答案就是你在修改引號字符的問題中提到的問題。

我的測試代碼:

var test = new[] { "Item1", "Item2", "\".\"", "\"Item4\"" }; 
foreach (var s in test) 
{ 
    textBox1.AppendTextAddNewLine(s.Trim('"')); 
} 

結果輸出:

Item1 
Item2 
. 
Item4 
+0

請注意,您可能還需要取消字段值的一部分的未轉義引號。請參閱此問題以瞭解如何轉義用於Excel的CSV文件; http://stackoverflow.com/questions/165042/stop-excel-from-automatically-converting-certain-text-values-to-dates,以及關於此問題的官方CSV規範的此頁面; http://tools.ietf.org/html/rfc4180 #page-3 – Sphinxxx 2013-04-04 19:06:21

+0

@Sphinxxx是真實的,但修剪只會修剪開始或結束時的引號字符而不是字符串中間,所以在這種情況下,我相信它應該沒問題,但我不是引號轉義/以任何方式解散專家 – Charles380 2013-04-05 14:31:46

0

我寫了下面這五種方法將變成一個CSV文件導入數據表。

它們的設計考慮了可選的引號(例如,「符號),併成爲多才多藝儘可能不使用其他庫:否則

Warning[] warnings; 
    string[] streamids; 
    string mimeType; 
    string encoding; 
    string filenameExtension; 

    byte[] bytes = rvMain.ServerReport.Render("csv", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings); 

    string CsvBody = System.Text.Encoding.UTF8.GetString(bytes); 

    DataTable dt = GetDataTableFromCsvString(CsvBody,true); 

public static DataTable GetDataTabletFromCSVFile(string filePath, bool isHeadings) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      using (TextFieldParser TextFieldParser = new TextFieldParser(filePath)) 
      { 
       if (isHeadings) 
       { 
        MethodResult = GetDataTableFromTextFieldParser(TextFieldParser); 

       } 
       else 
       { 
        MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser); 

       } 

      } 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

    public static DataTable GetDataTableFromCsvString(string csvBody, bool isHeadings) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      MemoryStream MemoryStream = new MemoryStream(); 


      StreamWriter StreamWriter = new StreamWriter(MemoryStream); 

      StreamWriter.Write(csvBody); 

      StreamWriter.Flush(); 


      MemoryStream.Position = 0; 


      using (TextFieldParser TextFieldParser = new TextFieldParser(MemoryStream)) 
      { 
       if (isHeadings) 
       { 
        MethodResult = GetDataTableFromTextFieldParser(TextFieldParser); 

       } 
       else 
       { 
        MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser); 

       } 

      } 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

    public static DataTable GetDataTableFromRemoteCsv(string url, bool isHeadings) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); 
      HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 

      StreamReader StreamReader = new StreamReader(httpWebResponse.GetResponseStream()); 

      using (TextFieldParser TextFieldParser = new TextFieldParser(StreamReader)) 
      { 
       if (isHeadings) 
       { 
        MethodResult = GetDataTableFromTextFieldParser(TextFieldParser); 

       } 
       else 
       { 
        MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser); 

       } 

      } 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 


    private static DataTable GetDataTableFromTextFieldParser(TextFieldParser textFieldParser) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      textFieldParser.SetDelimiters(new string[] { "," }); 

      textFieldParser.HasFieldsEnclosedInQuotes = true; 


      string[] ColumnFields = textFieldParser.ReadFields(); 

      DataTable dt = new DataTable(); 

      foreach (string ColumnField in ColumnFields) 
      { 
       DataColumn DataColumn = new DataColumn(ColumnField); 

       DataColumn.AllowDBNull = true; 

       dt.Columns.Add(DataColumn); 

      } 


      while (!textFieldParser.EndOfData) 
      { 
       string[] Fields = textFieldParser.ReadFields(); 


       for (int i = 0; i < Fields.Length; i++) 
       { 
        if (Fields[i] == "") 
        { 
         Fields[i] = null; 

        } 

       } 

       dt.Rows.Add(Fields); 

      } 

      MethodResult = dt; 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

    private static DataTable GetDataTableFromTextFieldParserNoHeadings(TextFieldParser textFieldParser) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      textFieldParser.SetDelimiters(new string[] { "," }); 

      textFieldParser.HasFieldsEnclosedInQuotes = true; 

      bool FirstPass = true; 

      DataTable dt = new DataTable(); 

      while (!textFieldParser.EndOfData) 
      { 
       string[] Fields = textFieldParser.ReadFields(); 

       if(FirstPass) 
       { 
        for (int i = 0; i < Fields.Length; i++) 
        { 
         DataColumn DataColumn = new DataColumn("Column " + i); 

         DataColumn.AllowDBNull = true; 

         dt.Columns.Add(DataColumn); 

        } 

        FirstPass = false; 

       } 

       for (int i = 0; i < Fields.Length; i++) 
       { 
        if (Fields[i] == "") 
        { 
         Fields[i] = null; 

        } 

       } 

       dt.Rows.Add(Fields); 

      } 

      MethodResult = dt; 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

如果像我一樣,你從報告服務,然後保存,你應該使用這樣的,所有你需要做的是:

bool IsHeadings = true; //Does the data include a heading row? 

    DataTable dt = GetDataTableFromCsvString(CsvBody, IsHeadings); 

或直接從csv文件使用

bool IsHeadings = true; //Does the data include a heading row? 

    DataTable dt = GetDataTabletFromCsvFile(FilePath, IsHeadings) 

,或者如果您在C#是爲使用遠程存儲

bool IsHeadings = true; //Does the data include a heading row? 

    DataTable dt = GetDataTabletFromRemoteCsv(Url, IsHeadings)