The ReportExporters uses the Microsoft Report Viewer Redistributable 2005. You can download it from here. Also, if you have installed .NET Framework 3.5, you can try to change the references to the libraries from the Microsoft Report Viewer Redistributable 2008.

Introduction

Some time ago, I was looking for a solution for exporting data from a DataGridView to MS Excel. I tried a well-known method by using the Microsoft.Office.Interop.Excel.Application class, but the application was too slow. So, I tried to find another method.

While working with SQL Server 2005 Reporting Services, I found out that the component ReportViewer can export report data to a native XLS file. When I took a closer look at the Report Definition Language Specification, the idea of creating a library for programmatically generating an RDLC-file occured. The resulting RDLC-file should reproduce the metadata of the DataGridView control (content and layout). This RDLC-file can be loaded to the Microsoft.Reporting.WinForms.LocalReport class by using the method LoadReportDefinition, and the Render method allows to export reports to the selected format. The description of classes and examples for using this library can be found below:

ReportStyle Properties

In the demo application, I want to show you an example of exporting data of different types (System.String, System.Double, System.Byte[], System.Drawing.Image) with the custom formatting and hyperlinks. The demo uses an API for Google Image Search library of Ilan Assayag in order to get images data for displaying them in a DataGridView.

Here is the result:

For binding as a datasource, I'm using an array of GImage objects, which can be initialized by an instance of Ilan.Google.API.ImageSearch.SearchResult that contains information returned from Google Image Search for each image.

In order to change metadata (columns width, formatting, DataCellViewType, etc.) gathered in DataGridViewReportDataAdapter, or to add grouping of rows, it's necessary to create a custom ReportDataAdapter class (in this demo, it is GImageReportDataAdapter) inherited from the DataGridViewReportDataAdapter class. The DataGridViewReportDataAdapter cannot initialize the ReportDataColumn.DefaultCellStyle.Border, because the DataGridView class does not contain the information about the border of its columns.

Microsoft Reporting Services allows to group data by criteria. In order to set grouping data, it's necessary to override the GetTableGroups method of the interface IReportDataAdapter. If grouping is not needed, the function should return null.

In this demo, I used the ApplyRandomOrderToArray method for applying a random order for the GImage array. You can see the result of row data grouping by using SearchTag; also sort descending by SearchTag as in the screenshot below. The Google search query was "Paris; London; New York" and the checkbox "Use Grouping" was checked.

Report rendering can be customized by using Device Information Settings. I've written classes inherited from BaseDeviceInfoSettings for each available report rendering type. The PdfDeviceInfoSettings class (ExcelDeviceInfoSettings for exporting to Excel, and ImageDeviceInfoSettings for exporting to image) can be used for getting the DeviceInfo XML element and passing it to the method ExportToPdf(string deviceInfo) of the interface IReportExporter.

Much to my surprise MS Reporting services allows us to export reports in Excel workbook with several worksheets. It can be designed by placing one by one a few Rectangle controls in the main report and placing in each Rectangle control one Subreport control. In this case we can create an Excel workbook with up to 1000 worksheets. But there is a small problem in this method — on the second and further worksheets the first row is hidden (his height is equal to 1 Pixel).

In the code, in order to use the ability of adding extra worksheets to a workbook it's necessary to put List<IReportDataAdapter> (one instance of IReportDataAdapter per worksheet) in the constructor WinFormsReportExporter.

Class DataSetAdapterProvider allows you to create set of IReportDataAdapter for dataset tables. By default it creates objects of class DataViewReportDataAdapter (can be initialized by DataTable.DefaultView). Implementation of the DataViewReportDataAdapter class does not format data(columns). This task is for custom application developers.

Anton Ponomarev describes in his article, Adding DOC, RTF, and OOXML Export Formats to the Microsoft Report Viewer Control, adding a custom rendering extension to the standard Microsoft Report Viewer control. He modified the ReportViewer assemblies by using .NET tools. As a result, he got the Microsoft.ReportViewer.WinForms.Modified.dll assembly in which the Report Viewer component is able to generate reports in Microsoft Word formats (DOC, RTF, WordprocessingML, and OOXML) when it works in local mode.

I suppose if references in ReportExporters to Microsoft.ReportViewer.WinForms.dll is changed to Microsoft.ReportViewer.WinForms.Modified.dll, and the IReportExporter interface is extended, then it will be possible to export a DataGridView to DOC, RTF, WordprocessingML, and OOXML formats.

I don't have the Microsoft.ReportViewer.WinForms.Modified.dll yet. I'm going to investigate this problem soon.

Conclusion

With the ReportExporters library, you can:

Export a DataGridView/DataSet to native XLS instead of SpeedSheetXML. It is not required that MS Excel be installed.

Before anything i'd like to say that you've done a great work, this library is very very cool and ver very useful.

I'd like to implement some new improvements to it, and i'd like you to help me for doing it.

1st.- I'd like to have an AlternateRowDefaultStyle for printing the table, Where is the best site for doing it?
I've just finished the deploy of this one issue, I say to you what i've done because of if you want to add it into the original one:

2nd.- When an small image is printed in pdf format, the image is pixelated, could we fix it in any way?
3rd.- Is it possible to adjust the width of a column to it's content automatically before printing it?
4th.- When we export a report to image format, could we get the imagen adjusted to the report content automatically without having the two values indicated?

Hi!
I was checking. Nothing special is not needed. Just assign DataView to DataGridView.DataSource.
Then you should apply required style & formatting for just created DataGridViewColumns, or you can create custom ReportDataAdapterter like in sample above.

I'm using report processing in local mode, not in remote mode.So you should have only assemblies from Microsoft Report Viewer Redistributable. SQL Server 2005 Reporting Services are not used in this case.

Downloaded the code and the sample and had it working on no time. Even took the liberty to modify it to apply a simple border around each cell.

What about adding a class to take a data set and create a new worksheet in the workbook for each of the defined tables. This way you could pass in a multi-table data set and get a single workbook with all the data tables in it.

Good timing on the post. I ran into this requirement today and your solution appears to be the slickest one out there. No requirement for having excel installed on the machine is nice. I for one don't really care for having to create the Excel application object just to write out a file. You would think MS would have this ability built in to some of its objects.