You should be familiar with how to export the data of the datagridview to excel. It is nothing more than traversing the rows and columns of the datagridview dview and writing the data into the Excel Workbook, however, you need to add a com reference to excel in the project, which will be restricted by the client environment. It is easier to directly export data in CSV format. CSV is a simple file that separates data with delimiters (such as commas, Tab tabs, and so on, it can be opened in Excel or notepad. Generally, exporting data directly to a CSV file is faster. However, if you export data to a file in the Excel standard format, you need to call the object in the COM component, therefore, the speed will be slower. It is necessary to add a real-time progress bar to the UI. The easiest way to use progressbar in multiple threads is to use the backgroundworker component and put the exported data code into the dowork event handler of the backgroundworker, and reports the progress in real time. The backgroundworker progresschanged event is used to update the value of progressbar In the UI thread, and the backgroundworker runworkercompleted event is used to process things after the operation is completed, such as hiding progressbar, or Display Error information. However, there is a problem here. The data export method is generally a public method that can be called in different places of the application. Therefore, this method should not depend on any form or UI element, we should try to write it into a class independently, and it also supports the update of progressbar.
According to the traditional method of using backgroundworker, we need to pass backgroundworker to this class. At the same time, the class also needs to process events related to backgroundworker and UI-related events, this clearly violates the single responsibility principle in Agile development-a class only allows one reason for its change ". The introduction of too many UI-related elements will cause the class to be less generic and difficult to implement. How to export data from the datagridview to an Excel or CSV file is not difficult. The main problem now is how to support real-time update of progressbar progress.
A better way is to adopt the. NET event-driven approach. We can define several events in the class, such as the events when data is exported, the events when data is exported, and the events after data is exported. The caller registers these events to get in touch with the class. To put it bluntly, the link of a connection is an event, which is the same as the interaction between various forms in the winform program. Let's take a look at the main uses of these events.
1. events when data export starts
This event is triggered before the data is exported. It is used to obtain the total number of steps required for data export (generally, it can be regarded as the sum of the rows and columns in the datagridview data, depending on the specific export method ). The caller can update the properties of the progressbar In the event processing program, such as value, maximnm, and visible.
2. events when data is being exported
This event updates the progress of the progressbar. Each row or column of data exported triggers an event. The caller updates the progress of the progressbar In the event handler.
3. Events after data export is complete
In the method for exporting data, this event is triggered no matter what the data export process ends (successfully ends or throws an exception), and a custom parameter inherited from the eventargs class is passed. In the event processing program, the caller can determine whether the data export is successful based on this parameter, so as to display the error information in the UI thread or provide the project completion prompt information.
Note that the caller must use the invoke agent to update the UI in the event processing program. Otherwise, an exception occurs in cross-thread UI operations. For a modal dialog box such as MessageBox. Show (), if it is not called by proxy in invoke, it will lose the role of the modal dialog box because it is executed in a non-UI thread.
Complete code of the class: exportdatagridviewtoexcel.zip
Example of frontend call:
Private exportdatagridviewtoexcel export = NULL;
Public detailstable ()
{
Initializecomponent ();
Export = new exportdatagridviewtoexcel ();
Export. Maid = This. Maid;
Export. exportstartingevent + = new eventhandler (export_exportstartingevent );
Export. exportprogressingevent + = new eventhandler (export_exportprogressingevent );
Export. exportendedevent + = new eventhandler <exportdatagridviewtoexcel. exportendedeventargs> (export_exportendedevent );
}
// Data export end event.
Void export_exportendedevent (Object sender, exportdatagridviewtoexcel. exportendedeventargs E)
{
If (E. iscompleted)
{
If (this. invokerequired)
{
This. Invoke (New methodinvoker (delegate ()
{
MessageBox. Show ("complete! "," Prompt ", messageboxbuttons. OK, messageboxicon. information );
}));
}
}
Else
{
If (this. invokerequired)
{
This. Invoke (New methodinvoker (delegate ()
{
MessageBox. Show (this, "Export File failed. \ r \ n {0}" + E. Errors = NULL? String. Empty: E. errors. message, "errors", messageboxbuttons. OK, messageboxicon. Error );
}));
}
}
If (this. invokerequired)
{
This. Invoke (New methodinvoker (delegate ()
{
This. toolstripprogressbar. Visible = false;
}));
}
}
// Data export in process event.
Void export_exportprogressingevent (Object sender, eventargs E)
{
Int nowvalue = convert. toint32 (sender );
If (this. invokerequired)
{
This. Invoke (New methodinvoker (delegate ()
{
This. toolstripprogressbar. value = nowvalue;
}));
}
}
// Data export Starting event.
Void export_exportstartingevent (Object sender, eventargs E)
{
Int maxvalue = convert. toint32 (sender );
If (this. invokerequired)
{
This. Invoke (New methodinvoker (delegate ()
{
This. toolstripprogressbar. value = 0;
This. toolstripprogressbar. Maximum = maxvalue;
This. toolstripprogressbar. Visible = true;
}));
}
}
// Export to CSV.
Private void exporttocsvtoolstripmenuitem_exporttocsv_click (Object sender, eventargs E)
{
This. savefiledialog_csv.filename = This. text;
If (savefiledialog_csv.showdialog () = system. Windows. Forms. dialogresult. OK)
{
Export. filepath = savefiledialog_csv.filename;
Thread thread = new thread (New parameterizedthreadstart (export. datagridviewtocsv ));
Thread. Start (savefiledialog_csv.openfile ());
}
}
// Export to excel.
Private void exporttoexceltoolstripmenuitem_exporttoexcel_click (Object sender, eventargs E)
{
This. savefiledialog_excel.filename = This. text;
If (savefiledialog_excel.showdialog () = system. Windows. Forms. dialogresult. OK)
{
Export. filepath = savefiledialog_excel.filename;
Thread thread = new thread (New threadstart (export. datagridviewtoexcel ));
Thread. Start ();
}
}
Private void copytoolstripmenuitem_copy_click (Object sender, eventargs E)
{
Dataobject d = This. datagridview1.getclipboardcontent ();
Clipboard. setdataobject (d );
}
Private void toolstripbutton_toexcel_click (Object sender, eventargs E)
{
This. exporttoexceltoolstripmenuitem_exporttoexcel.w.mclick ();
}
Private void toolstripbutton_tocsv_click (Object sender, eventargs E)
{
This. exporttocsvtoolstripmenuitem_exporttocsv.w.mclick ();
}
The last three event handlers are copy events in the context menu of the dview; export to excel events in the context menu of the datagridview, you can directly use the export mclick method of the exporttoexceltoolstripmenuitem toolbar button; the export to CSV event in the context menu of the datagridview, directly using the Export mclick method of the exporttocsvtoolstripmenuitem toolbar button.