Thema: Delphi drucken einer tabelle ?!

Einzelnen Beitrag anzeigen

heiopei
(Gast)

n/a Beiträge
 
#1

drucken einer tabelle ?!

  Alt 11. Feb 2005, 11:31
hallo,
ich hab folgendes etwas komplexeres problem:

ich hab ein stringgrid, das ich ausdrucken möchte.
allerdings möchte ich dazu
-zeilenumrüche innerhalb der zellen beachten
-vertikale und horizontale trennlinien zeichnen
-das ganze auch als durckvorschau anzeigen
-das ganze überhaupt drucken

so. jetzt hab ich aber ewig nach funktionen zum zeilenumbruch im internet gesucht und es dann selbst gemacht. (wer interesse daran hat, kann sich ja bei mir melden)
dabei wird eine tabelle übergeben und jede zelle wird durchlaufen... dann wird die so neu entstandene tabelle in ein array gespeichert. soviel dazu!

jetzt hab ich aber das problem das ich die tabelle natürlich auch noch drucken muss!
dazu hab ich folgenden code verfasst:

Delphi-Quellcode:
...
//typdefinierung für eine zelle der tabelle "table"
type TZelle = record
  rownr: Word;
  text: ShortString;
end;

const
  //abstand von links (randbreite)
  lrand = 20;
  //abstand von oben
  orand = 20;
  //abstand von unten
  urand = 20;
var
  //größen der einzelnen spalten der tabelle (grafisch)
  cwidths, temp: array of Byte;
  //tabelle mit den umgebrochenen zelleninhalten
  table: array of array of TZelle;
  //tabelle mit den fertigen drucktabellen
  //größe der tabelle + 1
  tpos: Word;
  //anzahl der zellen
  colpos: Word;
...

//diese prozedur wird aufgerufen, um die tabelle zu drucken
procedure Tfrmprnt.make_printing;
var
  i: Word; //zählvariable
begin
  with Printer do
  begin
    //druckauftrag beginnen
    BeginDoc;
    //druckbild auf "horizontal" stellen
    Orientation := poPortrait;
    //jede zeicheneinheit des canvas auf 0.1 mm festlegen positive x nach rechts
    // positive y nach oben
    SetMapMode(Handle, MM_LOMETRIC);
    //seitenbreite und - höhe festlegen
    pgwidth := GetDeviceCaps(Handle, HorzSize);
    pgheight := GetDeviceCaps(Handle, VertSize);
    //wenn die tabellenbreite > als seitenbreite bei druckbild = "horizontal"
    if (temp[colpos - 1] + 2 * lrand) > pgwidth then
    begin
      //druckbild auf "vertikal" umstellen
      Orientation := poLandscape;
      //jede zeicheneinheit des canvas auf 0.1 mm festlegen positive x nach
      // rechts positive y nach oben -- kann vermutlich weggelassen werden!!
      SetMapMode(Handle, MM_LOMETRIC);
      //seitenbreite und -höhe neu festlegen
      pgwidth := GetDeviceCaps(Handle, HorzSize);
      pgheight := GetDeviceCaps(Handle, VertSize);
    end
    //y = oberer rand = 20mm
    y := -orand;
    //titel des ausdrucks drucken
    print_title;
    //tabellenkopf schreiben
    print_line(1, true);
    //jede zeile der tabelle schreiben
    for i := 2 to tpos - 1 do
    begin
      //überprüfen, ob trennlinie gezogen werden soll (wegen zeilenumbrüchen!!!)
      if i > 2 then
        if table[i, 1].rownr <> table[i - 1, 1].rownr then
          print_line(i, true)
        else
          print_line(i, false);
      //wenn am rand unten angekommen neu seite beginnen
      if y < -(pgheight - urand) then
      begin
        break; //warum das weis ich nicht (steht so im kochbuch delphi6)
        //neue seite auf dem drucker erstellen
        NewPage;
        //y neu festlegen
        y := - orand;
        //jede zeicheneinheit des canvas auf 0.1 mm festlegen positive x nach
        // rechts positive y nach oben
        SetMapMode(Handle, MM_LOMETRIC);
        //tabellenheader erneut drucken
        print_line(1, true);
      end;
    end;
    //druckauftrag abschließen
    EndDoc;
  end;
end;

//diese prozedur wird aufgerufen, um den titel zu schreiben
procedure Tfrmprnt.print_title;
begin
  with Printer.Canvas do
  begin
    //größe und aussehen der schrift festlegen
    Font.Size := 4 * 10; //* 10, da 0.1mm ;-)
    Font.Style := [fsbold];
// SetTextAlign(Printer.Handle, TA_RIGHT + TA_TOP);
    //titel schreiben
    TextOut((pgwidth * 10 - TextWidth(title)) div 2, y * 10, title);
  end;
  //mit schreiber um 20 nach unten gehen
  dec(y, 20);
end;

//diese prozedur wird aufgerufen, um text rechtsbündig zu schreiben
//x: position auf x-achse; txt: zu druckender text
procedure Tfrmprnt.print_right(x: Word; txt: ShortString);
begin
  //schreiber auf rechts oben ausrichten
  SetTextAlign(Printer.Handle, TA_RIGHT + TA_TOP);
  //text schreiben
  Printer.Canvas.TextOut(lrand * 10 + x * 10, y * 10, txt);
end;

//diese prozedur wird aufgerufen, um die zeile i der tabelle zu drucken
procedure Tfrmprnt.print_line(i: Word; rowend: Boolean);
var
  j: Byte; //zählvariable
begin
  with Printer.Canvas do
  begin
    //größe und aussehen der schrift festlegen
    Font.Height := 2 * 10;
    Font.Style := [];
    //jede zelle schreiben
    for j := 1 to colpos - 1 do
      print_right(temp[j], table[i, j].text);
    //mit schreiber um drei nach unten gehen
    dec(y, 3);
    //wenn ende der "zeileneinheit" (da mit zeilenumbruch)
    if rowend = true then
    begin
      //stiftgröße festlegen
      Pen.Width := 1;
      //linie vertikal zeichnen
      MoveTo(lrand * 10, y * 10);
      LineTo(prntwidth * 10, (y - 2) * 10);
    end;
  end;
end;
allerdings ist da irgendwo n fehler drin, da:
-die schriftgröße völlig überdimensional ist
-die tabelle nicht zu erkennen ist, da alles übereinander geschrieben wird

kann mir jemand einen tipp geben, oder sagen wo der hund hängt?
(oder auch nen neuen vorschlag achen)

ps:
-mit quickreport wollt ichs nicht machen, da die vertikalen striche nicht richtig dargestellt werden
(ein problem für sich...) und die exe sonst zu groß werden würde!
-die vertikalen striche werden bis jetzt auch bei mir noch nicht behandelt!

hoffe ich hab keine variablendefinitionen ausgelassen, etc.
  Mit Zitat antworten Zitat