|
Create Table in Code |
Top Previous Next |
|
Very often you will have to create a table, for example a calculation.
This can be done best using the TableAdd procedure. This procedure requires only a few parameters, such as row cont and column count but can also work with a callback procedure which is executed for each created cell.
Since the callback procedure receives information about the current column and row number it is easy to apply special properties to certain cells or preset the contents of the created cell.
Note: You can also use the Rows[r].Cols[c] arrays as described in the second part of this chapter but then you have to take care that you work with the correct row index. Using this arrays is probably also a little slower.
Please see reference for supported WPAT_ codes.
a) Use TableAdd() with a callback function
This code will append a new table to the end of the text:
WPRichText1.TableAdd(7,7, [wptblActivateBorders,wptblAppendTableAtEnd],nil, InvoiceDemoCell);
This is a screen shot of the created table:
The callback procedure InvoiceDemoCell is implemented like this
procedure TWPTableCalc.InvoiceDemoCell(RowNr, ColNr: Integer; par: TParagraph); const prods : array[1..5] of string = ( 'Cool', 'Master', 'Hummer', 'High Performace', 'Better' ); begin // Set the widths of the rows case ColNr of 1 : par.ASet(WPAT_COLWIDTH_PC, 500); // % * 100 ! 2 : par.ASet(WPAT_COLWIDTH_PC, 2500); else begin par.ASet(WPAT_COLWIDTH_PC, 1400); par.ASet(WPAT_Alignment, Integer(paralRight)); end; end;
// Set the text and the cell names and commands
if RowNr=1 then // Header Row ------------------------------ begin case ColNr of 1 : ; 2 : par.SetText('Product'); 3 : par.SetText('Price'); 4 : par.SetText('Amount'); 5 : par.SetText('net'); 6 : par.SetText('+VAT'); 7 : par.SetText('total'); end; par.ASetColor(WPAT_FGColor, $A0A0A0); par.ASet(WPAT_ParProtected,1); par.ASet(WPAT_Alignment, Integer(paralCenter)); end else if RowNr=7 then // Footer Row ------------------------------ begin par.ADel(WPAT_BorderWidth); // Delete the border width for ALL linese par.ASet(WPAT_BorderWidthT, 40); // ANd set the top line to 40 twips par.ASetAdd( WPAT_BorderFlags, WPBRD_DRAW_Top); // Add a flag! // par.ParentRow.ASet(WPAT_BoxMinHeight, WPCentimeterToTwips(1.5)); par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.3)); par.ASet(WPAT_SpaceAfter, WPCentimeterToTwips(0.3)); par.ASet(WPAT_ParProtected,1); case ColNr of 1 : ; 2 : ; 3 : ; 4 : ; 5 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_NET'); end; 6 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_VAT'); end; 7 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_TOTAL'); par.ASetCharStyle(true, WPSTY_BOLD); end; end;
end else // Data Rows ------------------------------ begin case ColNr of 1 : begin par.SetText(IntToStr(RowNr-1)); par.ASet(WPAT_ParProtected,1); end; 2 : par.SetText(prods[RowNr-1]); 3 : par.SetText(IntToStr(Random(1000)+1)); 4 : par.SetText(IntToStr(Random(3)+1)); 5 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)*left(1)'); par.ASetStringProp(WPAT_PAR_NAME, 'PAR_NET'); par.ASet(WPAT_ParProtected,1); end; 6 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'left(1)*0.16'); par.ASetStringProp(WPAT_PAR_NAME, 'PAR_VAT'); par.ASet(WPAT_ParProtected,1); end; 7 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)+left(1)'); par.ASetStringProp(WPAT_PAR_NAME, 'PAR_TOTAL'); par.ASet(WPAT_ParProtected,1); end; end; end; end;
Note: The commands par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)+left(1)'); par.ASetStringProp(WPAT_PAR_NAME, 'PAR_TOTAL'); are only usable with WPTools Bundle. They are used to add calculation to a table.
b) Use TableAdd() and the Rows[] and Cols[] arrays
This example appends 2 rows to the current table (a new table is created if necessary) and loads an image in the second cell of the first row.
Screen shot of the created table. (Only the first row is visible.)
procedure TForm1.CreateTableWithImageClick(Sender: TObject); var tbl: TParagraph; obj: TWPTextObj; img: TWPOImage; imagefilename: string; rowoffset : Integer; begin // Select the image from file or use a local image imagefilename := ''; if SelectImageFile.Checked then begin if OpenPictureDialog1.Execute then imagefilename := OpenPictureDialog1.FileName else exit; end;
// Create the image object img := TWPOImage.Create(WPRichText1); // uses WPObj_Image try if imagefilename = '' then img.Picture.Assign(Image2.Picture) else img.LoadFromFile(imagefilename); except img.Free; // We cannot load this image raise; end;
// This code is required if we do *not* use the wptblAppendTableAtEnd option. // since than an existing table is enlarged tbl := WPRichText1.Table; if tbl<>nil then begin rowoffset := tbl.RowCount; WPRichText1.ActiveParagraph := tbl.LastChild.ColFirst; end else rowoffset := 0;
// Create the table and after that modify the cells // makes sure a new table is created at the end! tbl := WPRichText1.TableAdd(2, 1, [wptblActivateBorders], nil, nil);
// Set text of first column tbl.Rows[rowoffset+0].Cols[0].SetText(imagefilename);
// Create the TWPTextObj (which is the reference to image) obj := tbl.Rows[rowoffset+0].Cols[1].AppendNewObject(wpobjImage, false, false, 0); obj.ObjRef := img; obj.Frame := [wpframeFine];
// Set the size of the image obj.Width := img.ContentsWidth * 2; obj.Height := img.ContentsHeight * 2;
// Empty row, no borders - move cursor to first cell WPRichText1.ActiveParagraph := tbl.ColFirst; tbl := WPRichText1.TableAdd(2, 1, [], nil, nil); WPRichText1.ActiveParagraph := tbl.ColFirst;
// Format and display changed text WPRichText1.Refresh; end;
c) Create a table with a header and footer row which are repeated on each page
This feature is controlled by the flags paprIsFooter and paprIsHeader in the property TParagraph.par. The property must be set in the row paragraph which is the parent paragraph of a cell. The API TableAdd does this for you.
We suggest to use this feature with the flag wpfDontBreakTableRows in FormatOptions. In any case please set the property wpDisableSpeedReformat.
Example code:
procedure TForm1.CreateTableCellCallBackHF(RowNr, ColNr: Integer; par: TParagraph); begin if RowNr = -1 then // THIS CELL IS IN THE HEADER begin par.ASetColor(WPAT_BGColor, clBtnFace); if ColNr = 1 then par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5)) else par.SetText('HEADER'); end else if RowNr = -2 then // THIS CELL IS IN THE FOOTER begin par.ASetColor(WPAT_BGColor, clBtnFace); if ColNr = 1 then par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5)) else par.SetText('FOOTER'); end else begin if (RowNr and 1) = 0 then par.ASetColor(WPAT_BGColor, clYellow); if ColNr = 1 then begin par.ASetColor(WPAT_BGColor, clBtnFace); par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5)); par.SetText(IntToStr(RowNr)); end else begin par.SetText(IntToStr(FCellNr)); inc(FCellNr); end; end; end;
procedure TForm1.CreateTableWithHeaderFooterClick(Sender: TObject); begin WPRichText1.Clear; FRowCount := 200; // count of rows, excluding header and footer! WPRichText1.FormatOptions := [wpDisableSpeedReformat, wpfDontBreakTableRows]; WPRichText1.TableAdd( 4, FRowCount, [wptblActivateBorders,wptblCreateHeaderRow,wptblCreateFooterRow], nil, CreateTableCellCallBackHF); WPRichText1.Refresh; end;
|