dbftool.lpr 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  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 PrintRecord(DBf: TDBf; RecordNumber: integer);
  247. // Prints contents of a record to screen
  248. var
  249. i: integer;
  250. begin
  251. writeln('Record ' + IntToStr(RecordNumber));
  252. for i := 0 to DBf.Fields.Count - 1 do
  253. begin
  254. if DBF.fields[i].IsNull then
  255. writeln('Field ', DBf.Fields[i].FieldName, ' is ***NULL***')
  256. else
  257. if DBF.Fields[i].DataType in [ftVarBytes, ftBytes] then
  258. writeln('Field ', DBF.Fields[i].FieldName, ' has value: binary ' + BinFieldToHex(DBF.Fields[i]))
  259. else
  260. writeln('Field ', DBf.Fields[i].FieldName, ' has value: ' + DBf.fields[i].AsString);
  261. end;
  262. end;
  263. { TDBFTool }
  264. procedure TDBFTool.ExportDBF(var MyDbf: TDbf; ExportFormat: string);
  265. // Exports recordset to specified format
  266. var
  267. ExportSettings: TCustomExportFormatSettings;
  268. Exporter: TCustomFileExporter;
  269. begin
  270. try
  271. case UpperCase(ExportFormat) of
  272. 'ACCESS', 'MSACCESS':
  273. begin
  274. Exporter := TXMLXSDExporter.Create(nil);
  275. ExportSettings := TXMLXSDFormatSettings.Create(true);
  276. (ExportSettings as TXMLXSDFormatSettings).CreateXSD := true;
  277. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  278. AccessCompatible;
  279. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  280. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  281. end;
  282. 'ADO', 'ADONET', 'ADO.NET':
  283. begin
  284. Exporter := TXMLXSDExporter.Create(nil);
  285. ExportSettings := TXMLXSDFormatSettings.Create(true);
  286. (ExportSettings as TXMLXSDFormatSettings).CreateXSD := true;
  287. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  288. ADONETCompatible;
  289. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  290. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  291. end;
  292. 'CSVEXCEL', 'EXCELCSV', 'CREATIVYST':
  293. begin
  294. Exporter := TCSVExporter.Create(nil);
  295. ExportSettings := TCSVFormatSettings.Create(true);
  296. (ExportSettings as TCSVFormatSettings).RowDelimiter:=LineEnding;
  297. //todo: delimiter?
  298. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.csv');
  299. end;
  300. 'CSV', 'CSVRFC4180', 'CSVLIBRE', 'CSVLIBREOFFICE':
  301. begin
  302. Exporter := TCSVExporter.Create(nil);
  303. ExportSettings := TCSVFormatSettings.Create(true);
  304. (ExportSettings as TCSVFormatSettings).DecimalSeparator := '.';
  305. (ExportSettings as TCSVFormatSettings).StringQuoteChar := '"';
  306. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.csv');
  307. end;
  308. 'DATASET', 'DELPHI':
  309. begin
  310. Exporter := TXMLXSDExporter.Create(nil);
  311. ExportSettings := TXMLXSDFormatSettings.Create(true);
  312. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  313. DelphiClientDataset;
  314. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  315. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  316. end;
  317. 'EXCEL', 'EXCELXML':
  318. begin
  319. Exporter := TXMLXSDExporter.Create(nil);
  320. ExportSettings := TXMLXSDFormatSettings.Create(true);
  321. (ExportSettings as TXMLXSDFormatSettings).ExportFormat := ExcelCompatible;
  322. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  323. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  324. end;
  325. 'JSON':
  326. begin
  327. Exporter := TSimpleJSONExporter.Create(nil);
  328. ExportSettings := TSimpleJSONFormatSettings.Create(true);
  329. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.json');
  330. end;
  331. 'SIMPLEXML', 'XML':
  332. begin
  333. Exporter := TSimpleXMLExporter.Create(nil);
  334. ExportSettings := TSimpleXMLFormatSettings.Create(true);
  335. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  336. end;
  337. 'RTF':
  338. begin
  339. Exporter := TRTFExporter.Create(nil);
  340. ExportSettings := TSimpleXMLFormatSettings.Create(true);
  341. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.rtf');
  342. end;
  343. 'SQL':
  344. begin
  345. Exporter := TSQLExporter.Create(nil);
  346. ExportSettings := TSQLFormatSettings.Create(true);
  347. (ExportSettings as TSQLFormatSettings).QuoteChar := '"';
  348. (ExportSettings as TSQLFormatSettings).DecimalSeparator := '.';
  349. (ExportSettings as TSQLFormatSettings).TableName := ChangeFileExt(MyDBF.TableName,'');
  350. (ExportSettings as TSQLFormatSettings).DateFormat := 'yyyy"-"mm"-"dd'; //ISO 8601, yyyy-mm-dd
  351. (ExportSettings as TSQLFormatSettings).TimeFormat := 'hh":"nn":"ss'; //ISO 8601, hh:mm:ss;
  352. (ExportSettings as TSQLFormatSettings).DateTimeFormat :=
  353. (ExportSettings as TSQLFormatSettings).DateFormat + '"T"' + (ExportSettings as TSQLFormatSettings).TimeFormat; //ISO 8601
  354. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.sql');
  355. end;
  356. 'TEX', 'LATEX':
  357. begin
  358. Exporter := TTeXExporter.Create(nil);
  359. ExportSettings := TTeXExportFormatSettings.Create(true);
  360. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.tex');
  361. end;
  362. 'TEXT', 'FIXED', 'FIXEDTEXT':
  363. begin
  364. Exporter := TFixedLengthExporter.Create(nil);
  365. ExportSettings := nil;
  366. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.txt');
  367. end
  368. else
  369. begin
  370. writeln('***Error: Unknown export format ' + ExportFormat + ' specified' + '. Aborting');
  371. Exporter := nil;
  372. ExportSettings := nil;
  373. Terminate;
  374. Exit;
  375. end;
  376. end;
  377. if assigned(ExportSettings) then
  378. Exporter.FormatSettings := ExportSettings;
  379. Exporter.Dataset := MyDBF;
  380. MyDBF.First; // we've just read the last record - make sure export starts at beginning
  381. Exporter.Execute;
  382. writeln('Completed export to ' + Exporter.FileName);
  383. finally
  384. if assigned(Exporter) then
  385. Exporter.Free;
  386. if assigned(ExportSettings) then
  387. ExportSettings.Free;
  388. end;
  389. end;
  390. procedure TDBFTool.DoRun;
  391. var
  392. DBFs: TStringList;
  393. Demo: boolean;
  394. ErrorMsg: string;
  395. FileNo: integer;
  396. MyDbf: TDbf;
  397. RecCount: integer;
  398. TableLevel: integer; //todo: use it
  399. begin
  400. // quick check parameters
  401. ErrorMsg := CheckOptions('h', 'createdemo exportformat: help tablelevel:');
  402. if ErrorMsg <> '' then
  403. begin
  404. ShowException(Exception.Create(ErrorMsg));
  405. Terminate;
  406. Exit;
  407. end;
  408. // parse parameters
  409. if HasOption('h', 'help') then
  410. begin
  411. WriteHelp;
  412. Terminate;
  413. Exit;
  414. end;
  415. DBFs := TStringList.Create;
  416. try
  417. Demo := false;
  418. if HasOption('createdemo') then
  419. Demo := true;
  420. TableLevel := 4; //DBF
  421. if HasOption('tablelevel') then
  422. TableLevel := StrToIntDef(GetOptionValue('tablelevel'), 4);
  423. if Demo then
  424. begin
  425. try
  426. CreateDemoDBFs('', TableLevel);
  427. except
  428. on E: Exception do
  429. begin
  430. writeln('*** Error creating demo databases: ' + E.Message);
  431. Terminate;
  432. Exit;
  433. end;
  434. end;
  435. end;
  436. // Process all dbfs if no files specified
  437. if DBFs.Count = 0 then
  438. GetDBFList(DBFs);
  439. if DBFs.Count = 0 then
  440. writeln('Could not find any dbf files');
  441. for FileNo := 0 to DBFs.Count - 1 do
  442. begin
  443. if not (fileexists(DBFs[FileNo])) then
  444. begin
  445. // for some reason, fpc trunk suddenly returns the directory as well...
  446. //writeln('Sorry, file ',DBFs[FileNo],' does not exist.');
  447. break;
  448. end;
  449. MyDbf := TDbf.Create(nil);
  450. try
  451. try
  452. MyDbf.FilePath := ExtractFilePath(DBFs[FileNo]);
  453. MyDbf.TableName := ExtractFileName(DBFs[FileNo]);
  454. MyDbf.ReadOnly := true;
  455. writeln('*** Opening: ' + DBFs[FileNo]);
  456. MyDbf.Open;
  457. writeln('Database tablelevel: ' + IntToStr(MyDbf.TableLevel));
  458. writeln('Database codepage: ' + IntToStr(MyDBF.CodePage));
  459. RecCount := 1;
  460. while not (MyDbf.EOF) do
  461. begin
  462. PrintRecord(MyDBF, RecCount);
  463. MyDBF.Next;
  464. RecCount := RecCount + 1;
  465. writeln('');
  466. end;
  467. if HasOption('exportformat') then
  468. begin
  469. try
  470. ExportDBF(MyDbf,GetOptionValue('exportformat'));
  471. except
  472. on E: Exception do
  473. begin
  474. writeln('*** Problem exporting file ', FileNo, ': ', E.Message);
  475. end;
  476. end;
  477. end;
  478. MyDbf.Close;
  479. except
  480. on E: Exception do
  481. begin
  482. writeln('*** Error reading file ', FileNo, ': ', E.Message);
  483. end;
  484. end;
  485. finally
  486. MyDbf.Free;
  487. end;
  488. end;
  489. finally
  490. DBFs.Free;
  491. end;
  492. // stop program loop
  493. Terminate;
  494. end;
  495. constructor TDBFTool.Create(TheOwner: TComponent);
  496. begin
  497. inherited Create(TheOwner);
  498. StopOnException := true;
  499. end;
  500. destructor TDBFTool.Destroy;
  501. begin
  502. inherited Destroy;
  503. end;
  504. procedure TDBFTool.WriteHelp;
  505. begin
  506. writeln('Usage: ', ExeName, ' -h');
  507. writeln(' --createdemo create demo database');
  508. writeln(' --tablelevel=<n> optional: desired tablelevel for demo db');
  509. writeln(' 3 DBase III');
  510. writeln(' 4 DBase IV');
  511. writeln(' 7 Visual DBase 7');
  512. writeln(' 25 FoxPro 2.x');
  513. writeln(' 30 Visual FoxPro');
  514. writeln(' --exportformat=<text> export dbfs to format. Format can be:');
  515. writeln(' access Microsoft Access XML');
  516. writeln(' adonet ADO.Net dataset XML');
  517. writeln(' csvexcel Excel/Creativyst format CSV text file (with locale dependent output)');
  518. writeln(' csvRFC4180 LibreOffice/RFC4180 format CSV text file');
  519. writeln(' dataset Delphi dataset XML');
  520. writeln(' excel Microsoft Excel XML');
  521. writeln(' fixedtext Fixed length text file');
  522. writeln(' json JSON file');
  523. writeln(' rtf Rich Text Format');
  524. writeln(' simplexml Simple XML');
  525. writeln(' sql SQL insert statements');
  526. writeln(' tex LaTeX file');
  527. end;
  528. var
  529. Application: TDBFTool;
  530. begin
  531. Application := TDBFTool.Create(nil);
  532. Application.Title := 'DBFTool';
  533. Application.Run;
  534. Application.Free;
  535. end.