Je travaille avec DataTable et je dois les convertir au format de fichier CSV. La plupart des tables avec lesquelles je travaille ont plus de 50 000 enregistrements, j'essaie donc de minimiser le temps nécessaire pour les convertir.
Voici ma méthode actuelle:
public static string table_to_csv(DataTable table)
{
string file = "";
foreach (DataColumn col in table.Columns)
file = string.Concat(file, col.ColumnName, ",");
file = file.Remove(file.LastIndexOf(','), 1);
file = string.Concat(file, "\r\n");
foreach (DataRow row in table.Rows)
{
foreach (object item in row.ItemArray)
file = string.Concat(file, item.ToString(), ",");
file = file.Remove(file.LastIndexOf(','), 1);
file = string.Concat(file, "\r\n");
}
return file;
}
Existe-t-il un moyen d'améliorer l'efficacité de cette méthode? Je suis le bienvenu pour toutes les modifications et idées que vous avez!
oui, utilisez un System.Text.StringBuilder pour les chaînes énormes. J'ai implémenté celui-ci:
public static string DataTableToCSV(this DataTable datatable, char seperator)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < datatable.Columns.Count; i++)
{
sb.Append(datatable.Columns[i]);
if (i < datatable.Columns.Count - 1)
sb.Append(seperator);
}
sb.AppendLine();
foreach (DataRow dr in datatable.Rows)
{
for (int i = 0; i < datatable.Columns.Count; i++)
{
sb.Append(dr[i].ToString());
if (i < datatable.Columns.Count - 1)
sb.Append(seperator);
}
sb.AppendLine();
}
return sb.ToString();
}
Voici une méthode que j'ai dans ma classe Utility. Fonctionne bien pour ce que je fais.
public static void GenerateCSV(DataTable dt)
{
StringBuilder sb = new StringBuilder();
try
{
int count = 1;
int totalColumns = dt.Columns.Count;
foreach (DataColumn dr in dt.Columns)
{
sb.Append(dr.ColumnName);
if (count != totalColumns)
{
sb.Append(",");
}
count++;
}
sb.AppendLine();
string value = String.Empty;
foreach (DataRow dr in dt.Rows)
{
for (int x = 0; x < totalColumns; x++)
{
value = dr[x].ToString();
if (value.Contains(",") || value.Contains("\""))
{
value = '"' + value.Replace("\"", "\"\"") + '"';
}
sb.Append(value);
if (x != (totalColumns - 1))
{
sb.Append(",");
}
}
sb.AppendLine();
}
}
catch (Exception ex)
{
// Do something
}
}
J'ai utilisé cette méthode qui copie le tableau d'objets dans une plage de cellules Excel plutôt que de copier ligne par ligne puis colonne par colonne et cela s'est avéré être un moyen assez efficace
public void ExportToExcel(DataTable dataTable, String pathToSave)
{
// Create the Excel Application object
var excelApp = new ApplicationClass();
// Create a new Excel Workbook
Workbook excelWorkbook = excelApp.Workbooks.Add(Type.Missing);
int sheetIndex = 0;
// Copy the DataTable to an object array
var rawData = new object[dataTable.Rows.Count + 1, dataTable.Columns.Count];
// Copy the column names to the first row of the object array
for (var col = 0; col < dataTable.Columns.Count; col++)
{
rawData[0, col] = dataTable.Columns[col].ColumnName;
}
// Copy the values to the object array
for (var col = 0; col < dataTable.Columns.Count; col++)
{
for (int row = 0; row < dataTable.Rows.Count; row++)
{
rawData[row + 1, col] = dataTable.Rows[row].ItemArray[col];
}
}
// Calculate the final column letter
string finalColLetter = string.Empty;
const string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int colCharsetLen = colCharset.Length;
if (dataTable.Columns.Count > colCharsetLen)
{
finalColLetter = colCharset.Substring(
(dataTable.Columns.Count - 1) / colCharsetLen - 1, 1);
}
finalColLetter += colCharset.Substring((dataTable.Columns.Count - 1) % colCharsetLen, 1);
// Create a new Sheet
var excelSheet = (Worksheet)excelWorkbook.Sheets.Add(excelWorkbook.Sheets.Item[++sheetIndex], Type.Missing, 1, XlSheetType.xlWorksheet);
excelSheet.Name = dataTable.TableName;
// Fast data export to Excel
var excelRange = string.Format("A1:{0}{1}", finalColLetter, dataTable.Rows.Count + 1);
excelSheet.Range[excelRange, Type.Missing].Value2 = rawData;
// Mark the first row as BOLD and BLUE
var headerColumnRange = (Range)excelSheet.Rows[1, Type.Missing];
headerColumnRange.Font.Bold = true;
headerColumnRange.Font.Color = 0xFF0000;
headerColumnRange.EntireColumn.AutoFit();
// Save and Close the Workbook
excelWorkbook.SaveAs(pathToSave, XlFileFormat.xlWorkbookNormal, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
excelWorkbook.Close(true, Type.Missing, Type.Missing);
excelWorkbook = null;
// Release the Application object
excelApp.Quit();
excelApp = null;
// Collect the unreferenced objects
GC.Collect();
GC.WaitForPendingFinalizers();
}