dbftool.lpr 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. program dbftool;
  2. { Reads and exports DBF files. Can create a demo DBF file to test with.
  3. Demonstrates creating DBF tables, filling it with data,
  4. and exporting datasets.
  5. }
  6. {$mode objfpc}{$H+}
  7. uses {$IFDEF UNIX} {$IFDEF UseCThreads}
  8. cthreads, {$ENDIF} {$ENDIF}
  9. Classes,
  10. SysUtils,
  11. CustApp,
  12. DB,
  13. dbf,
  14. dbf_fields,
  15. dbf_common,
  16. dateutils,
  17. fpdbexport,
  18. fpcsvexport,
  19. fpdbfexport,
  20. fpfixedexport,
  21. fprtfexport,
  22. fpsimplejsonexport,
  23. fpsimplexmlexport,
  24. fpsqlexport,
  25. fptexexport,
  26. fpxmlxsdexport;
  27. type
  28. { TDBFTool }
  29. TDBFTool = class(TCustomApplication)
  30. private
  31. procedure ExportDBF(var MyDbf: TDbf; ExportFormat: string);
  32. protected
  33. procedure DoRun; override;
  34. public
  35. constructor Create(TheOwner: TComponent); override;
  36. destructor Destroy; override;
  37. procedure WriteHelp; virtual;
  38. end;
  39. procedure CreateDemoDBFs(Directory: string; TableLevel: integer);
  40. // Creates 2 demonstration DBFs in Directory with dbase compatibility level
  41. // TableLevel
  42. var
  43. NewDBF: TDBF;
  44. i: integer;
  45. begin
  46. NewDBF := TDBF.Create(nil);
  47. try
  48. if Directory = '' then
  49. NewDBF.FilePath := '' { application directory}
  50. else
  51. NewDBF.FilePathFull := ExpandFileName(Directory) {full absolute path};
  52. if TableLevel <= 0 then
  53. NewDBF.TableLevel := 4 {default to DBase IV}
  54. else
  55. NewDBF.TableLevel := TableLevel;
  56. NewDBF.TableName := 'customer.dbf';
  57. writeln('Creating ', NewDBF.TableName, ' with table level ', NewDBF.TableLevel);
  58. if TableLevel >= 30 then
  59. begin
  60. NewDBF.FieldDefs.Add('CUST_NO', ftAutoInc);
  61. end
  62. else
  63. NewDBF.FieldDefs.Add('CUST_NO', ftInteger);
  64. NewDBF.FieldDefs.Add('CUSTOMER', ftString, 25);
  65. NewDBF.FieldDefs.Add('CITY', ftString, 25);
  66. NewDBF.FieldDefs.Add('COUNTRY', ftString, 15);
  67. NewDBF.CreateTable;
  68. NewDBF.Open;
  69. for i := 1 to 5 do //keep size manageable until we have working files
  70. begin
  71. NewDBF.Append;
  72. if (NewDBF.FieldDefs.Find('CUST_NO').DataType <> ftAutoInc) then
  73. NewDBF.FieldByName('CUST_NO').AsInteger := i;
  74. case i of
  75. 1:
  76. begin
  77. NewDBF.FieldByName('CUSTOMER').AsString := 'Michael Design';
  78. NewDBF.FieldByName('CITY').AsString := 'San Diego';
  79. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  80. end;
  81. 2:
  82. begin
  83. NewDBF.FieldByName('CUSTOMER').AsString := 'Michael Design';
  84. NewDBF.FieldByName('CITY').AsString := 'San Diego';
  85. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  86. end;
  87. 3:
  88. begin
  89. NewDBF.FieldByName('CUSTOMER').AsString := 'VC Technologies';
  90. NewDBF.FieldByName('CITY').AsString := 'Dallas';
  91. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  92. end;
  93. 4:
  94. begin
  95. NewDBF.FieldByName('CUSTOMER').AsString := 'Klämpfl, Van Canneyt';
  96. NewDBF.FieldByName('CITY').AsString := 'Boston';
  97. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  98. end;
  99. 5:
  100. begin
  101. NewDBF.FieldByName('CUSTOMER').AsString := 'Felipe''s Bank';
  102. NewDBF.FieldByName('CITY').AsString := 'Manchester';
  103. NewDBF.FieldByName('COUNTRY').AsString := 'England';
  104. end;
  105. end;
  106. NewDBF.Post;
  107. end;
  108. NewDBF.Close;
  109. finally
  110. NewDBF.Free;
  111. end;
  112. NewDBF := TDBF.Create(nil);
  113. try
  114. if Directory = '' then
  115. NewDBF.FilePath := '' {application directory}
  116. else
  117. NewDBF.FilePathFull := ExpandFileName(Directory) {full absolute path};
  118. if TableLevel <= 0 then
  119. NewDBF.TableLevel := 4 {default to DBase IV}
  120. else
  121. NewDBF.TableLevel := TableLevel;
  122. NewDBF.TableName := 'employee.dbf';
  123. writeln('Creating ', NewDBF.TableName, ' with table level ', NewDBF.TableLevel);
  124. if TableLevel >= 30 then
  125. begin
  126. NewDBF.FieldDefs.Add('EMP_NO', ftAutoInc);
  127. end
  128. else
  129. NewDBF.FieldDefs.Add('EMP_NO', ftInteger);
  130. NewDBF.FieldDefs.Add('FIRST_NAME', ftString, 15);
  131. NewDBF.FieldDefs.Add('LAST_NAME', ftString, 20);
  132. NewDBF.FieldDefs.Add('PHONE_EXT', ftString, 4);
  133. NewDBF.FieldDefs.Add('JOB_CODE', ftString, 5);
  134. NewDBF.FieldDefs.Add('JOB_GRADE', ftInteger);
  135. NewDBF.FieldDefs.Add('JOB_COUNTR', ftString, 15); //Note 10 character limit for table/field names in most DBases
  136. NewDBF.FieldDefs.Add('SALARY', ftFloat);
  137. NewDBF.CreateTable;
  138. NewDBF.Open;
  139. for i := 1 to 5 do //keep size manageable until we have working files
  140. begin
  141. NewDBF.Append;
  142. if (NewDBF.FieldDefs.Find('EMP_NO').DataType <> ftAutoInc) then
  143. NewDBF.FieldByName('EMP_NO').AsInteger := i;
  144. case i of
  145. 1:
  146. begin
  147. NewDBF.FieldByName('FIRST_NAME').AsString := 'William';
  148. NewDBF.FieldByName('LAST_NAME').AsString := 'Shatner';
  149. NewDBF.FieldByName('PHONE_EXT').AsString := '1702';
  150. NewDBF.FieldByName('JOB_CODE').AsString := 'CEO';
  151. NewDBF.FieldByName('JOB_GRADE').AsInteger := 1;
  152. NewDBF.FieldByName('JOB_COUNTR').AsString := 'USA';
  153. NewDBF.FieldByName('SALARY').AsFloat := 48000;
  154. end;
  155. 2:
  156. begin
  157. NewDBF.FieldByName('FIRST_NAME').AsString := 'Ivan';
  158. NewDBF.FieldByName('LAST_NAME').AsString := 'Ishenin';
  159. NewDBF.FieldByName('PHONE_EXT').AsString := '9802';
  160. NewDBF.FieldByName('JOB_CODE').AsString := 'Eng';
  161. NewDBF.FieldByName('JOB_GRADE').AsInteger := 2;
  162. NewDBF.FieldByName('JOB_COUNTR').AsString := 'Russia';
  163. NewDBF.FieldByName('SALARY').AsFloat := 38000;
  164. end;
  165. 3:
  166. begin
  167. NewDBF.FieldByName('FIRST_NAME').AsString := 'Erin';
  168. NewDBF.FieldByName('LAST_NAME').AsString := 'Powell';
  169. NewDBF.FieldByName('PHONE_EXT').AsString := '1703';
  170. NewDBF.FieldByName('JOB_CODE').AsString := 'Admin';
  171. NewDBF.FieldByName('JOB_GRADE').AsInteger := 2;
  172. NewDBF.FieldByName('JOB_COUNTR').AsString := 'USA';
  173. NewDBF.FieldByName('SALARY').AsFloat := 45368;
  174. end;
  175. 4:
  176. begin
  177. NewDBF.FieldByName('FIRST_NAME').AsString := 'Margaret';
  178. NewDBF.FieldByName('LAST_NAME').AsString := 'Tetchy';
  179. NewDBF.FieldByName('PHONE_EXT').AsString := '3804';
  180. NewDBF.FieldByName('JOB_CODE').AsString := 'Eng';
  181. NewDBF.FieldByName('JOB_GRADE').AsInteger := 3;
  182. NewDBF.FieldByName('JOB_COUNTR').AsString := 'England';
  183. NewDBF.FieldByName('SALARY').AsFloat := 28045;
  184. end;
  185. 5:
  186. begin
  187. NewDBF.FieldByName('FIRST_NAME').AsString := 'Sergey';
  188. NewDBF.FieldByName('LAST_NAME').AsString := 'Bron';
  189. NewDBF.FieldByName('PHONE_EXT').AsString := '3807';
  190. NewDBF.FieldByName('JOB_CODE').AsString := 'Admin';
  191. NewDBF.FieldByName('JOB_GRADE').AsInteger := 3;
  192. NewDBF.FieldByName('JOB_COUNTR').AsString := 'England';
  193. NewDBF.FieldByName('SALARY').AsFloat := 24468;
  194. end;
  195. end;
  196. NewDBF.Post;
  197. end;
  198. NewDBF.Close;
  199. finally
  200. NewDBF.Free;
  201. end;
  202. end;
  203. procedure GetDBFList(Results: TStringList);
  204. // Gets list of all .dbf files in a directory and its subdirectories.
  205. var
  206. r: TSearchRec;
  207. begin
  208. results.Clear;
  209. if FindFirst('*.dbf', faAnyFile -
  210. {$WARNINGS OFF}
  211. faVolumeID - faSymLink
  212. {$WARNINGS ON}
  213. , r) = 0 then
  214. begin
  215. repeat
  216. if (r.Attr and faDirectory) <> faDirectory then
  217. begin
  218. results.add(expandfilename(r.Name));
  219. end;
  220. until (FindNext(r) <> 0);
  221. findclose(r);
  222. end;
  223. end;
  224. function BinFieldToHex(BinarySource: TField): string;
  225. // Convert binary field contents to strings with hexadecimal representation.
  226. // Useful for displaying binary field contents.
  227. var
  228. HexValue: PChar;
  229. begin
  230. Result := '';
  231. HexValue := StrAlloc(Length(BinarySource.AsBytes));
  232. try
  233. try
  234. BinToHex(PChar(BinarySource.AsBytes), HexValue, Length(BinarySource.AsBytes));
  235. Result := 'size: ' + IntToStr(Length(BinarySource.AsBytes)) + '; hex: ' + HexValue;
  236. except
  237. on E: Exception do
  238. begin
  239. Result := 'exception: ' + E.ClassName + '/' + E.Message;
  240. end;
  241. end;
  242. finally
  243. StrDispose(HexValue);
  244. end;
  245. end;
  246. procedure PrintRecords(DBf: TDBf);
  247. // Prints contents of available records to screen
  248. var
  249. i: integer;
  250. RecordCount: integer;
  251. begin
  252. Dbf.First;
  253. RecordCount:=0;
  254. while not (Dbf.EOF) do
  255. begin
  256. RecordCount := RecordCount + 1;
  257. writeln('Record ' + IntToStr(RecordCount));
  258. for i := 0 to DBf.Fields.Count - 1 do
  259. begin
  260. if DBF.fields[i].IsNull then
  261. writeln('Field ', DBf.Fields[i].FieldName, ' is ***NULL***')
  262. else
  263. if DBF.Fields[i].DataType in [ftVarBytes, ftBytes] then
  264. writeln('Field ', DBF.Fields[i].FieldName, ' has value: binary ' + BinFieldToHex(DBF.Fields[i]))
  265. else
  266. writeln('Field ', DBf.Fields[i].FieldName, ' has value: ' + DBf.fields[i].AsString);
  267. end;
  268. DBF.Next;
  269. writeln('');
  270. end;
  271. end;
  272. { TDBFTool }
  273. procedure TDBFTool.ExportDBF(var MyDbf: TDbf; ExportFormat: string);
  274. // Exports recordset to specified format
  275. var
  276. ExportSettings: TCustomExportFormatSettings;
  277. Exporter: TCustomFileExporter;
  278. begin
  279. try
  280. case UpperCase(ExportFormat) of
  281. 'ACCESS', 'MSACCESS':
  282. begin
  283. Exporter := TXMLXSDExporter.Create(nil);
  284. ExportSettings := TXMLXSDFormatSettings.Create(true);
  285. (ExportSettings as TXMLXSDFormatSettings).CreateXSD := true;
  286. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  287. AccessCompatible;
  288. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  289. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  290. end;
  291. 'ADO', 'ADONET', 'ADO.NET':
  292. begin
  293. Exporter := TXMLXSDExporter.Create(nil);
  294. ExportSettings := TXMLXSDFormatSettings.Create(true);
  295. (ExportSettings as TXMLXSDFormatSettings).CreateXSD := true;
  296. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  297. ADONETCompatible;
  298. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  299. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  300. end;
  301. 'CSVEXCEL', 'EXCELCSV', 'CREATIVYST':
  302. begin
  303. Exporter := TCSVExporter.Create(nil);
  304. ExportSettings := TCSVFormatSettings.Create(true);
  305. (ExportSettings as TCSVFormatSettings).RowDelimiter:=LineEnding;
  306. //todo: delimiter?
  307. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.csv');
  308. end;
  309. 'CSV', 'CSVRFC4180', 'CSVLIBRE', 'CSVLIBREOFFICE':
  310. begin
  311. Exporter := TCSVExporter.Create(nil);
  312. ExportSettings := TCSVFormatSettings.Create(true);
  313. (ExportSettings as TCSVFormatSettings).DecimalSeparator := '.';
  314. (ExportSettings as TCSVFormatSettings).StringQuoteChar := '"';
  315. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.csv');
  316. end;
  317. 'DATASET', 'DELPHI':
  318. begin
  319. Exporter := TXMLXSDExporter.Create(nil);
  320. ExportSettings := TXMLXSDFormatSettings.Create(true);
  321. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  322. DelphiClientDataset;
  323. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  324. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  325. end;
  326. 'EXCEL', 'EXCELXML':
  327. begin
  328. Exporter := TXMLXSDExporter.Create(nil);
  329. ExportSettings := TXMLXSDFormatSettings.Create(true);
  330. (ExportSettings as TXMLXSDFormatSettings).ExportFormat := ExcelCompatible;
  331. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  332. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  333. end;
  334. 'JSON':
  335. begin
  336. Exporter := TSimpleJSONExporter.Create(nil);
  337. ExportSettings := TSimpleJSONFormatSettings.Create(true);
  338. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.json');
  339. end;
  340. 'SIMPLEXML', 'XML':
  341. begin
  342. Exporter := TSimpleXMLExporter.Create(nil);
  343. ExportSettings := TSimpleXMLFormatSettings.Create(true);
  344. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  345. end;
  346. 'RTF':
  347. begin
  348. Exporter := TRTFExporter.Create(nil);
  349. ExportSettings := TSimpleXMLFormatSettings.Create(true);
  350. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.rtf');
  351. end;
  352. 'SQL':
  353. begin
  354. Exporter := TSQLExporter.Create(nil);
  355. ExportSettings := TSQLFormatSettings.Create(true);
  356. (ExportSettings as TSQLFormatSettings).QuoteChar := '"';
  357. (ExportSettings as TSQLFormatSettings).DecimalSeparator := '.';
  358. (ExportSettings as TSQLFormatSettings).TableName := ChangeFileExt(MyDBF.TableName,'');
  359. (ExportSettings as TSQLFormatSettings).DateFormat := 'yyyy"-"mm"-"dd'; //ISO 8601, yyyy-mm-dd
  360. (ExportSettings as TSQLFormatSettings).TimeFormat := 'hh":"nn":"ss'; //ISO 8601, hh:mm:ss;
  361. (ExportSettings as TSQLFormatSettings).DateTimeFormat :=
  362. (ExportSettings as TSQLFormatSettings).DateFormat + '"T"' + (ExportSettings as TSQLFormatSettings).TimeFormat; //ISO 8601
  363. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.sql');
  364. end;
  365. 'TEX', 'LATEX':
  366. begin
  367. Exporter := TTeXExporter.Create(nil);
  368. ExportSettings := TTeXExportFormatSettings.Create(true);
  369. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.tex');
  370. end;
  371. 'TEXT', 'FIXED', 'FIXEDTEXT':
  372. begin
  373. Exporter := TFixedLengthExporter.Create(nil);
  374. ExportSettings := nil;
  375. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.txt');
  376. end
  377. else
  378. begin
  379. writeln('***Error: Unknown export format ' + ExportFormat + ' specified' + '. Aborting');
  380. Exporter := nil;
  381. ExportSettings := nil;
  382. Terminate;
  383. Exit;
  384. end;
  385. end;
  386. if assigned(ExportSettings) then
  387. Exporter.FormatSettings := ExportSettings;
  388. Exporter.Dataset := MyDBF;
  389. MyDBF.First; // we've just read the last record - make sure export starts at beginning
  390. Exporter.Execute;
  391. writeln('Completed export to ' + Exporter.FileName);
  392. finally
  393. if assigned(Exporter) then
  394. Exporter.Free;
  395. if assigned(ExportSettings) then
  396. ExportSettings.Free;
  397. end;
  398. end;
  399. procedure TDBFTool.DoRun;
  400. var
  401. DBFs: TStringList;
  402. Demo: boolean;
  403. ErrorMsg: string;
  404. FileNo: integer;
  405. MyDbf: TDbf;
  406. TableLevel: integer;
  407. begin
  408. // quick check parameters
  409. ErrorMsg := CheckOptions('h', 'createdemo exportformat: help tablelevel:');
  410. if ErrorMsg <> '' then
  411. begin
  412. ShowException(Exception.Create(ErrorMsg));
  413. Terminate;
  414. Exit;
  415. end;
  416. // parse parameters
  417. if HasOption('h', 'help') then
  418. begin
  419. WriteHelp;
  420. Terminate;
  421. Exit;
  422. end;
  423. DBFs := TStringList.Create;
  424. try
  425. Demo := false;
  426. if HasOption('createdemo') then
  427. Demo := true;
  428. TableLevel := 4; //DBF
  429. if HasOption('tablelevel') then
  430. TableLevel := StrToIntDef(GetOptionValue('tablelevel'), 4);
  431. if Demo then
  432. begin
  433. try
  434. CreateDemoDBFs('', TableLevel);
  435. except
  436. on E: Exception do
  437. begin
  438. writeln('*** Error creating demo databases: ' + E.Message);
  439. Terminate;
  440. Exit;
  441. end;
  442. end;
  443. end;
  444. // Process all dbfs if no files specified
  445. if DBFs.Count = 0 then
  446. GetDBFList(DBFs);
  447. if DBFs.Count = 0 then
  448. writeln('Could not find any dbf files');
  449. for FileNo := 0 to DBFs.Count - 1 do
  450. begin
  451. if not (fileexists(DBFs[FileNo])) then
  452. begin
  453. // for some reason, fpc trunk suddenly returns the directory as well...
  454. //writeln('Sorry, file ',DBFs[FileNo],' does not exist.');
  455. break;
  456. end;
  457. MyDbf := TDbf.Create(nil);
  458. try
  459. try
  460. MyDbf.FilePath := ExtractFilePath(DBFs[FileNo]);
  461. MyDbf.TableName := ExtractFileName(DBFs[FileNo]);
  462. MyDbf.ReadOnly := true;
  463. writeln('*** Opening: ' + DBFs[FileNo]);
  464. MyDbf.Open;
  465. writeln('Database tablelevel: ' + IntToStr(MyDbf.TableLevel));
  466. writeln('Database codepage: ' + IntToStr(MyDBF.CodePage));
  467. PrintRecords(MyDBF);
  468. if HasOption('exportformat') then
  469. begin
  470. try
  471. ExportDBF(MyDbf,GetOptionValue('exportformat'));
  472. except
  473. on E: Exception do
  474. begin
  475. writeln('*** Problem exporting file ', FileNo, ': ', E.Message);
  476. end;
  477. end;
  478. end;
  479. MyDbf.Close;
  480. except
  481. on E: Exception do
  482. begin
  483. writeln('*** Error reading file ', FileNo, ': ', E.Message);
  484. end;
  485. end;
  486. finally
  487. MyDbf.Free;
  488. end;
  489. end;
  490. finally
  491. DBFs.Free;
  492. end;
  493. // stop program loop
  494. Terminate;
  495. end;
  496. constructor TDBFTool.Create(TheOwner: TComponent);
  497. begin
  498. inherited Create(TheOwner);
  499. StopOnException := true;
  500. end;
  501. destructor TDBFTool.Destroy;
  502. begin
  503. inherited Destroy;
  504. end;
  505. procedure TDBFTool.WriteHelp;
  506. begin
  507. writeln('Usage: ', ExeName, ' -h');
  508. writeln(' --createdemo create demo database');
  509. writeln(' --tablelevel=<n> optional: desired tablelevel for demo db');
  510. writeln(' 3 DBase III');
  511. writeln(' 4 DBase IV');
  512. writeln(' 7 Visual DBase 7');
  513. writeln(' 25 FoxPro 2.x');
  514. writeln(' 30 Visual FoxPro');
  515. writeln(' --exportformat=<text> export dbfs to format. Format can be:');
  516. writeln(' access Microsoft Access XML');
  517. writeln(' adonet ADO.Net dataset XML');
  518. writeln(' csvexcel Excel/Creativyst format CSV text file (with locale dependent output)');
  519. writeln(' csvRFC4180 LibreOffice/RFC4180 format CSV text file');
  520. writeln(' dataset Delphi dataset XML');
  521. writeln(' excel Microsoft Excel XML');
  522. writeln(' fixedtext Fixed length text file');
  523. writeln(' json JSON file');
  524. writeln(' rtf Rich Text Format');
  525. writeln(' simplexml Simple XML');
  526. writeln(' sql SQL insert statements');
  527. writeln(' tex LaTeX file');
  528. end;
  529. var
  530. Application: TDBFTool;
  531. begin
  532. Application := TDBFTool.Create(nil);
  533. Application.Title := 'DBFTool';
  534. Application.Run;
  535. Application.Free;
  536. end.