Как человек возившийся с Delphi таблицами несколько лет скажу, что
zubr 100% прав. 
вот пример кода
procedure TForm1.StringGrid2DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var s:string;
 Flag: Cardinal;
 H: integer;
 i,isize: integer;
begin
 StringGrid2.Canvas.FillRect(Rect);
 s := StringGrid2.Cells[ACol,ARow];
 if (Acol=1) AND (ARow>0) then Flag := DT_LEFT else Flag := DT_CENTER;
 {
if (aRow=1) then begin
   StringGrid2.canvas.font.size:=8;
end else begin
   StringGrid2.canvas.font.size:=10;
end;
  }
 Inc(Rect.Left,3);
 Dec(Rect.Right,3);
 H := DrawText(StringGrid2.Canvas.Handle,PChar(s),length(s),Rect,Flag);
 if H > StringGrid2.RowHeights[ARow] then  begin
    StringGrid2.RowHeights[ARow] := H;  //увеличиваем
  end;
end;
с DBGrid все аналогично.
Единственный вариант когда пришлось ставит сторонний элемент - при использовании динамических объединяемых ячеек, в остальных стандартного набора StringGrid и DBGrid хватает