2016-03-04 52 views
0

我提供了2個Excel文件,我將其轉換爲TSV文件,最終必須在TSV文件中提供。第一個文件是主文件(strWorksheetPath),並且必須包含所有行。第二個文件(PrintPath)有附加信息,但主文件中的每一行都沒有額外的信息。在C#中這樣做我跟着this msdn guide做我必須做的事情,它工作正常。不幸的是,文件1有23欄,文件2有10欄共有33欄,共33處。我創建了一些臨時類來查看是否一切正常,但在我看來,它看起來非常混亂。在C#代碼清理中合併2個TSV文件

有沒有辦法清理我的代碼,並使其看起來更整齊,可能不需要做臨時類,濃縮一些重複代碼,...?

public static void ConvertTSVtoMontDataTable(string strWorksheetPath, string strPrintPath, 
     bool closeConnection = true) 
    { 
     // Check if the main file exist. 
     if (!File.Exists(strWorksheetPath)) return; 

     // Load both files. 
     var mainFile = File.ReadAllLines(strWorksheetPath); 
     var extraFile = File.ReadAllLines(strPrintPath); 

     // Create 2 lists. 
     var mainLines = mainFile.Select(line => new TempMainLine(line)).ToList(); 
     var extraLines = extraFile.Select(line => new TempExtraLine(line)).ToList(); 
     var lines = new List<TempLine>(); 


     // Merge both files. 
     var leftOuterJoinQuery = 
      from worksheetLine in mainLines 
      join printLine in extraLines on string.Concat(worksheetLine.prop6, worksheetLine.prop8) equals 
       string.Concat(printLine.prop4, printLine.prop5) into lineGroup 
      from line in lineGroup.DefaultIfEmpty() 
      select 
       new TempLine(worksheetLine.prop0, worksheetLine.prop1, worksheetLine.prop2, worksheetLine.prop3, 
        worksheetLine.prop4, worksheetLine.prop5, worksheetLine.prop6, worksheetLine.prop7, 
        worksheetLine.prop8, worksheetLine.prop9, worksheetLine.prop10, worksheetLine.prop11, 
        worksheetLine.prop12, worksheetLine.prop13, worksheetLine.prop14, worksheetLine.prop15, 
        worksheetLine.prop16, worksheetLine.prop17, worksheetLine.prop18, worksheetLine.prop19, 
        worksheetLine.prop20, worksheetLine.prop21, worksheetLine.prop22, line == null ? "" : line.prop0, 
        line == null ? "" : line.prop1, line == null ? "" : line.prop2, line == null ? "" : line.prop3, 
        line == null ? "" : line.prop4, line == null ? "" : line.prop5, line == null ? "" : line.prop6, 
        line == null ? "" : line.prop7, line == null ? "" : line.prop8, line == null ? "" : line.prop9); 

     foreach (var tempLine in leftOuterJoinQuery) 
     { 
      lines.Add(tempLine); 
     } 

     // Write output to new temp file (TESTING) 
     using (
      var file = 
       new StreamWriter(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), 
        "output.txt"))) 
     { 
      foreach (var item in lines) 
      { 
       file.WriteLine(item.prop0 + (char)9 + item.prop1 + (char)9 + item.prop2 + (char)9 + item.prop3 + 
           (char)9 + item.prop4 + (char)9 + item.prop5 + (char)9 + item.prop6 + (char)9 + 
           item.prop7 + (char)9 + item.prop8 + (char)9 + item.prop9 + (char)9 + item.prop10 + 
           (char)9 + item.prop11 + (char)9 + item.prop12 + (char)9 + item.prop13 + (char)9 + 
           item.prop14 + (char)9 + item.prop15 + (char)9 + item.prop16 + (char)9 + 
           item.prop17 + (char)9 + item.prop18 + (char)9 + item.prop19 + (char)9 + 
           item.prop20 + (char)9 + item.prop21 + (char)9 + item.prop22 + (char)9 + 
           item.prop23 + (char)9 + item.prop24 + (char)9 + item.prop25 + (char)9 + 
           item.prop26 + (char)9 + item.prop27 + (char)9 + item.prop28 + (char)9 + 
           item.prop29 + (char)9 + item.prop30 + (char)9 + item.prop31 + (char)9 + 
           item.prop32); 
      } 
     } 
    } 
+0

你可以包括TempLine類嗎?你也可以在'//合併兩個文件'之後不需要foreach(),你可以將'var lines ='移動到var var leftOuterJoinQuery ='並執行'ToList(); '在結尾 – CaseyR

回答

1

我想到這一些,也不管您的Temp *類是什麼樣子,沿(根據您提供的代碼)的下面將工作給予的假設行的東西,你輸出這兩個文件中的每一列都按照它們的順序排列。如果需要排除字段,更改順序等,則需要對下面的或不同的解決方案進行一些更改。

它基本上只是讀取這兩個文件,加入Split()結果,然後結合兩行。我沒有看到一個點在處理LOJ邏輯空printFile線,但如果你需要額外的標籤,你可以用類似line ?? new String('\t', 10)

注意更換line ?? "",這可能不是要走的最有效的方法關於這一點,如果你的文件很大,你一定會優化這一點。

// Merge both files. 
var lines = 
    from worksheetLine in mainFile 
    join printLine in extraFile on string.Concat(worksheetLine.Split('\t')[6], worksheetLine.Split('\t')[8]) equals 
    string.Concat(printLine.Split('\t')[4], printLine.Split('\t')[5]) into lineGroup 
    from line in lineGroup.DefaultIfEmpty() 
    select string.Concat(worksheetLine, line ?? ""); 

// Write output to new temp file (TESTING) 
using (
    var file = 
     new StreamWriter(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), 
      "output.txt"))) 
{ 
    foreach (var item in lines) 
    { 
     file.WriteLine(item); 
    } 
} 
+0

我從來沒有想過分離標籤上的線條,並與這些工作。你的解決方案正是我所希望的。我改變的唯一的事情就是'選擇'到'選擇字符串.Concat(worksheetLine,'\ t',行 - 新字符串('\ t',8))''所以在最後一列之間有一個額外的選項卡第二個文件的第一個文件和第一列以及第二個文件如你所建議的那樣是'空'的空白標籤。非常感謝! – Krowi

+0

很高興幫助。我最初使用字典(基本上是對應於>集合的IEnumerable >)來測試這個想法,但認爲這可能是過度的。但是,好處是分裂發生了每個文件一次,具體取決於你需要運行的效率如何,這可能是一個值得探索的途徑 – CaseyR

+0

哦,並且需要兩個文件之間額外的選項卡,我沒有考慮到這一點 – CaseyR