FPDF-Problemchen

  • Um Rechnungen und Lieferscheine auszudrucken verwende ich FPDF und das funzt auch so weit ganz gut.
    Zumindest so lange, wie ich die Default-Einstellungen nicht ändere.

    Default ist eingestellt, das er nach 20 Rechnungspositionen eine Folgeseite beginnt. Das klappt auch.
    Nun hat aber die Default-Rechnungsposition nur eine Zeile. Ich brauche aber eine, zwei, drei und manchmal 4 Zeilen je Artikel.

    Das sieht so aus:
    (Einzeilig)
    [ATTACH=CONFIG]935[/ATTACH]


    (Mehrzeilig)

    [ATTACH=CONFIG]936[/ATTACH]

    Der Codeschnipsel dazu:

    Jetzt ist mir absolut nicht klar, wie ich das Ding dazu bringen könnte, das es den Seitenumbruch an der richtigen Stelle macht, wenn ich einzeilige und mehrzeilige Artikel da reindrucken will.
    Muß ich etwa alle Rechnungspositionen jetzt 4-zeilig machen, weil das die maximale Höhe ist und einfach die Anzahl der Positionen von 20 auf z.B. 10 reduzieren?
    Oder geht das eleganter?

    Ausserdem erschließt sich mir der Sinn dieses Dingens ja gar nicht: Zeile 2: ($item_count / 32)

    Ganz spassig wird es, wenn er beginnt Folgeseiten zu drucken :D

    Da druckt er jeweile eine Zelle der nächsten Rechnungsposition in die neue Seite. Sonst ist da nur mein Logo und der Footer. Dann nimmt er eine neue Seite und druckt die nächste Zelle rein.
    WTF?

    [ATTACH=CONFIG]937[/ATTACH][ATTACH=CONFIG]938[/ATTACH][ATTACH=CONFIG]939[/ATTACH]

  • Hm, das Thema hatte ich bei mir auch, exakt das gleiche. Zwei Möglichkeiten:

    1. Du errechnest die Größe des "Artikelbereichs" in Pixel und gehst dann nach dem Wert. Würde ich aber nicht machen, da sehr umständlich und nicht unbedingt korrekt.

    2. Du zählst nicht die Zeilen der Tabelle, sondern die Zeilen selbst, die geschrieben werden.

    "if ((is_long($item_count / 32) && $i >= 20) || ($i == 20)){"

    Das ist eine gute Frage. Übersetzt heißt das ja nur, "erstelle eine neue Seite, wenn das Ergebnis von $item_count / 32 ein Integer ist und zugleich $i >= 20 .... oder wenn $i = 20 ist"

    Für was das aber genau ist, keine Ahnung, das wird im Code nicht wirklich ersichtlich. Die Bedingung is_long() trifft jedenfalls nur zu, wenn $item_count 32, 64, 96 oder ein vielfaches davon ist.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • So, nochmal ich. Habe mal bei mir nachgesehen, wie ich das mache. Muss nun sagen, es gibt noch eine Möglichkeit 3 und die nutze ich.

    Bei mir habe ich das im Script.
    if($pdf->GetY() > 222)
    {
    $pdf->AddPage();
    }

    $pdf->GetY() liefert die aktuelle Position auf der Seite.
    *** Link veraltet ***

    Wenn ich mich recht erinnere, dann ist die Angabe in Millimetern, also in meinem Fall oben: Wenn aktuelle Position größer als 222mm, dann neue Seite anfangen. Nur wie das nun bei Dir reinpasst, gute Frage. FPDF bietet die Funktionalität jedenfalls an.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Ah^^
    Das dürfte es sein :D

    Mittlerweile hab ich das Ding überzeugt, mir jeweils 10 Rechnungspositionen auf die erste Seite zu drucken und dann ne Folgeseite zu erstellen.
    Da wird dann der Tabellenheader am richtigen Platz gedruckt (Menge, Artikel UST usw.) und darunter die folgenden Artikel, bis er beim footer ankommt. Dann wird wieder eine Seite usw.
    Soweit passt es schonmal *schnauf

    Aber jetzt ist natürlich das Problemchen mit den Rechnungspositionen mit weniger als 4 Zeilen noch nicht gelöst...
    Wenn ich 20 einzeilige Positionen habe, dann druckt er auf der 1. Seite halt nur 10 Positionen und fängt dann eine neue Seite an :wall:

    Ich versuch mal Tor 3 :D

    Irgendwie muß das doch zu machen sein, ds die Zeilenhöhe der Rechnungspositionen immer z.B. 20mm sein sollen, egal wie viele Zeilen da drinstehen *grml

    btw: Bei isses aktuell auf mm eingestellt:
    function FPDF($orientation='P',$unit='mm',$format='A4')

    Wer zuerst "Datenschutz" sagt, hat verloren.

  • Zitat

    Irgendwie muß das doch zu machen sein, ds die Zeilenhöhe der Rechnungspositionen immer z.B. 20mm sein sollen


    Auch das geht. Kommt nur drauf an, wie Dein Script da arbeitet. Aber die Zellenhöhe kann man angeben. So gesehen kennt FPDF ja auch keine Zellen oder Tabellen im Sinne von HTML. Das Ding arbeitet mit mm und eigenen Boxen, die dann anhand von x- und y-Positionen ausgerichtet werden. Man kann also sagen, eine Zelle (Box), 30mm breit, 15mm hoch an die Position 100mm von oben und 50mm von links. Die Frage ist hier wirklich nur, wie Dein Script da arbeitet.

    z.B. bei mir:

    Code
    // Header Anfang
    $pdf->SetFont('Arial','BI',10);
    $pdf->Cell($spalte1,6,'Position','TB',0,'L');
    $pdf->Cell($spalte2,6,'Anzahl','TB',0,'L');
    $pdf->Cell($spalte3,6,'Artikel','TB',0,'L');
    $pdf->Cell($spalte4,6,'Einzelpreis','TB',0,'R');
    $pdf->Cell($spalte5,6,'Gesamtpreis','TB',0,'R');
    $pdf->SetFont('Arial','',10);
    $pdf->Ln();
    // Header Ende


    Diese ganzen $spalteX sind die Breitenangaben (vorher im Script festgelegt) und die "6" ist die jeweilige Höhe.
    *** Link veraltet ***

    Ich für meinen Fall habe mir damals eine Rechnung mit Word erstellt, so wie ich sie haben will. Und dann mit FPDF so lange die Zellen hin und her geschoben, bis die deckungsgleich waren wie meine Rechnungsvorlage.

    Header und Footer sind immer auf jeder Seite und fix positioniert. Der Anfang der Artikelliste auch. Die Länge ist variabel, so wie bei Dir. Und da kommt dann eben mit $pdf->GetY() dynamisch ein Seitenwechsel mit rein.

    Allerdings ist Dein verschobener Header / Footer nicht normal. Wie wird der denn generiert? Auch per Cell und Positionsangaben? Wenn ja, dann liegt hier der Fehler und irgendwo wird der x bzw y Wert nicht resetet. FPDF hat aber gerade für Header und Footer die Möglichkeit, eine eigene Funktion zu erstellen, dann sind beide immer exakt an der gleichen Stelle, auf jeder Seite.

    Schaut das bei Dir so in etwa aus?

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Also ich hab die Zellenhöhe jetzt hingekriegt^^
    Sogar besonders schmutzig.

    PHP
    $pdf->MultiCell(10,$rowheight=14,$order->products[$i]['qty'] . '',1,'A');


    $rowheight=14
    14mm reichten auch :D

    Allerdings fehlt mir jetzt immer bei der letzten Zellenreihe bei den Artikeln die border bottom, weil ich die Zelle mit LTR abschließen muß.
    Sonst steht bei einzeiligen Positionen nach der ersten Reihe eine border bottom. Und das sieht voll Kagge aus.

    Derzeit bin ich schon mal so weit gelangt:
    [ATTACH=CONFIG]940[/ATTACH][ATTACH=CONFIG]941[/ATTACH]

    Und gegen diese fehlende border bottom werd ich auch noch irgendwie wa reinfrickeln können. Vielleicht.

  • Automatisch signieren kannst Du die schon. Wenn das aber gemäß UST-Gesetz sein soll, dann wird das entweder aufwändiger oder kostspieliger.

    1. Version:
    Ein eigener Signaturserver und ein eigener Tresor. In aller Regel einmalige Kosten, aber sehr aufwendig.

    2. Version:
    Externe Signaturanbieter. Laufende kosten pro Rechnung. Externer Tresor und auch hier laufende Kosten pro Rechnung im Tresor.

    Tresor bedeutet: "Sicheres Archiv" mit Zertifizierung bzw. entsprechendem Standard. Das Speichern auf der Festplatte, USB oder DVD zählt als nicht sicher. Auch einfach so auf dem Webspace reicht nicht.

    Die zweite Version funktioniert nach zwei Möglichkeiten. Entweder Du sendest die Rechnung an den Dienstanbieter, der signiert und sendet direkt an den Empfänger weiter oder, Du sendest an den Dienstanbieter, der signiert und sendet an Dich zurück. Du sendest dann an den Empfänger weiter. Der Dienstanbieter betreibt in aller Regel auch den Tresor, in dem die Signaturen abgelegt werden und durch den Empfänger geprüft werden können.

    Oder was meinst Du mit signieren genau?

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Das UST-Gesetz ist mir hier ja herzlich wurscht :D

    Ich meine einfach diese Persönliche Signatur, die ich z.B. im Adobe Writer auch machen kann.
    Damit am Ende des PDFs ein Prüfcode erscheint und die Nachricht: "Dieses PDF wurde durch Firma yxz erstellt und signiert".

    Kann man die per FPDF erstellten PDFs auch vor Veränderung schützen? Ansehen ja. Drucken ja. Verändern nein.

    Wer zuerst "Datenschutz" sagt, hat verloren.

  • Hm, jetzt fragst Du mich was. Sind die Dinger denn nicht schreibgeschützt?

    Wegen dem Prüfcode. Gute Frage, so einen kenne ich nicht. Wäre nun die Frage, was da im Code enthalten ist. Der Inhalt des PDF oder die PDF-Datei an sich? Ersteres sollte man mit PHP einfach so lösen können, unabhängig vom PDF. Bei letzterem müsste man das PDF quasi speichern, als Text öffnen um den eigentlichen Quellcode zu bekommen und daraus den Code errechnen. Das sollte noch kein Problem sein, nur jetzt muss der Code ja auch in das zuvor schon geschriebene PDF.... Gehen tut das irgendwie, denn fertige Signierer (Signaturianten, oder wie auch immer) gibt es ja für FPDF.

    *** Link veraltet ***

    Wenn man da nun die Class kennen würde, dann könnte man das direkt nachbauen ...

    Edit:
    In der Tat, nicht schreibgeschützt... Hatte ich noch gar nicht bemerkt...
    [ATTACH=CONFIG]944[/ATTACH]

  • Aso. Wegem Prüfcode:

    Ich kann halt z.B. eine Unterschriftengrafik einbauen und/oder eine Grafik meines Stempels.
    Drunter steht dann: "Dieses Dokument wurde signiert von [Name der im PDF-Writer angegeben wurde] am [Datum].
    Dann steht noch klein eine Prüfsumme drin, die sich aus Grösse, Datum uns weiß-der-geier errechnet. Ein Hash halt. Die ist auch in den Metas gespeichert.
    Wenn nun jemand das Dokument trotz Schreibschutz verändert oder die Signatur einfach als Grafik in ein neues PDF einfügt, dann muß ich das nur mit einem PDF-Writer öffnen, der meine Signatur gespeichert hat und ich sehe genau, ob das Dokument valide, also unverändert, ist.
    Das funzt wohl mit Privatem und Öffentlichem Key.

    Die Signatur und mein Key ist natürlich nicht "amtlich". Aber es macht irgendwie Eindruck und 99% der Leute wissen eh nicht, ob/was dsa jetzt nützen soll, ausser das es Wichtig aussieht.

    Wer zuerst "Datenschutz" sagt, hat verloren.

  • Hm, also ehrlich muss ich da jetzt sagen, dass ich das sehr spannend finde, es aber irgendwie meinen Horizont übersteigt. Gehen tut das sicherlich, nur wie, keine Ahnung, leider.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(