I get over 100000+ rows in a Data Grid View at times and I want the users to be able to export them to excel faster. Currently, my windows form goes in the "Not Responding" stage but it is actually carrying out the export in the Back End. I want to carry out the export on a different thread so that it is faster, AND I want to add a progress bar to show the progress of the export itself.
I have tried the following:
- Create a new Task - time to export actually gets longer
- Create a different thread to run on using Thread thread = new Thread(Export) - it gives an error when the show Dialogue Box line is run
My code is as follows:
private void BtnSearchExportCSV_Click(object sender, EventArgs e)
{
Export();
}
private void CopyAllToClipBoard()
{
dgvSearchFilter.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
dgvSearchFilter.MultiSelect = true;
dgvSearchFilter.RowHeadersVisible = false;
dgvSearchFilter.SelectAll();
DataObject dataObj = dgvSearchFilter.GetClipboardContent();
if (dataObj != null)
{
Invoke((Action)(() => { Clipboard.SetDataObject(dataObj); }));
//Clipboard.SetDataObject(dataObj);
}
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occurred while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
private void Export()
{
try
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel Documents (*.xls)|*.xls";
sfd.FileName = "Export.xls";
if (sfd.ShowDialog() == DialogResult.OK)
{
// Copy DataGridView results to clipboard
CopyAllToClipBoard();
object misValue = System.Reflection.Missing.Value;
Excel.Application xlexcel = new Excel.Application();
// Without this you will get two confirm overwrite prompts
xlexcel.DisplayAlerts = false;
Excel.Workbook xlWorkBook = xlexcel.Workbooks.Add(misValue);
Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
// Paste clipboard results to worksheet range
Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1];
CR.Select();
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
// For some reason column A is always blank in the worksheet. ¯\_(ツ)_/¯
// Delete blank column A and select cell A1
//Excel.Range delRng = xlWorkSheet.get_Range("A:A").Cells;
//delRng.Delete(Type.Missing);
//xlWorkSheet.get_Range("A1").Select();
// Save the excel file under the captured location from the SaveFileDialog
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlexcel.DisplayAlerts = true;
xlWorkBook.Close(true, misValue, misValue);
xlexcel.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlexcel);
// Clear Clipboard and DataGridView selection
Clipboard.Clear();
dgvSearchFilter.ClearSelection();
// Open the newly saved excel file
if (File.Exists(sfd.FileName))
System.Diagnostics.Process.Start(sfd.FileName);
}
}
catch (Exception exception)
{
MessageBox.Show("The following exception occurred: " + exception.ToString());
}
}
}
I'm getting more familiar with C#. However, this is the first time I have encountered something like this.
Thank you.