[Lazarus] Flexible exporter for grid-like components

Werner Pamler werner.pamler at freenet.de
Fri May 6 19:06:30 CEST 2016


Am 01.05.2016 um 21:34 schrieb Werner Pamler:
>
> TStringGrid provides the methods SaveToCSVFile/Stream for saving the 
> grid content to a csv file or stream. This is very convenient for 
> users, but it is not very flexible: The export works only for the csv 
> data format, no html, no possibility to plug in other formats. It 
> requires always a modification of the /grids /unit to extend these 
> methods by additional options. And it works only with TStringGrid - 
> there are other grid-like controls, such as custom "virtual" grids 
> derived from TCustomDrawGrid, TListview in report mode, TKGrid and 
> other third-party grids which are not supported: if they do not have 
> such a method on their own the export code has to be re-written 
> (often: duplicated).
>
> The attached file contains code for a flexibile export system for 
> 2D-data classes which is open and can easily be extended to other 
> formats and other controls. It essentially consists of two parts:
>
>   * *TLazExporter *represents the file format. The class is abstract
>     and provides the methods to write cells and rows to stream and
>     file. I implemented an exporter for *csv *and *html *files for the
>     lclbase package. But in addition there is also a dedicated
>     SpreadsheetExporter which takes care of *Excel *and/or
>     *Opendocument *file formats (using fpspreadsheet).
>   * *TLazExporterLink *provides the data to be exported. It is an
>     abstract class between the control to be exported and the writer.
>     It exposes methods to navigate from cell to cell and row to row,
>     and to define the strings assigned to each cell. I implemented a
>     TGridExporterLink (accessing *TCustomStringGrid*, in the long run:
>     *TCustomDrawGrid*) and *TCustomListView*. The same principle works
>     for any other classes with 2D data arrays (matrix).
>
> The unit /GridExporter /exposes functions to write grid content to 
> file and to stream. The exporter instance is passed as a parameter, 
> i.e. it is very easy to switch from csv to hml or any other format 
> provided the corresponding exporter is available.
>
>          procedure ExportGridToFile(AGrid: TCustomStringGrid; 
> AExporter: TLazExporter; const AFileName: String; AOptions: 
> TGridExportOptions); overload;
>          procedure ExportGridToStream(AGrid: TCustomStringGrid; 
> AExporter: TLazExporter; AStream: TStream; AOptions: 
> TGridExportOptions); overload;
>
> Similarly, there are also ExportListviewToFile/Stream procedures in 
> the unit /ListViewExporter /for the export from a TListview.
>
> Properties of the exporter can be used to fine-tune the export. In 
> case of the html exporter, for example, a set of css statements can be 
> specified to format the exported html table:
>
>          htmlexporter := THTMLExporter.Create;
>          with htmlexporter do
>          begin
>            CSS.Add('table { border: 1px solid #DDDDFF; }');
>            CSS.Add('th { background-color: #DDDDFF; }');
>            CSS.Add('h1 { font-family:Helvetica, Arial, sans-serif; 
> font-size:16pt; color:blue; background-color: #EEEEFF}; }');
>         end;
>         ExportGridToFile(StringGrid1, exporter, AFileNameForGrid, 
> [geoFixedRows, geoFixedCols, geoVisibleColsOnly]);
>         ExportListViewToFile(Listview1, exporter, 
> AFileNameForListView, [leoTitles, leoVisibleColsOnly]);
>
> In addition to these procedures there are overloaded versions taking 
> the exporter class (instead of an exporter instance) as a parameter. 
> In this way the default exporter parameters are applied during the 
> export. Of course, these procedures can be added as methods to the 
> classes referred to by the first parameter.
>
> The attached demo shows the exporter system at work. It requires no 
> modification of any LCL packages or units. In the long run, however, 
> I'd propose to add unit /LazExporter /to package /LazUtils /and 
> /GridExporter /and /ListviewExporter /to package /LclBase 
> /(/SpreadsheetExporter /would go to /laz_//fpspreadsheet/), and to 
> make these modifications to the /grids /unit:
>
>   * Extend the ExportGridToFile/Stream procedures to accept also
>     TCustomDrawGrid descendants. This would be possible by introducing
>     a virtual method GetCellText(Col,Row) to TCustomDrawGrid (or maybe
>     even TCustomGrid) which would catch the cell text from a special
>     event OnGetCellText; this would help to create "virtual" grids
>     using TCustom(Draw)Grids. In case of the TStringGrid, of course,
>     GetCellText would simply return the cell strings Cells[Col, Row].
>   * Replace the code in SaveToCSVFile/Stream by the csv exporter. I'd
>     also vote to deprecate these methods because they are special
>     cases of the csv exporter.
>   * Replace the copy-to-clipboard code (CopyCellRectToClipboard) by
>     the csv exporter. In addition, a html format could be written to
>     the clipboard with almost no extra code.
>
> I would greatly appreciate any comments.
>
In preparing a patch for a Mantis feature request I came across this 
issue: fpc does already contain a series of exporters 
(packages/fcl-db/export, component palette "Data Export"), among them a 
TCSVExporter, TSimpleXMLExporter etc. Since they focus on database 
export there is no overlap with the new exporters primarily. But they 
make things a lot more complicated...

The easiest way would be to stay with the "two exporter" solution, one 
set for database, the other one for non-database export. The new 
exporters could be renamed to contain a prefix "Laz" in their name, or 
"Text", or "NonDB", or similar.

On the other hand, it should be possible to generalize the fcl exporters 
such that they support also non-database sources. This would avoid a lot 
of code duplication, and it would present a clearer class hierarchy for 
data export to the user. BUT: A lot of refactoring of the corresponding 
fcl code is involved in this solution. Therefore, since Lazarus will 
support the last pre-3.0 version of fpc for a long time, this solution 
will not be available in a Lazaraus released version for the next couple 
of years...

What's your opinion out there?


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20160506/ad800416/attachment-0003.html>


More information about the Lazarus mailing list