udapp.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. unit udapp;
  2. {$mode objfpc}
  3. {$h+}
  4. {$I demos.inc}
  5. interface
  6. uses
  7. Classes, SysUtils, fpttf, fpreport,
  8. {$IFDEF ExportPDF}
  9. fpreportpdfexport,
  10. {$ENDIF}
  11. {$IFDEF ExportFPIMAGE}
  12. fpreportfpimageexport,
  13. {$ENDIF}
  14. {$IFDEF ExportHTML}
  15. fpreporthtmlexport,
  16. {$ENDIF}
  17. {$IFDEF ExportAggPas}
  18. fpreportaggpasexport,
  19. {$ENDIF}
  20. {$IFDEF ExportLCL}
  21. fpreportformexport,
  22. fpreportprinterexport,
  23. fpreportpreview,
  24. cfgfpreportpdfexport,
  25. cfgfpreportimageexport,
  26. forms,
  27. interfaces,
  28. {$ENDIF}
  29. {$IFDEF ExportFPGui}
  30. fpreport_export_form,
  31. fpg_base,
  32. fpg_main,
  33. fpg_form,
  34. {$ENDIF}
  35. custapp,
  36. fpreportstreamer;
  37. Type
  38. // Order is important for default. First available class will be used as default.
  39. TRenderFormat = (rfDefault,rfPDF,rfFPImage,rfAggPas,rfLCL,rfFPGui,rfHTML);
  40. TFPReportExporterClass = Class of TFPReportExporter;
  41. { TReportDemoApp }
  42. TReportDemoApp = class(TComponent)
  43. private
  44. Frpt: TFPReport;
  45. protected
  46. procedure InitialiseData; virtual;
  47. procedure CreateReportDesign; virtual;
  48. public
  49. Class Function Description : string; virtual;
  50. // procedure DoCreateJSON(const AFileName: String; RunTime: Boolean=False);
  51. Property rpt : TFPReport read Frpt Write FRpt;
  52. end;
  53. TReportDemoAppClass = Class of TReportDemoApp;
  54. { TReportDemoApplication }
  55. { TReportRunner }
  56. TExporterEvent = Procedure(Sender :TObject; Exporter : TFPReportExporter) of object;
  57. TReportRunner = Class (TComponent)
  58. private
  59. FBaseOutputFileName: String;
  60. FDesignFileName: String;
  61. FLocation: String;
  62. FCreateJSON: Boolean;
  63. FOnInitExporter: TExporterEvent;
  64. FReportApp : TReportDemoApp;
  65. FExporter : TFPReportExporter;
  66. FFormat : TRenderFormat;
  67. FRunFileName: String;
  68. Protected
  69. Function CreateReportExport : TFPReportExporter; virtual;
  70. procedure DoCreateJSON(const AFileName: String; RunTime: Boolean); virtual;
  71. procedure ExportReport; virtual;
  72. procedure RunReport(AFileName: string); virtual;
  73. Public
  74. destructor destroy; override;
  75. Procedure Execute;
  76. Property CreateJSON : Boolean Read FCreateJSON Write FCreateJSON;
  77. Property ReportApp : TReportDemoApp Read FReportApp Write FReportApp;
  78. Property Format : TRenderFormat Read FFormat Write FFormat;
  79. Property RunFileName : String Read FRunFileName Write FRunFileName;
  80. Property DesignFileName : String Read FDesignFileName Write FDesignFileName;
  81. Property Exporter : TFPReportExporter Read FExporter;
  82. Property Location : String Read FLocation Write FLocation;
  83. Property BaseOutputFileName : String Read FBaseOutputFileName Write FBaseOutputFileName;
  84. Property OnInitExporter : TExporterEvent Read FOnInitExporter Write FOnInitExporter;
  85. end;
  86. TReportDemoApplication = class(TCustomApplication)
  87. private
  88. FRunner: TReportRunner;
  89. procedure ListReports(AWithIndentation: boolean = False);
  90. procedure Usage(Msg: String);
  91. Class
  92. Var Reports : TStrings;
  93. Protected
  94. Property Runner : TReportRunner Read FRunner;
  95. public
  96. constructor Create(AOwner :TComponent) ; override;
  97. destructor Destroy; override;
  98. procedure DoRun; override;
  99. class function GetReportClass(AName: String): TReportDemoAppClass;
  100. Class Procedure RegisterReport(aName : String; AClasss : TReportDemoAppClass);
  101. Class Procedure GetRegisteredReports(aList : TStrings);
  102. Class function GetRenderClass(F: TRenderFormat): TFPReportExporterClass;
  103. Class Function FormatName(F : TRenderFormat) : String;
  104. end;
  105. { TReportDef }
  106. TReportDef = Class
  107. ReportClass: TReportDemoAppClass;
  108. Constructor create(AClass : TReportDemoAppClass);
  109. end;
  110. implementation
  111. class function TReportDemoApplication.FormatName(F: TRenderFormat): String;
  112. begin
  113. Str(F,Result);
  114. delete(Result,1,2);
  115. end;
  116. { TReportDemoApp }
  117. procedure TReportDemoApp.InitialiseData;
  118. begin
  119. // Do nothing
  120. end;
  121. procedure TReportDemoApp.CreateReportDesign;
  122. begin
  123. if PaperManager.PaperCount=0 then
  124. PaperManager.RegisterStandardSizes;
  125. end;
  126. class function TReportDemoApp.Description: string;
  127. begin
  128. Result:='';
  129. end;
  130. class function TReportDemoApplication.GetRenderClass(F: TRenderFormat
  131. ): TFPReportExporterClass;
  132. begin
  133. Case F of
  134. {$IFDEF ExportPDF}
  135. rfPDF: Result:=TFPReportExportPDF;
  136. {$ENDIF}
  137. {$IFDEF ExportFPIMAGE}
  138. rfFPImage: Result:=TFPReportExportFPImage;
  139. {$ENDIF}
  140. {$IFDEF ExportFPIMAGE}
  141. rfhtml: Result:=TFPReportExportHTML;
  142. {$ENDIF}
  143. {$IFDEF ExportAggPas}
  144. rfAggPas: Result:=TFPReportExportAggPas;
  145. {$ENDIF}
  146. {$IFDEF ExportLCL}
  147. rfLCL: Result:=TFPreportPreviewExport;
  148. {$ENDIF}
  149. {$IFDEF ExportFPGui}
  150. rfFPGui: Result := TFPreportPreviewExport;
  151. {$ENDIF}
  152. else
  153. Result:=Nil;
  154. end;
  155. end;
  156. function TReportRunner.CreateReportExport: TFPReportExporter;
  157. Var
  158. C, Def : TFPReportExporterClass;
  159. F : TRenderFormat;
  160. begin
  161. Result:=Nil;
  162. C:=Nil;
  163. Def:=Nil;
  164. {$IFDEF ExportLCL}
  165. def:=TFPreportPreviewExport;
  166. {$ENDIF}
  167. {$IFDEF ExportfpGUI}
  168. def:=fpreport_export_form.TFPreportPreviewExport;
  169. {$ENDIF}
  170. F:=Succ(rfDefault);
  171. While (Result=Nil) and (F<=High(TRenderFormat)) do
  172. begin
  173. C:=TReportDemoApplication.GetRenderClass(F);
  174. if (Def=Nil) and (C<>Nil) then
  175. Def:=C;
  176. if (F=FFormat) and (C<>Nil) then
  177. Result:=C.Create(Self);
  178. F:=Succ(F);
  179. end;
  180. If (Result=Nil) then
  181. begin
  182. if (FFormat=rfDefault) then
  183. begin
  184. if Def=Nil then
  185. Raise Exception.Create('No default render format available. Please check the defines in udapp.pp')
  186. else
  187. Result:=Def.Create(Self);
  188. end
  189. else
  190. Raise Exception.Create('Requested format %s not available. Please check the defines in udapp.');
  191. end;
  192. end;
  193. destructor TReportRunner.destroy;
  194. begin
  195. FreeAndNil(FReportApp);
  196. inherited destroy;
  197. end;
  198. procedure TReportRunner.Execute;
  199. begin
  200. FReportApp.InitialiseData;
  201. FReportApp.CreateReportDesign;
  202. If (DesignFileName<>'') then
  203. DoCreateJSON(DesignFileName,False);
  204. RunReport(RunFileName);
  205. ExportReport;
  206. end;
  207. constructor TReportDemoApplication.Create(AOwner : TComponent);
  208. begin
  209. Inherited;
  210. StopOnException:=True;
  211. FRunner:=TReportRunner.Create(Self);
  212. FRunner.Location:=Location;
  213. end;
  214. destructor TReportDemoApplication.Destroy;
  215. begin
  216. FreeAndNil(FRunner);
  217. FreeAndNil(Reports);
  218. inherited Destroy;
  219. end;
  220. procedure TReportRunner.RunReport(AFileName : string);
  221. begin
  222. // specify what directories should be used to find TrueType fonts
  223. gTTFontCache.SearchPath.Add(Location+'/fonts/');
  224. {$IFDEF UNIX}
  225. gTTFontCache.SearchPath.Add(GetUserDir + '.fonts/');
  226. gTTFontCache.SearchPath.Add('/usr/share/fonts/truetype/ubuntu-font-family/');
  227. gTTFontCache.SearchPath.Add('/usr/share/fonts/truetype/dejavu/');
  228. {$ENDIF}
  229. // ask to generate the font cache
  230. gTTFontCache.BuildFontCache;
  231. ReportApp.Rpt.RunReport;
  232. If (aFileName<>'') then
  233. DoCreateJSON(aFileName,True);
  234. end;
  235. Type
  236. THackFPReport = Class(TFPReport)
  237. Public
  238. Property RTObjects;
  239. end;
  240. procedure TReportRunner.DoCreateJSON(const AFileName: String; RunTime: Boolean);
  241. var
  242. F : Text;
  243. rs: TFPReportJSONStreamer;
  244. S :String;
  245. begin
  246. rs := TFPReportJSONStreamer.Create(Nil);
  247. try
  248. if RunTime then
  249. TFPReportComponent(THackFPReport(FReportApp.rpt).RTObjects[0]).WriteElement(rs)
  250. else
  251. THackFPReport(FReportApp.rpt).WriteElement(rs);
  252. S:=rs.JSON.FormatJSON;
  253. finally
  254. rs.Free;
  255. end;
  256. // Write to file
  257. AssignFile(F,AFileName);
  258. Rewrite(F);
  259. Writeln(F,S);
  260. CloseFile(F);
  261. end;
  262. procedure TReportRunner.ExportReport;
  263. begin
  264. FExporter:=CreateReportExport;
  265. try
  266. If Assigned(FOnInitExporter) then
  267. FOnInitExporter(Self,Exporter);
  268. {$IFDEF ExportLCL}
  269. If FExporter is TFPreportPreviewExport then
  270. Application.Initialize;
  271. {$ENDIF}
  272. {$IFDEF ExportFPGui}
  273. If FExporter is TFPreportPreviewExport then
  274. fpgApplication.Initialize;
  275. {$ENDIF}
  276. if (BaseOutputFileName<>'') and (FExporter.DefaultExtension<>'') then
  277. begin
  278. ForceDirectories(ExtractFilePath(BaseOutputFileName));
  279. FExporter.SetFileName(BaseOutputFileName);
  280. end;
  281. FReportApp.rpt.RenderReport(FExporter);
  282. finally
  283. FreeAndNil(FExporter);
  284. end;
  285. end;
  286. procedure TReportDemoApplication.Usage(Msg : String);
  287. var
  288. F : TRenderFormat;
  289. begin
  290. if (Msg<>'') then
  291. begin
  292. Writeln('Error : ',Msg);
  293. Writeln('');
  294. end;
  295. ExitCode:=Ord((Msg<>''));
  296. Writeln('Usage : ',ExtractFileName(ParamStr(0)),' [options]');
  297. Writeln('Where options is one of:');
  298. Writeln('-h --help This help');
  299. Writeln('-l --list List available reports.');
  300. Writeln('-j --json=file Also write report design to JSON file.');
  301. Writeln('-f --format=FMT Export format to use (use "default" for first, default format).');
  302. Writeln('-r --runtime=file Also write first page of report runtime to JSON file.');
  303. Writeln('-d --demo=<name> Run the demo specified by <name>.');
  304. Writeln('');
  305. Writeln('Known output formats for this binary: ');
  306. for F in TRenderformat do
  307. if GetRenderClass(F)<>Nil then
  308. WriteLn(' ', FormatName(F));
  309. Writeln('');
  310. Writeln('Known demos for this binary: ');
  311. ListReports(True);
  312. ExitCode:=Ord(Msg<>'')
  313. end;
  314. procedure TReportDemoApplication.ListReports(AWithIndentation: boolean);
  315. Var
  316. S : String;
  317. lIndent: string;
  318. begin
  319. if AWithIndentation then
  320. lIndent := ' ';
  321. if Assigned(Reports) then
  322. for S in reports do
  323. begin
  324. Writeln(lIndent, s);
  325. end;
  326. end;
  327. { TReportDef }
  328. constructor TReportDef.create(AClass: TReportDemoAppClass);
  329. begin
  330. ReportClass:=AClass;
  331. end;
  332. class function TReportDemoApplication.GetReportClass(AName: String
  333. ): TReportDemoAppClass;
  334. Var
  335. I : Integer;
  336. begin
  337. Result:=Nil;
  338. if Reports<>Nil then
  339. begin
  340. I:=Reports.IndexOf(AName);
  341. if I<>-1 then
  342. Result:=TReportDef(Reports.Objects[i]).ReportClass;
  343. end;
  344. if Result=Nil then
  345. Raise Exception.Create('No such demo : '+AName);
  346. end;
  347. class procedure TReportDemoApplication.RegisterReport(aName: String;
  348. AClasss: TReportDemoAppClass);
  349. begin
  350. If Reports=Nil then
  351. begin
  352. Reports:=TStringList.Create;
  353. TStringList(Reports).Duplicates:=dupError;
  354. TStringList(Reports).Sorted:=True;
  355. TStringList(Reports).OwnsObjects:=True;
  356. end;
  357. Reports.AddObject(AName,TReportDef.Create(AClasss));
  358. end;
  359. class procedure TReportDemoApplication.GetRegisteredReports(aList: TStrings);
  360. begin
  361. aList.Assign(reports);
  362. end;
  363. Var
  364. Demo : String;
  365. Function GetReportAppName : string;
  366. begin
  367. Result:='fpreportdemo';
  368. if (demo<>'') then
  369. Result:=Result+'-'+demo;
  370. end;
  371. procedure TReportDemoApplication.DoRun;
  372. Var
  373. D,F,S,J : String;
  374. Fmt : TRenderFormat;
  375. begin
  376. OnGetApplicationName:=@GetReportAppName;
  377. S:=CheckOptions('lj::hf:r:d:',['list','json::','help','format:','runtime:','demo:']);
  378. if (S<>'') or HasOption('h','help') then
  379. begin
  380. Usage(S);
  381. Terminate;
  382. exit;
  383. end;
  384. if HasOption('l','list') then
  385. begin
  386. ListReports;
  387. Terminate;
  388. exit;
  389. end;
  390. FRunner.RunFileName:=GetoptionValue('r','runtime');
  391. D:=GetOptionValue('d','demo');
  392. if (D='') then
  393. Usage('Need demo name');
  394. Demo:=D;
  395. if HasOption('j','json') then
  396. begin
  397. J:=GetOptionValue('j','json');
  398. if J='' then
  399. J:=ChangeFileExt(Paramstr(0),'.json');
  400. end;
  401. F:=GetOptionValue('f','format');
  402. Fmt:=High(TRenderFormat);
  403. While (Fmt>rfDefault) and (CompareText(FormatName(Fmt),F)<>0) do
  404. Fmt:=Pred(Fmt);
  405. if (F<>'') and (CompareText(F,'default')<>0) and (Fmt=rfDefault) then
  406. Usage(Format('Unknown output format: %s',[F]));
  407. FRunner.ReportApp:=GetReportClass(D).Create(Self);
  408. FRunner.ReportApp.rpt:=TFPReport.Create(FRunner.ReportApp);
  409. FRunner.Format:=Fmt;
  410. FRunner.DesignFileName:=J;
  411. FRunner.Execute;
  412. Terminate;
  413. end;
  414. end.