Create Table from Database

Top  Previous  Next

WPTools possibilities to create text and tables in code are extraordinary powerful.

 

We created an example (Demos\GridMode) which loads a BDE database and creates a table with all the rows. Optionally blobs can be loaded using the TParagraph.LoadFromStream method - this will preserve the formatting.

The demo also shows how to change the background color using the ASetColor procedure.

Optionally rows can be splitted on several pages (RowBreak) and, if you want to test the performance, the same data  can be imported 100 times.

 

GridModeDemo

This screen shot was taken after the well known BIOLIFE database was loaded - 100 times.

This created 2800 rows and images on 400 pages in only 2.8 seconds! (P-M 1.6 GHZ)

 

 

This is the main routine of the demo.

It first cleares the text and sets the page size. Then a footer is created to show the page number. After that a new table paragraph is created (table) which will then host all rows.

 

Please note that the CreateRow function creates an object of the class TWPTableRowStyle. This class inherits from TWPTextStyle (so does class TParagraph!) and is used as template for all cells which are created. So when you make changes to rowstyle, the new properties will be applied to all cells which are created afterwards using InputCell.

The rowstyle object is deleted when the row is completed with EndRow.

 

 

procedure TForm1.LoadFromDataSet(Data: TDataSet; aName: string; LoadBlobAsANSI: Boolean);

var i, a, a_max, RowNr: Integer;

table, cell, row: TParagraph;

b: Boolean;

obj: TWPTextObj;

wpobj: TWPObject;

bit: TBitmap;

rowstyle: TWPTableRowStyle;

tim: Cardinal;

stream: TStream;

begin

WPRichText1.Clear;

Caption := 'loading... - press ESCAPE to abort';

tim := GetTickCount;

try

 

   WPRichText1.EditOptions := [];

 

// Set Page Size

   WPRichText1.Header.PageSize := wp_DinA4;

   WPRichText1.Header.LeftMargin := WPCentimeterToTwips(2);

   WPRichText1.Header.RightMargin := WPCentimeterToTwips(1);

   WPRichText1.Header.TopMargin := WPCentimeterToTwips(1.5);

   WPRichText1.Header.BottomMargin := WPCentimeterToTwips(1.5);

   WPRichText1.Header.Landscape := TRUE;

   // WPRichText1.WordWrap := TRUE;

 

   // Create Footer

   WPRichText1.ActiveText := WPRichText1.HeaderFooter.Get(

          wpIsFooter, wpraOnAllPages);

   WPRichText1.InputString(aName + #9);

   WPRichText1.InputTextField(wpoPageNumber);

   WPRichText1.ASet(WPAT_BorderFlags, WPBRD_DRAW_Top);

   WPRichText1.SetTabPos(MaxInt, tkRight);

 

    // Switch to BODY

   WPRichText1.ActiveText := WPRichText1.BodyText;

 

   RowNr := 0;

 

   if StressTest.Checked then

   begin a_max := 100;

     ProgressBar1.Visible := TRUE;

   end else

   begin

     a_max := 1;

     ProgressBar1.Visible := FALSE;

   end;

 

   // Boolean to alternate the background

   b := FALSE;

 

   // Add all rows to this table

   table := WPRichText1.ActiveText.CreateTable(nil);

 

   table.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4);

 

   // now create the rows, a_max is used for stresstest

   for a := 1 to a_max do

   begin

     ProgressBar1.Position := a;

     ProgressBar1.Update;

 

   // Start at the beginning of database

     Data.First;

 

   // Repeat for all data rows

     repeat

       inc(RowNr);

       rowstyle := table.CreateRow(nil, true);

       if rowstyle <> nil then

       begin

         b := not b;

         rowstyle.ASetColor(WPAT_BGColor, clBlue);

         rowstyle.ASet(WPAT_ShadingValue, 30);

 

       // Create first Column with numbers

         cell := rowstyle.InputCell;

         cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_Right);

         cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1));

         cell.SetText(IntToStr(RowNr));

 

       // Make sure every other row is *not* shaded:

         if b then

         begin

           rowstyle.ADel(WPAT_BGColor);

           rowstyle.ADel(WPAT_ShadingValue);

         end;

         rowstyle.ASet(WPAT_IndentRight, 72);

 

         for i := 0 to Data.Fields.Count - 1 do

         begin

           cell := rowstyle.InputCell;

           if Data.Fields[i] is TGraphicField then

           begin

             bit := TBitmap.Create;

             bit.Assign(Data.Fields[i]);

             wpobj := TWPOImage.CreateImage(WPRichText1.Memo.RTFData, bit);

             obj := TWPTextObj.Create;

             cell.Insert(0, obj);

             obj.ObjRef := wpobj;

             obj._SetObjType(12); // = TWPTextObjType.wpobjImage

             obj.Width := wpobj.ContentsWidth div 3;

             obj.Height := wpobj.ContentsHeight div 3;

             bit.Free;

           end

           else if Data.Fields[i] is TBlobField then

           begin

             if LoadBlobAsANSI then

             begin

           // The simple method which loads text into one paragraph

               cell.ASet(WPAT_CharFontSize, 600);

               cell.SetText(Copy(Data.Fields[i].AsString, 1, 400) + '...');

             end else

             begin

           // the "difficult" method which also loads formatted text

               stream := TBlobStream.Create(Data.Fields[i] as TBlobField, bmRead);

               try

                 cell.LoadFromStream(stream,

                    'AUTO', '', [wploadpar_ClearShading]);

               finally

                 stream.Free;

               end;

             end;

           end

           else cell.SetText(Data.Fields[i].AsString);

           cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_Bottom);

         end;

       // Create the cells

         row := table.EndRow(rowstyle);

         if not RowBreak.Checked then

           row.ASet(WPAT_ParKeep, 1);

 

       // Allow ESCAPE

         if (GetAsyncKeyState(VK_ESCAPE) shr 15) <> 0 then

         begin

           if MessageBox(Handle, 'Abort loading of data ?', 'ESCAPE',

             MB_YESNO) = IDYES then exit;

         end;

       end;

 

       Data.Next;

     until Data.EOF;

   end; // for a

 

finally

   WPRichText1.Refresh;

   Caption := Format('WPTools5: Created %d rows in %.02f sec', [RowNr, (GetTickCount - tim) / 1000]);

end;

end;