[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