Recent

Author Topic: Alternative to Lazarus Report  (Read 26949 times)

Graeme

  • Hero Member
  • *****
  • Posts: 1430
    • Graeme on the web
Re: Alternative to Lazarus Report
« Reply #15 on: August 12, 2014, 11:14:10 pm »
I have not touch lazreport for now but I may have take a look.  The reason of my post is that I am curious how you manage your reporting via code. Can you at least provide a sample code for us to have a reference?
No problem. I'll put a demo together over the weekend so you can see. I'll post here where to find it.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Graeme

  • Hero Member
  • *****
  • Posts: 1430
    • Graeme on the web
Re: Alternative to Lazarus Report
« Reply #16 on: October 09, 2015, 01:25:51 pm »
I have not touch lazreport for now but I may have take a look.  The reason of my post is that I am curious how you manage your reporting via code. Can you at least provide a sample code for us to have a reference?
Very sorry for the late reply... I completely forgot about this.

As I mentioned, I use fpGUI's PDF engine to do reporting, and I generate all my reports from code - thus I find them much more maintainable, searchable and more flexible in design. Here is a very simple listing report example. I have a lot more complex ones too, but I chose a simple one simply as an easy example.

My software is very Object Oriented - I don't use TDataSet and DB-aware components, everything is driven by Objects. I use tiOPF has my backend framework for loading and persisting objects to/from any database or data file. So my reporting is no different. I tend to create a "Report Data Object" which I can set the report parameters (eg: To/From date etc), then do a Read() which will load it up with all the data I need for my report.

Note:
tiOPF does supply a TDataset compatible class though, so you can hook up tiOPF based objects to TDataset driven code like DB-aware components, existing reporting tools etc. I don't do this though.

Here is the code for one such listing report:
Code: Pascal  [Select]
  1. procedure TEnrolmentListReportForm.Process_PDF_Report;
  2. var
  3.   rpt: TRptEnrolmentList;  // report object
  4.   lReport: T_Report;
  5.   itm: TRptEnrolmentItem;  // report repeatable data items
  6.   FtTitle: Integer;
  7.   FtText: Integer;
  8.   FtTextB: Integer;
  9.   lLineStyle: Integer;
  10.   LsTitle: Integer;
  11.   LsText: Integer;
  12.   Col: array[1..5] of Integer;  // this report is column based
  13.   lDataCount,lCol: Integer;
  14.   v: single;
  15.   s: string;
  16.   lCount: integer;
  17.   lAlignment: shortint;
  18.  
  19. const
  20.   cCentreAddressX = 120;
  21.  
  22.   procedure WritePageHeader;
  23.   begin
  24.     with lReport do
  25.     begin
  26.       // write title on each page
  27.       WriteHeader(cnLeft,lnEnd,'Enrolment List',ColDefaut,FtTitle,LsTitle);
  28.       // write page number and total of pages on each page
  29.       NumPageSectionFooter(cnRight,lnEnd,'Page','of',True,False, ColDefaut,FtText,LsText);
  30.     end;
  31.   end;
  32.  
  33.   procedure WriteAddress(const ACentre: TCentre);
  34.   begin
  35.     with lReport do
  36.     begin
  37.       // Centre address lines
  38.       WritePage(cnLeft,lnEnd,ACentre.Caption,Col[5],FtTextB,LsText);
  39.       // leave some whitespace
  40.       WritePage(cnLeft,lnEnd,' ',Col[1],FtText,LsText);
  41.       WritePage(cnLeft,lnEnd,' ',Col[1],FtText,LsText);
  42.     end;
  43.   end;
  44.  
  45.   procedure WriteColumnHeaders;
  46.   begin
  47.     with lReport do
  48.     begin
  49.       // Report filter details
  50.       WritePage(cnLeft,lnCurrent,Format('For Period: %s to %s', [FormatDateTime('yyyy-mm-dd', calStartDate.DateValue), FormatDateTime('yyyy-mm-dd', calEndDate.DateValue)]),ColDefaut,FtText,LsText);
  51.       WritePage(cnRight,lnEnd,'Date: ' + FormatDateTime('yyyy-mm-dd', Now),ColDefaut,FtText,LsText);
  52.       // Column headers
  53.       HorizLinePage(0,0,0,lLineStyle);
  54.       WritePage(cnLeft,lnCurrent,'Acc No.',Col[1],FtTextB,LsText);
  55.       WritePage(cnLeft,lnCurrent,'Billing Name',Col[2],FtTextB,LsText);
  56.       WritePage(cnLeft,lnCurrent,'Learner Name',Col[3],FtTextB,LsText);
  57.       WritePage(cnRight,lnEnd,'Effective Date',Col[4],FtTextB,LsText);
  58.       HorizLinePage(1,1,0,lLineStyle);
  59.     end;
  60.   end;
  61.  
  62. begin
  63.   tiProcessing(uiProcessing);
  64.   gM2Admin.TransTypeList.Read;
  65.   rpt := TRptEnrolmentList.Create;
  66.   try
  67.     // Set parameters and read report data
  68.     rpt.StartDate := calStartDate.DateValue;
  69.     rpt.EndDate := calEndDate.DateValue;
  70.     rpt.Centre := gM2Application.CurrentCentre;
  71.     rpt.Read;
  72.     if rpt.Count = 0 then
  73.     begin
  74.       tiEndProcessing;
  75.       tiAppMessage(uiErrNoDataExistsForReport);
  76.       Exit; //==>
  77.     end;
  78.  
  79.     lReport:= T_Report.Create;
  80.     try
  81.       with lReport do
  82.       begin
  83.         DefaultFile:= 'Enrolment_List.pdf';
  84.         // define orientation, page format, measurement unit, language, preview (true) or print (false)
  85.         BeginWrite(oPortrait,A4,msMM,'E',True);
  86.         // create the fonts to be used (use one of the 14 Adobe PDF standard fonts)
  87.         FtTitle := Font('helvetica-15:bold',clBlack);
  88.         FtText  := Font('helvetica-7',clBlack);
  89.         FtTextB := Font('helvetica-7:bold',clBlack);
  90.         // create columns to be used
  91.         Col[1]:= Column(10,23,0);  // Acc No
  92.         Col[2]:= Column(35,38,0);  // Billing Name
  93.         Col[3]:= Column(75,76,0);  // Learner
  94.         Col[4]:= Column(155,30,0);  // Effective Date
  95.  
  96.         Col[5]:= Column(cCentreAddressX,70,0);  // Centre Address
  97.  
  98.         // create a new section and define the margins with an additional one due to frames drawing
  99.         Section(10,10,10,10);
  100.  
  101.         // create the style of lines to be used
  102.         lLineStyle:= LineStyle(0.5,clBlack,lsSolid);
  103.         // create line spacings to be used
  104.         LsTitle := LineSpace(3,0,3);
  105.         LsText := LineSpace(1,0,0);
  106.  
  107.         WritePageHeader;
  108.         WriteAddress(rpt.Centre);
  109.         WriteColumnHeaders;
  110.  
  111.         lCount := 0;
  112.  
  113.         // now the actual report data (repeated rows)
  114.         for lDataCount:= 0 to rpt.Count-1 do
  115.         begin
  116.           itm := TRptEnrolmentItem(rpt.Items[lDataCount]);
  117.           lCount := lCount + 1;
  118.           for lCol := 1 to 4 do
  119.           begin
  120.             if lCol = 4 then
  121.               v := lnEnd
  122.             else
  123.               v := lnCurrent;
  124.             s := '';
  125.             lAlignment := cnLeft;
  126.             case lCol of
  127.               1:  s := itm.AccountNo;
  128.               2:  s := itm.BillingName;
  129.               3:  s := itm.FirstName + ' ' + itm.LastName;
  130.               4:
  131.               begin
  132.                 s := FormatDateTime('yyyy-mm-dd', itm.EffectiveDate);
  133.                 lAlignment := cnRight;
  134.               end;
  135.             end;
  136.             WritePage(lAlignment,v,s,Col[lCol],FtText,LsText);
  137.           end;
  138.         end;
  139.         // Leave some whitespace, then write the totals
  140.         WritePage(cnLeft,lnEnd,'',Col[1],FtText,LsText);
  141.         if lCount = 1 then
  142.           WritePage(cnRight,lnEnd,IntToStr(lCount) + ' item found',ColDefaut,FtTextB,LsText)
  143.         else
  144.           WritePage(cnRight,lnEnd,IntToStr(lCount) + ' items found',ColDefaut,FtTextB,LsText);
  145.  
  146.         // preparation is finished, so create PDF objects
  147.         tiEndProcessing;
  148.         EndWrite;
  149.       end;
  150.     finally
  151.       lReport.Free;
  152.     end;
  153.  
  154.   finally
  155.     rpt.Free;
  156.   end;
  157. end;
  158.  

And here is a screenshot of the generated PDF. As I said, this is a very simple report - but should get the point across.
« Last Edit: October 09, 2015, 01:33:46 pm by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/