"Интернет решения от доктора Боба" - читать интересную книгу автора (Swart Bob)

2.1.4. Записи

После анализа полей таблицы, мы можем пройтись по всей таблице и получить значения полей. Для каждой записи в таблице мы сгенерируем HTML-страницу. Мы можем использовать имена полей как заголовки, используя тег lt;H2gt; для ключевых полей и тег lt;H3gt; для не ключевых полей. Код просматривает всю таблицу т преобразовывает поля в текст и выводит их в HTML-файл:

while not Eof do

begin

  Inc(RecNr);

  System.Assign(f,FileName+'/'+PageNr(RecNr));

  System.Rewrite(f);

  writeln(f,'lt;HTMLgt;');

  writeln(f,'lt;HEADERgt;');

  writeln(f,'lt;TITLEgt;');

  writeln(f,Format('%s %d/%d',[ATable,RecNr,RecordCount]));

  writeln(f,'lt;/TITLEgt;');

  writeln(f,'lt;/HEADERgt;');

  writeln(f,'lt;BODYgt;');

  { print fields }

  for i:=0 to Pred(FieldCount) do

    if FieldTypes[i] gt; sf_UnKnown then

    begin

      if (keys gt;= i) then writeln(f,'lt;H2gt;')

                     else writeln(f,'lt;H3gt;');

      writeln(f,FieldDefs[i].Name,':');

      if (keys gt;= i) then writeln(f,'lt;/Bgt;lt;BRgt;') { lt;/H2gt; }

                     else writeln(f,'lt;/Bgt;lt;BRgt;'); { lt;/H3gt; }

      if FieldTypes[i] = sf_Memo then

        writeMemo(f,Fields[i])

      else writeln(f,Fields[i].AsString);

      if (keys = i) then writeln(f,'lt;HRgt;');

    end;

    writeln(f,'lt;/BODYgt;');

    writeln(f,'lt;/HTMLgt;');

    System.Close(f);

    Next

  end;

Заметим, что я использую здесь одно недокументированное свойство HTML: для окончания заголовка вы можете написать lt;/Bgt;, но вы должны использовать lt;BRgt; для разрыва строки. Таким образом, вы можете иметь заголовки, и текст, начинающийся правее и ниже заголовка. Пожалуйста, учтите, что это недокументированное свойство и вы должны заменить его раскомментировав lt;/H2gt; и lt;/H3gt; если вы не желаете жить на угле lt;юморgt;. Следующий листинг показывает как получить информацию из мемо поля базы данных и поместить его в текстовый файл. И наконец после этого мы отформатируем немного, помня что HTML игнорирует множественные переводы строки и пробелы.

 procedure WriteStream(var f: Text; var Stream: TMemoryStream);

 const

   LF = #10;

   BufSize = 8192; { bigger memos are chopped off!! }

 var

   Buffer: Array[0..Pred(BufSize)] of Char;

   i: Integer;

 begin

   Stream.Seek(0,0);

   if Stream.Size gt; 0 then

   begin

     Stream.Read(Buffer,Stream.Size);

     for i:=0 to Pred(Pred(Stream.Size)) do

     begin

       { empty line converted to lt;Pgt; break }

       if (Buffer[i] = LF) and (Buffer[i+1] = LF) then writeln(f,'lt;Pgt;');

       { strip multiple spaces (are ignored anyway) }

       if not ((Buffer[i] = ' ') and (Buffer[i+1] = ' ')) then write(f,Buffer[i]);

       { start new sentence on a new line (but only in HTML doc itself }

       if (Buffer[i] = '.') and (Buffer[i+1] = ' ') then writeln(f)

     end;

     writeln(f,Buffer[Pred(Stream.Size)])

   end

   else writeln(f,' ') { empty memo }

 end {WriteStream};

 procedure WriteMemo(var f: Text; Field: TField);

 var Stream: TMemoryStream;

 begin

   Stream := TMemoryStream.Create;

  (Field AS TMemoField).SaveToStream(Stream);

   WriteStream(f,Stream);

   Stream.Free

 end {WriteMemo};