udapp.pp 12 KB

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