CsvUtils.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.IO.Abstractions;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace qdr.app.studiou.orders2printpack.Extensions
  9. {
  10. public static class CsvUtils
  11. {
  12. public static DataTable CsvToDataTable(IFileSystem fs, string csvFile, string delimiter = ",", bool hasHeaderRow = true)
  13. {
  14. if (!fs.File.Exists(csvFile))
  15. {
  16. throw new FileNotFoundException("File '" + csvFile + "' not found!", csvFile);
  17. }
  18. DataTable dataTable = new DataTable();
  19. using (StreamReader streamReader = fs.File.OpenText(csvFile))
  20. {
  21. string[] array = null;
  22. if (hasHeaderRow)
  23. {
  24. array = ParseCsvLine(streamReader.ReadLine(), delimiter);
  25. if (array == null)
  26. {
  27. return dataTable;
  28. }
  29. string[] array2 = array;
  30. foreach (string text in array2)
  31. {
  32. dataTable.Columns.Add(text.Trim());
  33. }
  34. }
  35. while (!streamReader.EndOfStream)
  36. {
  37. string[] array3 = ParseCsvLine(streamReader.ReadLine(), delimiter);
  38. if (array3 == null)
  39. {
  40. continue;
  41. }
  42. if (array == null)
  43. {
  44. array = new string[array3.Length];
  45. for (int j = 0; j < array3.Length; j++)
  46. {
  47. array[j] = $"Column{j + 1}";
  48. dataTable.Columns.Add(array[j]);
  49. }
  50. }
  51. DataRow dataRow = dataTable.NewRow();
  52. for (int k = 0; k < Math.Min(array.Length, array3.Length); k++)
  53. {
  54. dataRow[k] = array3[k];
  55. }
  56. dataTable.Rows.Add(dataRow);
  57. }
  58. }
  59. return dataTable;
  60. }
  61. private static string[]? ParseCsvLine(string? line, string delimiter)
  62. {
  63. if (string.IsNullOrEmpty(line))
  64. {
  65. return null;
  66. }
  67. List<string> list = new List<string>();
  68. StringBuilder stringBuilder = new StringBuilder();
  69. bool flag = false;
  70. for (int i = 0; i < line.Length; i++)
  71. {
  72. if (flag)
  73. {
  74. if (line[i] == '"' && (i + 1 == line.Length || line[i + 1] != '"'))
  75. {
  76. flag = false;
  77. }
  78. else if (line[i] == '"' && i + 1 < line.Length && line[i + 1] == '"')
  79. {
  80. stringBuilder.Append('"');
  81. i++;
  82. }
  83. else
  84. {
  85. stringBuilder.Append(line[i]);
  86. }
  87. }
  88. else if (line[i] == '"')
  89. {
  90. flag = true;
  91. }
  92. else if (line.Substring(i).StartsWith(delimiter))
  93. {
  94. list.Add(stringBuilder.ToString().Trim());
  95. stringBuilder.Clear();
  96. i += delimiter.Length - 1;
  97. }
  98. else
  99. {
  100. stringBuilder.Append(line[i]);
  101. }
  102. }
  103. list.Add(stringBuilder.ToString().Trim());
  104. return list.ToArray();
  105. }
  106. public static void DataTableToCsv(IFileSystem fs, DataTable dataTable, string filePath, string delimiter = ",", Func<string, string>? processColumnCallback = null)
  107. {
  108. string delimiter2 = delimiter;
  109. using StreamWriter streamWriter = fs.File.CreateText(filePath);
  110. streamWriter.WriteLine(string.Join(delimiter2, from DataColumn column in dataTable.Columns
  111. select QuoteValue(processColumnCallback == null ? column.ColumnName : processColumnCallback(column.ColumnName), delimiter2)));
  112. foreach (DataRow row in dataTable.Rows)
  113. {
  114. streamWriter.WriteLine(string.Join(delimiter2, row.ItemArray.Select((object field) => QuoteValue(field?.ToString(), delimiter2))));
  115. }
  116. }
  117. public static List<Dictionary<string, string>> CsvToDictionaryList(IFileSystem fs, string csvFile, string delimiter = ",")
  118. {
  119. if (!fs.File.Exists(csvFile))
  120. {
  121. throw new FileNotFoundException("File '" + csvFile + "' not found!", csvFile);
  122. }
  123. List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
  124. using (StreamReader streamReader = new StreamReader(csvFile))
  125. {
  126. string[] array = ParseCsvLine(streamReader.ReadLine(), delimiter);
  127. if (array == null)
  128. {
  129. return list;
  130. }
  131. while (!streamReader.EndOfStream)
  132. {
  133. string[] array2 = ParseCsvLine(streamReader.ReadLine(), delimiter);
  134. if (array2 != null)
  135. {
  136. Dictionary<string, string> dictionary = new Dictionary<string, string>();
  137. for (int i = 0; i < array.Length; i++)
  138. {
  139. dictionary[array[i].Trim()] = ((i < array2.Length) ? array2[i] : string.Empty);
  140. }
  141. list.Add(dictionary);
  142. }
  143. }
  144. }
  145. return list;
  146. }
  147. private static string QuoteValue(string? value, string delimiter)
  148. {
  149. if (string.IsNullOrEmpty(value))
  150. {
  151. return string.Empty;
  152. }
  153. if (value.Contains(delimiter) || value.Contains("\"") || value.Contains("\r") || value.Contains("\n"))
  154. {
  155. return "\"" + value.Replace("\"", "\"\"") + "\"";
  156. }
  157. return value;
  158. }
  159. }
  160. }