|
|
@@ -0,0 +1,180 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Data;
|
|
|
+using System.IO.Abstractions;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace qdr.app.studiou.orders2printpack.Extensions
|
|
|
+{
|
|
|
+public static class CsvUtils
|
|
|
+{
|
|
|
+ public static DataTable CsvToDataTable(IFileSystem fs, string csvFile, string delimiter = ",", bool hasHeaderRow = true)
|
|
|
+ {
|
|
|
+ if (!fs.File.Exists(csvFile))
|
|
|
+ {
|
|
|
+ throw new FileNotFoundException("File '" + csvFile + "' not found!", csvFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ DataTable dataTable = new DataTable();
|
|
|
+ using (StreamReader streamReader = fs.File.OpenText(csvFile))
|
|
|
+ {
|
|
|
+ string[] array = null;
|
|
|
+ if (hasHeaderRow)
|
|
|
+ {
|
|
|
+ array = ParseCsvLine(streamReader.ReadLine(), delimiter);
|
|
|
+ if (array == null)
|
|
|
+ {
|
|
|
+ return dataTable;
|
|
|
+ }
|
|
|
+
|
|
|
+ string[] array2 = array;
|
|
|
+ foreach (string text in array2)
|
|
|
+ {
|
|
|
+ dataTable.Columns.Add(text.Trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ while (!streamReader.EndOfStream)
|
|
|
+ {
|
|
|
+ string[] array3 = ParseCsvLine(streamReader.ReadLine(), delimiter);
|
|
|
+ if (array3 == null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array == null)
|
|
|
+ {
|
|
|
+ array = new string[array3.Length];
|
|
|
+ for (int j = 0; j < array3.Length; j++)
|
|
|
+ {
|
|
|
+ array[j] = $"Column{j + 1}";
|
|
|
+ dataTable.Columns.Add(array[j]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DataRow dataRow = dataTable.NewRow();
|
|
|
+ for (int k = 0; k < Math.Min(array.Length, array3.Length); k++)
|
|
|
+ {
|
|
|
+ dataRow[k] = array3[k];
|
|
|
+ }
|
|
|
+
|
|
|
+ dataTable.Rows.Add(dataRow);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return dataTable;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string[]? ParseCsvLine(string? line, string delimiter)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(line))
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<string> list = new List<string>();
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+ bool flag = false;
|
|
|
+ for (int i = 0; i < line.Length; i++)
|
|
|
+ {
|
|
|
+ if (flag)
|
|
|
+ {
|
|
|
+ if (line[i] == '"' && (i + 1 == line.Length || line[i + 1] != '"'))
|
|
|
+ {
|
|
|
+ flag = false;
|
|
|
+ }
|
|
|
+ else if (line[i] == '"' && i + 1 < line.Length && line[i + 1] == '"')
|
|
|
+ {
|
|
|
+ stringBuilder.Append('"');
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ stringBuilder.Append(line[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (line[i] == '"')
|
|
|
+ {
|
|
|
+ flag = true;
|
|
|
+ }
|
|
|
+ else if (line.Substring(i).StartsWith(delimiter))
|
|
|
+ {
|
|
|
+ list.Add(stringBuilder.ToString().Trim());
|
|
|
+ stringBuilder.Clear();
|
|
|
+ i += delimiter.Length - 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ stringBuilder.Append(line[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ list.Add(stringBuilder.ToString().Trim());
|
|
|
+ return list.ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void DataTableToCsv(IFileSystem fs, DataTable dataTable, string filePath, string delimiter = ",", Func<string, string>? processColumnCallback = null)
|
|
|
+ {
|
|
|
+ string delimiter2 = delimiter;
|
|
|
+ using StreamWriter streamWriter = fs.File.CreateText(filePath);
|
|
|
+ streamWriter.WriteLine(string.Join(delimiter2, from DataColumn column in dataTable.Columns
|
|
|
+ select QuoteValue(processColumnCallback == null ? column.ColumnName : processColumnCallback(column.ColumnName), delimiter2)));
|
|
|
+ foreach (DataRow row in dataTable.Rows)
|
|
|
+ {
|
|
|
+ streamWriter.WriteLine(string.Join(delimiter2, row.ItemArray.Select((object field) => QuoteValue(field?.ToString(), delimiter2))));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<Dictionary<string, string>> CsvToDictionaryList(IFileSystem fs, string csvFile, string delimiter = ",")
|
|
|
+ {
|
|
|
+ if (!fs.File.Exists(csvFile))
|
|
|
+ {
|
|
|
+ throw new FileNotFoundException("File '" + csvFile + "' not found!", csvFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
|
|
|
+ using (StreamReader streamReader = new StreamReader(csvFile))
|
|
|
+ {
|
|
|
+ string[] array = ParseCsvLine(streamReader.ReadLine(), delimiter);
|
|
|
+ if (array == null)
|
|
|
+ {
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (!streamReader.EndOfStream)
|
|
|
+ {
|
|
|
+ string[] array2 = ParseCsvLine(streamReader.ReadLine(), delimiter);
|
|
|
+ if (array2 != null)
|
|
|
+ {
|
|
|
+ Dictionary<string, string> dictionary = new Dictionary<string, string>();
|
|
|
+ for (int i = 0; i < array.Length; i++)
|
|
|
+ {
|
|
|
+ dictionary[array[i].Trim()] = ((i < array2.Length) ? array2[i] : string.Empty);
|
|
|
+ }
|
|
|
+
|
|
|
+ list.Add(dictionary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string QuoteValue(string? value, string delimiter)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(value))
|
|
|
+ {
|
|
|
+ return string.Empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (value.Contains(delimiter) || value.Contains("\"") || value.Contains("\r") || value.Contains("\n"))
|
|
|
+ {
|
|
|
+ return "\"" + value.Replace("\"", "\"\"") + "\"";
|
|
|
+ }
|
|
|
+
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+}
|
|
|
+}
|