Sign in Join
Wiki copytemporary

FPReport: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-## Contents
2-
3- * 1 Architecture
4- * 2 units
5- * 3 Report structure
6- * 4 Types of bands
7- * 4.1 DataBand
8- * 4.2 Report title and Summary
9- * 4.3 Page Header and Footer
10- * 4.4 Data Header and Footer
11- * 4.5 Group Header and Footer
12- * 4.6 Column Header and Footer
13- * 4.7 Child band
14- * 5 Printable elements
15- * 6 Data loops
16- * 6.1 Data loop structure
17- * 6.2 User data loop
18- * 6.3 DB Data loop
19- * 6.4 Collection Data loop
20- * 6.5 ObjectList Data loop
21- * 6.6 JSON Data loop
22- * 7 Loading and Saving to file
23- * 8 Data management
24- * 9 More Info
25- * 9.1 FAQ
26-
271## Architecture
282
29-FPReport is a banded reporting tool.
3+FPReport is a banded reporting tool.
304
31-It was designed from zero, to be able to run on a headless webserver, with minimal dependencies. An important use-case was a Linux server running in a container without X libraries installed. Creating a report is just placing squares with contents on a page, usually based on a data loop. This can be done entirely in-memory, and does not need a display or GUI.
5+It was designed from zero, to be able to run on a headless webserver, with minimal dependencies. An important use-case was a Linux server running in a container without X libraries installed. Creating a report is just placing squares with contents on a page, usually based on a data loop. This can be done entirely in-memory, and does not need a display or GUI.
326
33-Reports can be created entirely in code, or they can be read from a definition file. The default shipped file uses [[JSON]] as the format to store the report definition. The reports can also be designed visually, using a designer. A stand-alone designer exists, as well as the possibility to design a report within the Lazarus IDE.
7+Reports can be created entirely in code, or they can be read from a definition file. The default shipped file uses [[JSON]] as the format to store the report definition. The reports can also be designed visually, using a designer. A stand-alone designer exists, as well as the possibility to design a report within the Lazarus IDE.
348
35-Once the report is created, it can be saved to disk, or rendered. Rendering is the act of creating visual output.
9+Once the report is created, it can be saved to disk, or rendered. Rendering is the act of creating visual output.
3610
37-Various renderers have been implemented:
11+Various renderers have been implemented:
3812
39- * To [[PDF]]. The PDF renderer is the renderer of choice
40- * To a series of images. The FPImage renderer creates a bitmap per page, and the bitmaps can be saved in a directory in any of the supported FPImage formats.
41- * To HTML: each page is rendered as a HTML page using appropriate CSS markup.
13+- To [[PDF]]. The PDF renderer is the renderer of choice
14+- To a series of images. The FPImage renderer creates a bitmap per page, and the bitmaps can be saved in a directory in any of the supported FPImage formats.
15+- To HTML: each page is rendered as a HTML page using appropriate CSS markup.
4216
43- Parts that cannot be rendered as HTML and CSS will be rendered as an image and placed in the HTML page.
17+
18+Parts that cannot be rendered as HTML and CSS will be rendered as an image and placed in the HTML page.
4419
45- * To the LCL (a canvas).
20+- To the LCL (a canvas).
4621
47- This is in fact the basis of the preview, the designer and the printing support.
22+
23+This is in fact the basis of the preview, the designer and the printing support.
4824
49- * To an AggPas canvas. AggPas is a powerful graphics library, and this renderer is similar in scope to the FPImage renderer
50- * To fpGUI - this can be used to preview the report in a FPGUI report
25+- To an AggPas canvas. AggPas is a powerful graphics library, and this renderer is similar in scope to the FPImage renderer
26+- To fpGUI - this can be used to preview the report in a FPGUI report
5127
5228## units
5329
54-fpreport
55- To create a report in code, this unit is all that is necessary.
56- It contains the basic report, page, bands and elements.
57-fpreportstreamer
58- This unit contains the streamer, which reads/writes a report definition from/to file.
59-fpjsonreport
60- This unit contains a report class that can be dropped on a Lazarus form/Datamodule:
61- the report definition will be written to the form file.
62-fpreportdb
63- This unit contains the data loop component **TFPReportDatasetData** , which bases the loop on data from a dataset.
64-fpreportpdfexport
65- This unit contains the PDF exporter **TFPReportExportPDF**.
66- An instance of this class can be used to export a report to PDF.
67-fpreporthtmlexport
68- This unit contains the HTML exporter **TFPReportExportHTML**.
69- An instance of this class can be used to export a report to HTML pages.
70-fpreportfpimageexport
71- This unit contains the image exporter **TFPReportExportfpImage**.
72- An instance of this class can be used to export a report to any supported image format.
30+fpreport
31+To create a report in code, this unit is all that is necessary.
7332
33+It contains the basic report, page, bands and elements.
34+
35+fpreportstreamer
36+This unit contains the streamer, which reads/writes a report definition from/to file.
37+
38+fpjsonreport
39+This unit contains a report class that can be dropped on a Lazarus form/Datamodule:
40+
41+the report definition will be written to the form file.
42+
43+fpreportdb
44+This unit contains the data loop component **TFPReportDatasetData** , which bases the loop on data from a dataset.
45+
46+fpreportpdfexport
47+This unit contains the PDF exporter **TFPReportExportPDF**.
48+
49+An instance of this class can be used to export a report to PDF.
50+
51+fpreporthtmlexport
52+This unit contains the HTML exporter **TFPReportExportHTML**.
53+
54+An instance of this class can be used to export a report to HTML pages.
55+
56+fpreportfpimageexport
57+This unit contains the image exporter **TFPReportExportfpImage**.
58+
59+An instance of this class can be used to export a report to any supported image format.
60+
7461## Report structure
7562
76-A report is an instance of the **TFPReport** class. It consists of one or multiple pages, each page is an instance of **TFPReportCustomPage**. The instances are available in the **Pages** array property of the report class. The number of pages is reported in the **PageCount** property.
63+A report is an instance of the **TFPReport** class. It consists of one or multiple pages, each page is an instance of **TFPReportCustomPage**. The instances are available in the **Pages** array property of the report class. The number of pages is reported in the **PageCount** property.
7764
78-When the report is rendered, first the first page will be rendered (according to its data loop), then the second page will be rendered, and so on.
65+When the report is rendered, first the first page will be rendered (according to its data loop), then the second page will be rendered, and so on.
7966
80-Each page can consist of one or more bands. Some bands will appear only once in the output, others on regular places, but most bands will appear an arbitrary number of times, depending on the data which is given to the report. Typically there will be a data band which is printed once for each record in the data loop.
67+Each page can consist of one or more bands. Some bands will appear only once in the output, others on regular places, but most bands will appear an arbitrary number of times, depending on the data which is given to the report. Typically there will be a data band which is printed once for each record in the data loop.
8168
82-Every band contains one or more elements (a descendent of **TFPReportElement**).
69+Every band contains one or more elements (a descendent of **TFPReportElement**).
8370
84-Every time when the band is printed, all the elements on the band are printed. There are several types of element. The basic ones are
71+Every time when the band is printed, all the elements on the band are printed. There are several types of element. The basic ones are
8572
86- * A Memo. This is a text element which prints a text.
73+- A Memo. This is a text element which prints a text.
8774
88- The text can contain placeholders, which will be calculated every time the memo is printed.
75+
76+The text can contain placeholders, which will be calculated every time the memo is printed.
8977
90- * A checkbox. This is a graphical element, which prints a checkbox (checked or not)
91- * A image. This is a graphical element, which prints an image.
92- * A shape. This is an element which can print one of a series of geometrical shapes.
78+- A checkbox. This is a graphical element, which prints a checkbox (checked or not)
79+- A image. This is a graphical element, which prints an image.
80+- A shape. This is an element which can print one of a series of geometrical shapes.
9381
94-The elements share some common features, such as the ability to draw a frame around it, and to have a background color.
82+The elements share some common features, such as the ability to draw a frame around it, and to have a background color.
9583
9684## Types of bands
9785
98-FPReport has various types of bands. Each band has its own purpose. Some bands can appear only once in the definition of a report, other bands can appear multiple times.
86+FPReport has various types of bands. Each band has its own purpose. Some bands can appear only once in the definition of a report, other bands can appear multiple times.
9987
10088### DataBand
10189
102-This is the band (class **TFPReportDataBand**) that will be printed once for each record in the report data loop. Multiple data bands can be put in a report, if they are linked in a master-detail relation.
90+This is the band (class **TFPReportDataBand**) that will be printed once for each record in the report data loop. Multiple data bands can be put in a report, if they are linked in a master-detail relation.
10391
10492### Report title and Summary
10593
106-A report title (**TFPReportTitleBand**) and summary (**TFPReportSummaryBand**) can appear once on each page of the report. The are printed once: when the report rendering is started, and when the rendering ends.
94+A report title (**TFPReportTitleBand**) and summary (**TFPReportSummaryBand**) can appear once on each page of the report. The are printed once: when the report rendering is started, and when the rendering ends.
10795
10896### Page Header and Footer
10997
110-A Page Header (**TFPReportPageHeaderBand**) and footer (**TFPReportPageFooterBand**) are printed at the top and bottom of each page. This kind of band can be added once per page. There are options to skip printing the header on the first page, and the footer on the last page.
98+A Page Header (**TFPReportPageHeaderBand**) and footer (**TFPReportPageFooterBand**) are printed at the top and bottom of each page. This kind of band can be added once per page. There are options to skip printing the header on the first page, and the footer on the last page.
11199
112100### Data Header and Footer
113101
114-The data header (**TFPReportDataHeaderBand**) and footer (**TFPReportDataFooterBand**) are printed when a data loop starts, and ends. If a report contains multiple pages and uses multiple loops, then the report summary and title are printed only once, but the data header and summary are printed for every loop. This band can be added once for each data loop on the report.
102+The data header (**TFPReportDataHeaderBand**) and footer (**TFPReportDataFooterBand**) are printed when a data loop starts, and ends. If a report contains multiple pages and uses multiple loops, then the report summary and title are printed only once, but the data header and summary are printed for every loop. This band can be added once for each data loop on the report.
115103
116104### Group Header and Footer
117105
118-Data can be grouped based on an expression. When the value of the expression changes, a new group is started. A group is defined by placing a group header band (**TFPReportGroupHeaderBand**) on a page. Totals of a group can be displayed at the end of the group using a group footer (**TFPReportGroupFooterBand**)
106+Data can be grouped based on an expression. When the value of the expression changes, a new group is started. A group is defined by placing a group header band (**TFPReportGroupHeaderBand**) on a page. Totals of a group can be displayed at the end of the group using a group footer (**TFPReportGroupFooterBand**)
119107
120-This band can be added once for each data loop on the report.
108+This band can be added once for each data loop on the report.
121109
122110### Column Header and Footer
123111
124-A report can be on multiple columns. At the head of each column (on every page), a header can be printed using the Column Header band (**TFPReportColumnHeaderBand**). At the bottom of a column (again, on every page), a column footer band (**TFPReportColumnFooterBand**) can be printed.
112+A report can be on multiple columns. At the head of each column (on every page), a header can be printed using the Column Header band (**TFPReportColumnHeaderBand**). At the bottom of a column (again, on every page), a column footer band (**TFPReportColumnFooterBand**) can be printed.
125113
126-This band can be added once for each page in the report.
114+This band can be added once for each page in the report.
127115
128116### Child band
129117
130-With the exception of Page footer and column footer bands, every band can have a child band (**TFPReportChildBand**) attached to it. This can be useful for aligning purposes, for example when a band contains memo that grows, and the band is configured to stretch, so the content of the memo is accomodated.
118+With the exception of Page footer and column footer bands, every band can have a child band (**TFPReportChildBand**) attached to it. This can be useful for aligning purposes, for example when a band contains memo that grows, and the band is configured to stretch, so the content of the memo is accomodated.
131119
132-This band can be placed an arbitrary number of times on the report.
120+This band can be placed an arbitrary number of times on the report.
133121
134122## Printable elements
135123
136-On a band, you can drop one or more printable elements. A printable element is one of the following:
124+On a band, you can drop one or more printable elements. A printable element is one of the following:
137125
138- * a Memo. This is a text element. The text can contain formulas, and a limited set of HTML tags, such as bold, italic, underline and font or anchor tags.
126+- a Memo. This is a text element. The text can contain formulas, and a limited set of HTML tags, such as bold, italic, underline and font or anchor tags.
139127
140-The formulas will be evaluated, and the result will be substituted in the text.
128+The formulas will be evaluated, and the result will be substituted in the text.
141129
142- * A Shape: this is one of several shapes such as a circle, square, triangle or straight lines in various orientations.
143- * An image: You can embed any image in your report. All image formats as supported by FPC fcl-image can be used.
144- * A checkbox. This is a special case of the image component: it uses 2 images, one for true, the other for false values.
130+- A Shape: this is one of several shapes such as a circle, square, triangle or straight lines in various orientations.
131+- An image: You can embed any image in your report. All image formats as supported by FPC fcl-image can be used.
132+- A checkbox. This is a special case of the image component: it uses 2 images, one for true, the other for false values.
145133
146-Which one is used depends on the value of an expression which is evaluated every time the checkbox is printed.
134+Which one is used depends on the value of an expression which is evaluated every time the checkbox is printed.
147135
148- * A Barcode element. This element is in a separate unit (fpreportbarcode) and can be used to draw one of many types of barcode.
149- * a QRcode element. This element is in a separate unit (fpreportqrcode) and can be used to draw a QR code. It has some properties to determine the kind of barcode and how to position it.
136+- A Barcode element. This element is in a separate unit (fpreportbarcode) and can be used to draw one of many types of barcode.
137+- a QRcode element. This element is in a separate unit (fpreportqrcode) and can be used to draw a QR code. It has some properties to determine the kind of barcode and how to position it.
150138
151139## Data loops
152140
153-The data loop is a basic concept in the report. It can be thought of as an abstraction of an array of records: the data band will be printed for each "record" in the "array". The "fields" of each record are available to be used in an expression, and when an expression is evaluated which contains a field, then the value of the field for the current record will be used in the expression.
141+The data loop is a basic concept in the report. It can be thought of as an abstraction of an array of records: the data band will be printed for each "record" in the "array". The "fields" of each record are available to be used in an expression, and when an expression is evaluated which contains a field, then the value of the field for the current record will be used in the expression.
154142
155-Clearly, the data loop determines the number of pages in a rendered report.
143+Clearly, the data loop determines the number of pages in a rendered report.
156144
157-Currently, 5 kinds of data loop are available:
145+Currently, 5 kinds of data loop are available:
158146
159- * A user data loop.
147+- A user data loop.
160148
161- This loop is entirely event driven, and the various events are used to fetch the data.
149+
150+This loop is entirely event driven, and the various events are used to fetch the data.
162151
163- * A DB data loop.
152+- A DB data loop.
164153
165- This loop is driven by a data set: the record is 1 record in the data set, the 'fields' in the record are the fields in the dataset.
154+
155+This loop is driven by a data set: the record is 1 record in the data set, the 'fields' in the record are the fields in the dataset.
166156
167- * A TFPObjectList based loop.
157+- A TFPObjectList based loop.
168158
169- This uses RTTI of the objects to expose the data in the loop.
159+
160+This uses RTTI of the objects to expose the data in the loop.
170161
171- * A TCollection based loop.
162+- A TCollection based loop.
172163
173- Similar to the TFPObjectList loop, this uses RTTI of the objects to expose the data in the loop.
164+
165+Similar to the TFPObjectList loop, this uses RTTI of the objects to expose the data in the loop.
174166
175- * A JSON array/Object based loop.
167+- A JSON array/Object based loop.
176168
177- This takes a JSON array (or object) and will loop over the elements in the array.
169+
170+This takes a JSON array (or object) and will loop over the elements in the array.
178171
179172### Data loop structure
180173
181-Data loops appear on several levels, they determine the structure of the report.
174+Data loops appear on several levels, they determine the structure of the report.
182175
183- * The page can have a data loop.
184- * The main (master) data band. Only one such band can exist on the page.
176+- The page can have a data loop.
177+- The main (master) data band. Only one such band can exist on the page.
185178
186- This is the main data loop for the page.
179+
180+This is the main data loop for the page.
187181
188- * Detail data bands.
182+- Detail data bands.
189183
190- The loop of these bands are run every time the master data band of the detail data bands is printed.
191- Detail data bands can be nested, a detail data band can be the master of another detail data band.
184+
185+The loop of these bands are run every time the master data band of the detail data bands is printed.
192186
193-Per page in the report, the engine will determine the main data loop for that page.
187+Detail data bands can be nested, a detail data band can be the master of another detail data band.
194188
195-This is the first data band's data loop, if the data band has no master. This will be used to start rendering the bands on that page.
189+Per page in the report, the engine will determine the main data loop for that page.
196190
197-Usually, Page.Data will be Nil.
191+This is the first data band's data loop, if the data band has no master. This will be used to start rendering the bands on that page.
198192
199-But, if it is set, and it is different from the main data loop on the page, the complete page (and any loops on it) is rendered for each record in the page.data loop.
193+Usually, Page.Data will be Nil.
200194
201-If the main data loop equals the page data loop, the logic is as if the Page.Data is Nil (for backwards compatibility).
195+But, if it is set, and it is different from the main data loop on the page, the complete page (and any loops on it) is rendered for each record in the page.data loop.
202196
203-For each band that has sub-bands, the engine will run a a similar loop over sub-bands.
197+If the main data loop equals the page data loop, the logic is as if the Page.Data is Nil (for backwards compatibility).
204198
199+For each band that has sub-bands, the engine will run a a similar loop over sub-bands.
200+
205201### User data loop
206202
207-The user data loop is entirely event driven, and should be usable for any kind of data. The user is expected to implement several event handlers for the dataloop to implement its functionality.
203+The user data loop is entirely event driven, and should be usable for any kind of data. The user is expected to implement several event handlers for the dataloop to implement its functionality.
208204
209-OnOpen
210- Called when the data loop is 'opened'.
211- This can be used to set up the actual data.
212-OnFirst
213- Called when the reporting engine needs to position the data loop on the first record.
214-OnGetValue
215- Called when the reporting engine needs to get a value of a field.
216-OnGetNames
217- Called before opening the data loop, it is used to retrieve the list of fields in the data loop
218-OnNext
219- Called to signal that the data loop should go to the next record
220-OnGetEOF
221- Called to see if there are any more records in the data loop.
222-OnClose
223- Called when the report is finished, and the data loop is no longer needed.
205+OnOpen
206+Called when the data loop is 'opened'.
224207
208+This can be used to set up the actual data.
209+
210+OnFirst
211+Called when the reporting engine needs to position the data loop on the first record.
212+
213+OnGetValue
214+Called when the reporting engine needs to get a value of a field.
215+
216+OnGetNames
217+Called before opening the data loop, it is used to retrieve the list of fields in the data loop
218+
219+OnNext
220+Called to signal that the data loop should go to the next record
221+
222+OnGetEOF
223+Called to see if there are any more records in the data loop.
224+
225+OnClose
226+Called when the report is finished, and the data loop is no longer needed.
227+
225228### DB Data loop
226229
227-The dataset data loop (**TFPReportDatasetData** , unit _fpreportdb_) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback. The dataset data loop manages all data by itself. It will open the dataset or navigate through the dataset as the reporting engine calls the various methods.
230+The dataset data loop (**TFPReportDatasetData**, unit *fpreportdb*) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback. The dataset data loop manages all data by itself. It will open the dataset or navigate through the dataset as the reporting engine calls the various methods.
228231
229232### Collection Data loop
230233
231-Similar to the DB Data loop, the collection data loop (**TFPReportCollectionData** , unit _fpreportcontnr_) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback. The collection data loop loops over the items in a collection. It exposes the published properties of the collection items as fields.
234+Similar to the DB Data loop, the collection data loop (**TFPReportCollectionData**, unit *fpreportcontnr*) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback. The collection data loop loops over the items in a collection. It exposes the published properties of the collection items as fields.
232235
233236### ObjectList Data loop
234237
235-Similar to the collection data loop, the objectlist data loop (**TFPReportObjectListData** , unit _fpreportcontnr_) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback.
238+Similar to the collection data loop, the objectlist data loop (**TFPReportObjectListData**, unit *fpreportcontnr*) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback.
236239
237-The object list data loop loops over the items in an object list.
240+The object list data loop loops over the items in an object list.
238241
239-It exposes the published properties of the list items as fields. It assumes all the objects in the list are if the same class, and uses the first object in the list to determine the fields.
242+It exposes the published properties of the list items as fields. It assumes all the objects in the list are if the same class, and uses the first object in the list to determine the fields.
240243
241244### JSON Data loop
242245
243-Similar to the collection data loop, the JSON data loop (**TFPReportJSONData** , unit _fpreportjson_) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback.
246+Similar to the collection data loop, the JSON data loop (**TFPReportJSONData**, unit *fpreportjson*) has some of the events of the user data loop, but in difference with the user data loop, the events are purely for the user to get feedback.
244247
245-The JSON data loop loops over the items in a JSON Array or object.
248+The JSON data loop loops over the items in a JSON Array or object.
246249
247-It exposes the properties of the first item in the array (or object) as fields. If the first item in the array is again an array, then Column1 to ColumnN are used as field names
250+It exposes the properties of the first item in the array (or object) as fields. If the first item in the array is again an array, then Column1 to ColumnN are used as field names
248251
249-It assumes all the objects/arrays in the list are identical in structure.
252+It assumes all the objects/arrays in the list are identical in structure.
250253
251-The array can be nested inside a complex object: the Path property can be used to point the JSON Data loop to the correct location of the array (or object)
254+The array can be nested inside a complex object: the Path property can be used to point the JSON Data loop to the correct location of the array (or object)
252255
253256## Loading and Saving to file
254257
255-By itself, TFPReport has no concept of file formats.
256-
257-It only knows a streamer class. For this reason, it has no LoadFromFile/SaveToFile methods. The only currently supported streamer class is **TFPReportJSONStreamer** , which can be used to save and load a report design to/from file.
258+By itself, TFPReport has no concept of file formats.
258259
259-The [[FPReport Usage]] page explains how to load a report from file.
260+It only knows a streamer class. For this reason, it has no LoadFromFile/SaveToFile methods. The only currently supported streamer class is **TFPReportJSONStreamer**, which can be used to save and load a report design to/from file.
260261
261-For the same reason, a TFPReport cannot be used to store information in a lazarus .lfm file.
262+The [[FPReport Usage]] page explains how to load a report from file.
262263
263-The **TFPJSONReport** class (unit **fpjsonreport**) descends from **TFPReport** , and combines it with the JSON streamer. If you want to be able to automatically load a design from file, or store it in the lazarus .dfm file, you are better off using this class.
264+For the same reason, a TFPReport cannot be used to store information in a lazarus .lfm file.
264265
265-
266+The **TFPJSONReport** class (unit **fpjsonreport**) descends from **TFPReport**, and combines it with the JSON streamer. If you want to be able to automatically load a design from file, or store it in the lazarus .dfm file, you are better off using this class.
266267
267268## Data management
268269
269-By itself the TFPReport component does not have knowledge of datasets. It only knows an abstract data loop.
270+By itself the TFPReport component does not have knowledge of datasets. It only knows an abstract data loop.
270271
271-If you design a report using the report designer, the stand-alone designer writes data definitions to the JSON it creates. However, the report itself ignores this information, and no datasets or other data loops will be created.
272+If you design a report using the report designer, the stand-alone designer writes data definitions to the JSON it creates. However, the report itself ignores this information, and no datasets or other data loops will be created.
272273
273-In order to load and use the information about data in the report design, you can use a **TFPReportDataManager** component.
274+In order to load and use the information about data in the report design, you can use a **TFPReportDataManager** component.
274275
275-Just point the **FPJSONReport** instance's _DataManager_ property to the instance of the **TFPReportDataManager** component, and it will instantiate the necessary datasets, and couple them to the report.
276+Just point the **FPJSONReport** instance's *DataManager* property to the instance of the **TFPReportDataManager** component, and it will instantiate the necessary datasets, and couple them to the report.
276277
277-The [[FPReport Usage]] page explains how to do this.
278+The [[FPReport Usage]] page explains how to do this.
278279
279280## More Info
280281
281- * The [[FPReport Usage]] page explains how to create a basic report.
282- * The [[FPReport Designer]] page explains how to use the stand-alone report designer.
283- * The [[FPReport Custom elements]] page explains how to create custom elements for the reporting engine
284- * The [[FPReport Lazarus support]] page gives an overview of how FPReport can be used in Lazarus.
282+- The [[FPReport Usage]] page explains how to create a basic report.
283+- The [[FPReport Designer]] page explains how to use the stand-alone report designer.
284+- The [[FPReport Custom elements]] page explains how to create custom elements for the reporting engine
285+- The [[FPReport Lazarus support]] page gives an overview of how FPReport can be used in Lazarus.
285286
286287### FAQ
287288
288-See the FAQ -> [[FPReport FAQ]]
289+See the FAQ -\> [[FPReport FAQ]]
289290
290291---
291-*From the Free Pascal wiki, page "FPReport", as the Internet Archive kept it on 2022-12-30. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
292+*From the Free Pascal wiki, page "FPReport", as it stood on 2020-01-06 after a change by PascalR, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history