Skip to content

Instantly share code, notes, and snippets.

@Gabriel-Espinoza
Created July 18, 2014 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gabriel-Espinoza/1c86fec6e757fad3834e to your computer and use it in GitHub Desktop.
Save Gabriel-Espinoza/1c86fec6e757fad3834e to your computer and use it in GitHub Desktop.
Interpreta un string en formato CSV usando como separador de columna ";"
/// <summary>
/// Convierte un String a DataTable. El string debe tener estructura de CSV.
/// Esta operación es el complemento a DataTableToString
/// </summary>
/// <param name="data"></param>
/// <param name="includeHeader"></param>
/// <returns></returns>
public static DataTable StringToDataTable(string data, bool includeHeader)
{
return FileTools.StringToDataTable(data, includeHeader, "en-US", Encoding.UTF8, false);
}
public static DataTable StringToDataTable(string data, bool includeHeader, string cultureInfo, Encoding encoding, bool skipLenghtDifferences)
{
MemoryStream ms = new MemoryStream(encoding.GetBytes(data));
return FileTools.StreamToDataTable(ms, includeHeader, cultureInfo, skipLenghtDifferences);
}
/// <summary>
/// Convierte un Stream a DataTable.
/// </summary>
/// <param name="data"></param>
/// <param name="includeHeader"></param>
/// <returns></returns>
public static DataTable StreamToDataTable(Stream data, bool includeHeader, string cultureInfo, bool skipLenghtDifferences)
{
DataTable dt = new DataTable();
using (StreamReader sr = new StreamReader(data))
{
// Se asume que el separador de decimales es punto "." y el de miles "," (aunque este ultimo no se usa)
CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureInfo);
char[] delimiter = new char[] { ';' };
int rowsCompleted = 0;
try
{
Dictionary<string, int> indexes = new Dictionary<string, int>();
//Se lee la primera linea para crear columnas
string[] columnsArray = sr.ReadLine().Split(delimiter);
for (int i = 0; i < columnsArray.Length; i++)
{
string colName = includeHeader ? columnsArray[i] : "Column" + i;
DataColumn c = new DataColumn(colName);
dt.Columns.Add(c);
indexes.Add(c.ColumnName, i);
}
//Se retorna a la posicion de lectura inicial para no perder fila 0
if (!includeHeader)
{
sr.BaseStream.Position = 0;
sr.DiscardBufferedData();
}
while (sr.Peek() > -1)
{
string line = sr.ReadLine();
string[] lineArray = line.Split(delimiter);
DataRow newRow = dt.NewRow();
//Si hay fila con error se detiene la lectura o la salta
if (dt.Columns.Count != lineArray.Length)
{
if (skipLenghtDifferences)
continue;
else
{
string diferencia = dt.Columns.Count > lineArray.Length ? "mas" : "menos";
string msg = "La linea " + (rowsCompleted + 1) + " tiene " + diferencia + " columnas según definicion. Contenido: " + line;
throw new Exception(msg);
}
}
//Se carga la nueva fila
foreach (DataColumn column in dt.Columns)
{
string colName = column.ColumnName;
int index = indexes[colName];
string value = lineArray[index].Trim();
newRow[colName] = string.IsNullOrEmpty(value) ? DBNull.Value + "" : value;
}
dt.Rows.Add(newRow);
rowsCompleted++;
}
}
catch (Exception innerException)
{
throw new Exception("Error en línea " + rowsCompleted + ".", innerException);
}
finally
{
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
}
}
return dt;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment