Tutorial – PDF-Rechnung mit PHP erzeugen

Ich habe nun endlich das zweite Tutorial zu PDF mit PHP erzeugen gemacht.

Diesmal gehts um eine PDF-Rechnung.

zum Tutorial PDF-Rechnung mit PHP erzeugen

Wie immer die Fragen, Anregungen usw. zum Tutorial gleich hier als Kommentar posten ;-)

Viel Spaß!

55 Kommentare

  1. 1. Bert

    Kommentar vom 19. Mai 2009 um 15:46

    Hallo.
    Das Thema “PDF erzeugen” ist genau das was ich brauchen kann.
    Das Beispiel aus dem 1. Tutorial läuft top.
    Beim 2. Beispiel “Rechnung” jedoch bekomme ich nur den pdf-text im Explorer angezeigt, aber nicht als PDF interpretiert.
    Wo muss ich vielleicht noch was drehen?
    Ein Hinweis oder die Beantwortung meiner Frage wäre hilfreich.
    Danke.

  2. 2. Thomas

    Kommentar vom 19. Mai 2009 um 16:35

    Falls das Problem nur bei deinem Internet Explorer auftritt, könnte es eventuell an folgendem liegen (ich poste mal den Original-Text):

    Diese “wirren” Zeichen sind der tatsächliche Inhalt des PDF Dokuments der durch den Acrobat Reader interpretiert und dargestellt wird. Dieses Verhalten ist ein Bug im Internet Explorer. Wenn der Internet Explorer unter ein und derselben URL zuerst ein HTML Dokument und danach ein PDF Dokument erhält, wird dieses direkt, ohne den Acrobat Reader zu starten ausgegeben. Dieses Verhalten tritt meistens während der Entwicklung eines Script auf: Das Script hat einen Fehler und eine Fehlermeldung des Parseres wird als HTML an den Browser gesendet. Nachdem der Fehler behoben wurde und das Script ausgeführt wird, sendet dieses ein PDF Dokument und der obige Sachverhalt tritt ein. Um dieses Problem zu lösen kann ein Neustart des Internet Explorers vorgenommen werden, oder vor dem nächsten Aufruf eine andere URL geöffnet werden. Um dieses Verhalten zu umgehen, sollte das PDF Dokument während der Entwicklung als Datei erzeugt werden die dann geöffnet werden kann.

    Gib mal Bescheid, ob es daran lag.

  3. 3. Bert

    Kommentar vom 20. Mai 2009 um 09:35

    Danke Thomas.
    Während meiner Tests hat es nach ein paar Versuchen verblüffenderweise plötzlich auch funktioniert. Im weiteren Verlauf bin ich dann auch auf die Erklärung zu dem IE-Bug gestossen und habs damit bestätigt gesehen und soweit abgehakt.

    Nochmals Danke für Deine schnelle Antwort.
    Werde jetzt FPDF in meine Anwendung integrieren.

  4. 4. inspiron

    Kommentar vom 13. September 2009 um 16:18

    Hallo,
    ich möchte ein eigenes Logo einfügen, bekomme aber folgende Fehlermeldung:
    FPDF error: Alpha channel not supported: fpdf/klasse/FWP.png
    Was kann ich da machen?

    Gruß

  5. 5. Thomas

    Kommentar vom 13. September 2009 um 18:18

    FPDF unterstützt von Haus aus kein bei png-Bildern keinen Alpha-Channel.
    Eine Lösung dieses Problems wird hier vorgestellt, ich selbst hab das aber nicht probiert, sieht auch recht kompliziert aus.
    Am Einfachsten ist es, wenn Du das Bild als gif speicherst. Damit sollte FPDF keine Probleme haben.

  6. 6. inspiron

    Kommentar vom 1. November 2009 um 19:07

    Hallo,
    ich möchte den Ausschnitt “twShowRechnungspositionen()”mit Daten aus einer Datenbank füllen.
    Soweit funktioniert es, nur werden alle augelesenen Daten übereinander “// Tabellenzeile (mit MultiCell)” geschrieben. (alles in einer ZeileY “$this->SetXY(18, 45);”
    Leider habe ich es mit Schleifen nicht so drauf. Wie muß die Schleife für Y aussehen damit es passt?
    Gruß


    private function ShowPositionen() {

    // Spaltenbreiten und Beschriftung der Spalten & Zeilenköpfe festlegen
    $this->twSetSpaltenbreiten(array(8, 35, 40, 35, 18));
    $this->twSetSpaltenkoepfe(array('Pos', 'Name', 'Beschreibung', 'Uhrzeit', 'Dauer in Min' ));

    // Tabellenköpfe (nur mit Cell)
    $this->SetFillColor(244);
    $this->SetTextColor(000);
    $this->SetLineWidth(.3);
    $this->SetFont('Arial', 'B', '10');
    $this->SetXY(18, 38);
    for ($i=0; $itwArrSpaltenkoepfe); $i++) {
    $this->Cell($this->twArrSpaltenbreiten[$i], 7, $this->twArrSpaltenkoepfe[$i], 1, 0, 'C', 1);
    }
    $this->ln();

    // Datenbankzugriff
    .
    .
    .
    while($row = mysql_fetch_array($result))
    {

    // Tabellenzeile (mit MultiCell)
    $this->SetFillColor(224, 235, 255);
    $this->SetFont('Arial', '', 8);
    $this->SetXY(18, 45);
    $i = 0;
    foreach ($this->twArrRechnungspositionen as $pos) {
    $i++;
    $this->twShowZeileMitMultiCell(array(
    $i,
    $row['NAME'],
    $row['BESCHREIBUNG'],
    $row['UHRZEIT'],
    $row['DAUER'],
    ));

    // Box für Details & Beschreibungen
    $this->SetFillColor(244);
    $this->SetTextColor(000);

    $this->SetFont('Arial','B','9');
    $this->SetXY(18, 50);
    $this->MultiCell(43, 15, 'Details', 1, 'L'); // (breite, höhe.....)
    $this->SetFont('Arial','','8');
    $this->SetXY(61, 50);
    $this->MultiCell(138, 3, $this->Beschreibung['details'], 1, 'J');
    .
    .
    .

  7. 7. inspiron

    Kommentar vom 2. November 2009 um 11:39

    ..ich habe es so geändert

    //$this->SetXY(18, 45);
    $this->SetXY(18, $this->GetY());
    …das ist o.k.

    Nun wird aber die 2. MultiCell in der nächsten Zeile positioniert, ich möchte diese aber nebeneinander haben. Was muss ich da ändern?

    Gruß


    $this->SetFont('Arial','B','9');
    //$this->SetXY(18, 50);
    $this->SetXY(18, $this->GetY());
    $this->MultiCell(43, 15, 'Details', 1, 'L'); // (breite, hˆhe.....)
    $this->SetFont('Arial','','8');
    //$this->SetXY(61, 50);
    $this->SetXY(61, $this->GetY());
    $this->MultiCell(138, 15, $this->twArrBeschreibung['details'], 1, 'J');

  8. 8. Thomas

    Kommentar vom 2. November 2009 um 12:29

    Du musst mit SetXY die Position rechts von der Multicell direkt angeben.
    Bsp:
    $this->MultiCell(43, 15, ‘Details’, 1, ‘L’);
    //die Position (rechts von der MultiCell) setzen
    $x = $this->GetX() + 43;
    $y = $this->GetY();
    $this->SetXY($x, $y);

    Habs jetzt nich ausprobiert, aber so müsste es gehen.

  9. 9. inspiron

    Kommentar vom 2. November 2009 um 13:03

    …danke,
    aber sie wird immer noch in der nächsten Zeile angezeigt.:-(


    $this->SetFont('Arial','B','9');
    $this->SetXY(18, $this->GetY());
    $this->MultiCell(43, 15, 'Details', 1, 'L'); // (breite, hˆhe.....)
    $this->SetFont('Arial','','8');
    $x = $this->GetX() + 51; //die Position (rechts von der MultiCell) setzen
    $y = $this->GetY();
    $this->SetXY($x, $y);
    $this->MultiCell(173, 15, $this->twArrBeschreibung['details'], 1, 'J');

  10. 10. Thomas

    Kommentar vom 2. November 2009 um 13:24

    Kann es sein, dass deine zweite Multicell ansich nicht mehr in der Breite reinpasst mit 173 und deshalb eine neue Zeile losgeht?

  11. 11. inspiron

    Kommentar vom 2. November 2009 um 13:30

    …das hatte ich auch erst gedacht,
    habe die Zellenbreite auf 50 geändert, es bleibt so.
    Die horizontale Anordnung passt, nur am Ende der 1. Zelle beginnt in der 2. Zeile die 2. MultiCell

    Gruß

  12. 12. Thomas

    Kommentar vom 2. November 2009 um 13:33

    Ist eventuell irgendwo noch ein
    $this->Ln($h);
    versteckt ??

  13. 13. inspiron

    Kommentar vom 2. November 2009 um 13:47

    …anbei die komplette Position.
    private function twShowRechnungspositionen() {

    // Spaltenbreiten und Beschriftung der Spalten & Zeilenkˆpfe festlegen
    $this->twSetSpaltenbreiten(array(8, 35, 40, 35));
    $this->twSetSpaltenkoepfe(array('Pos', 'Name', 'Uhrzeit', 'Dauer in Min'));

    // Tabellenkˆpfe (nur mit Cell)
    $this->SetFillColor(244);
    $this->SetTextColor(000);
    $this->SetLineWidth(.3);
    $this->SetFont('Arial', 'B', '10');
    $this->SetXY(18, 38);
    for ($i=0; $itwArrSpaltenkoepfe); $i++) {
    $this->Cell($this->twArrSpaltenbreiten[$i], 7, $this->twArrSpaltenkoepfe[$i], 1, 0, 'C', 1);
    }
    $this->ln();

    // Datenbankzugriff
    require("admin/includes/config.php");

    $kategorie = "PP2.2"; //testabfrage

    // Verbindung oeffnen und Datenbank ausweahlen
    $conID = mysql_connect( $db_host, $db_user, $db_pass ) or die( "Die Datenbank konnte nicht erreicht werden!" );
    if ($conID)
    {
    mysql_select_db( $db_name, $conID );
    }
    // Anfrage zusammenstellen um die Datensaetze auszulesen
    $result=mysql_query("SELECT * FROM tabelle WHERE (`kategorie` LIKE '".addslashes($kategorie)."')ORDER BY `ID` DESC");

    while($row = mysql_fetch_array($result))
    {

    // Tabellenzeilen (mit MultiCell)
    $this->SetFillColor(224, 235, 255);
    $this->SetFont('Arial', '', 8);
    //$this->SetXY(18, 45);
    $this->SetXY(18, $this->GetY());
    $i = 0;
    foreach ($this->twArrRechnungspositionen as $pos) {
    $i++;
    $this->twShowZeileMitMultiCell(array(
    $i,
    $row['NAME'],
    $row['UHRZEIT'],
    $row['DAUER'],
    ));

    // Box f¸r Details & Beschreibungen
    $this->SetFillColor(244);
    $this->SetTextColor(000);

    $this->SetFont('Arial','B','9');
    $this->SetXY(18, $this->GetY());
    $this->MultiCell(43, 15, 'Details', 1, 'L'); // (breite, hˆhe.....)
    $this->SetFont('Arial','','8');
    $x = $this->GetX() + 51; //die Position (rechts von der MultiCell) setzen
    $y = $this->GetY();
    $this->SetXY($x, $y);
    $this->MultiCell(50, 15, $this->twArrBeschreibung['details'], 1, 'J');

    $this->SetFont('Arial','B','9');
    //$this->SetXY(18, 95);
    $this->SetXY(26, $this->GetY());
    $this->MultiCell(75, 6, 'Bemerkungen', 1, 'L'); // (breite, hˆhe.....)
    $this->SetFont('Arial','','8');
    //$this->SetXY(61, 95);
    $this->SetXY(26, $this->GetY());
    $this->MultiCell(173, 15, $this->twArrBeschreibung['bemerkungen'], 1, 'J');
    $this->SetFillColor(210);
    $this->SetTextColor(000, 000, 102);
    $this->ln(5);
    $this->SetX(18); // sonst gehts immer ganz links los...
    }
    $this->Cell(array_sum($this->twArrSpaltenbreiten), 0, '', 'T'); //Tabellenlinie unten

    }
    }
    /**
    * Wird bei mehreren Seiten nur auf der letzten Seite angezeigtzeigt.

  14. 14. Thomas

    Kommentar vom 2. November 2009 um 14:01

    Du musst in der Schleife hinter:

    $row['DAUER'],

    folgende Zeile einfügen (siehe Tutorial)

    $this->SetX(27); // sonst gehts immer ganz links los…

    (und mach das Komma weg bei $row['DAUER'],)

  15. 15. inspiron

    Kommentar vom 2. November 2009 um 15:31

    …danke nochmal für die Hilfe!
    Der Versatz ist immer noch. :-(

    $row['NAME'],
    $row['UHRZEIT'],
    $row['DAUER'],
    ));
    $this->SetX(27);

    // Box f¸r Details & Beschreibungen
    $this->SetFillColor(244);
    $this->SetTextColor(000);

  16. 16. Thomas

    Kommentar vom 2. November 2009 um 15:41

    foreach ($this->twArrRechnungspositionen as $pos) {
    $i++;
    $this->twShowZeileMitMultiCell(array(
    $i,
    $pos['text'],
    sprintf(“%9.2f”, $pos['menge']),
    sprintf(“%9.2f”, $pos['einzelpreis']),
    sprintf(“%9.2f”, $pos['gesamtpreis'])
    ));
    $this->SetX(27); // sonst gehts immer ganz links los…
    }

  17. 17. inspiron

    Kommentar vom 2. November 2009 um 19:14

    …ich habe es jetzt so gelöst.
    Der 2.MultiCell habe ich den Wert -15 verpasst
    $y = $this->GetY()-15; und somit ist diese wieder neben der 1. MultiCell. :-)

    2.Frage:
    Leider finde ich nichts, wie kann ich den Zeilenabstand in einer MultiCell einstellen.

    $this->SetFont('Arial','','6');
    $x = $this->GetX() + 8; //die Position (rechts von der MultiCell) setzen
    $y = $this->GetY();
    $this->SetXY($x, $y);
    $this->MultiCell(35, 15, 'Details', 1, 'L');
    $this->SetX(18);

    $this->SetFont('Arial','','6');
    $x = $this->GetX() + 43; //die Position (rechts von der MultiCell) setzen
    $y = $this->GetY()-15;
    $this->SetXY($x, $y);
    $this->MultiCell(138, 15, $this->twArrBeschreibung['details'], 1, 'J');
    $this->SetX(18);

  18. 18. Thomas

    Kommentar vom 2. November 2009 um 19:29

    Nur ma zum “Fehlerausschluss”, mal die aus der Datenbank ausgelesenen Werte mit einfachen Strings ersetzen. Nicht dass irgendwelche Zeilenumbrüche in den aus der DB ausgelesenen Werten enthalten sind.

  19. 19. inspiron

    Kommentar vom 23. November 2009 um 16:19

    Hallo,
    ich habe da wieder ein Problem auf der Seite TwPdfRechnung.php.

    In den beiden folgenden Zellen werden Datum und Kategorie angezeigt. soweit i.O.


    $this->Cell(20, 5, $this->twArrRechnungsdaten['datum'], 1, 1, '');
    $this->Cell(30, 5, $this->twArrRechnungsdaten['kategorie'], 1, 1, '');

    Weiter unten werden Daten aus einer Datenbank abgerufen.
    Als Such-Variable soll der Wert von “twArrRechnungsdaten['kategorie'],..datum” verwendet werden.
    Leider habe ich da kein Erfolg, was kann da falsch sein?
    Wenn ich die Werte “//$DATUM = “2009-10-17″;
    //$KATEGORIE = “PP2.2″;” fest zuordne, dann funktioniert es!

    Gruß


    $DATUM = . $this->twArrRechnungsdaten['datum'];
    $KATEGORIE = . $this->twArrRechnungsdaten['kategorie'];

    //$DATUM = "2009-10-17";
    //$KATEGORIE = "PP2.2";

    // Anfrage zusammenstellen um die Datensaetze auszulesen
    $result=mysql_query("SELECT * FROM tabelle WHERE (`DATUM` LIKE '".addslashes($DATUM)."' AND `KATEGORIE` LIKE '".addslashes($KATEGORIE)."')ORDER BY `ID` DESC");
    while($row = mysql_fetch_array($result))
    .
    .
    .

  20. 20. Thomas

    Kommentar vom 23. November 2009 um 16:28

    Kontrolliere mal das Datum, was du aus der Datenbank ausliest, beswtimmt ist da irgendein Fehler drin, Leerzeichen oder was weiß ich. Meist liegts daran.
    Übrigens:
    Wie ist die letzte Sache mit den Zeilenumbrüchen ausgegangen. Hatte es am Ende geklappt?

  21. 21. inspiron

    Kommentar vom 23. November 2009 um 16:59

    Mit
    $DATUM = . $this->twArrRechnungsdaten['datum'];
    $KATEGORIE = . $this->twArrRechnungsdaten['kategorie'];

    bekomme ich diese nicht ausgelesen.
    Ich kann sie nur auslesen wenn ich die Variablen fest eingebe

    $DATUM = "2009-10-17";
    $KATEGORIE = "PP2.2";

    Mit der letzten Sache bin ich noch nicht weiter, konnte erst letzte Woche weiter machen.

  22. 22. inspiron

    Kommentar vom 24. November 2009 um 13:19

    …gelöst!
    Es lag am falschen Datumsformat.

    Gruß

  23. 23. Jürgen Schulze

    Kommentar vom 17. Dezember 2009 um 11:19

    Hallo,
    vielen Dank für dieses vorzügliche Skript.
    Ich werde es für meine Zwecke anpassen.
    Danke
    Jürgen Schulze

  24. 24. Olli

    Kommentar vom 19. Januar 2010 um 08:18

    Hallo Thomas,
    Vielen Dank erstmal für die tollen Erklärungen und das Beispiel zum Rechnungsdruck. Ich habe es nun angepasst und bestücke die Rechnung mit meinen Daten aus der DB. Nun möchte ich aber gerne nicht nur eine Rechnung, sondern mehrere Rechnungen auf einmal ausdrucken. Ich habe hierzu die Sessiondaten in ein Array gelegt und in TwPdfRechnung.php den Konstruktor angepasst, so daß dort alle Rechnungen in einer Schleife laufen sollen:

    public function __construct() {

    // Konstruktor der vererbenden Klasse (FPDF) aufrufen
    parent::__construct(‘P’, ‘mm’, ‘A4′); // L=Querformat(Landscape), P=Hochformat(Portrait)

    // Session-Variablen aus dem aufrufenden Skript übernehmen
    $this->twArrRechnungsdatenGes = $_SESSION['twArrRechnungsdaten'];
    $this->twArrRechnungspositionenGes = $_SESSION['twArrRechnungspositionen'];
    for ($x=0; $xtwArrRechnungspositionenGes); $x++)
    {
    $this->twArrRechnungsdaten = $this->twArrRechnungsdatenGes['$x'];
    $this->twArrRechnungspositionen = $this->twArrRechnungspositionenGes['$x'];

    // Einstellungen für das PDF
    $this->SetDisplayMode( 100 ); // wie groß wird Seite angezeigt(in %)
    $this->SetAutoPageBreak(true, 43); // 43mm von unten erfolgt ein Seitenumbruch hierhier
    $this->AliasNbPages(); // Anzahl der Seiten berechnen ({nb}-sache)

    // Seite erzeugen
    $this->AddPage(); // PDF starten (ruft auch Header() und Footer() auf

    // zusätzliche Sachen
    $this->twShowRechnungspositionen(); // Tabelle mit allen Rechnungspositionen
    $this->twShowLetzteSeite(); // nur auf der letzten Seite
    } // ($x=0; $x<sizeof($theArray); $x++)
    }

    Leider wird aber immer nur die 1. Rechnung, welche übergeben wird erzeugt und keine weitere. Da habe ich irgeneinen blöden Fehler drinnen, den ich gerade nicht finde.

  25. 25. Thomas

    Kommentar vom 19. Januar 2010 um 09:44

    Upps, das würd ich nicht in der Klasse machen, das da mehrere Dateien generiert werden.
    Wenn du dein Array aus der Datenbank sowieso schon fertig geladen hast ehe du die pdf-Klasse aufrufst, dann würd ich die Schleife auch dort schon platzieren und dann sozusagen die pdf-Datei in der Schleife jedesmal neu erstellen und auf den Server schreiben. Musste dir aber für die Dateinamen irgendeinen Zähler mit einbauen, dass diese nicht jedesmal wieder überschrieben wird.

  26. 26. Olli

    Kommentar vom 19. Januar 2010 um 09:55

    Daran habe ich auch schon gedacht. Dann muß ich aber wieder jede einzele Rechnung mit PDF öffnen und ausdrucken. Ich würde aber gerne z.B. 30 verschiedene Rechnungen auf einmal erzeugen und dann mit einem Drucken diese alle auf einmal auf den Drucker bringen.

  27. 27. Thomas

    Kommentar vom 19. Januar 2010 um 10:01

    Dann müsstest du alles in eine Datei bringen, das gibt aber Probleme mit Header, Footer usw.
    Da sehe ich eigentlich keine Lösung…

    Du wirst das schon über eigenständige Dateien bzw. PDF’s lösen müssen :(

  28. 28. Max Power

    Kommentar vom 17. Mai 2011 um 14:51

    Hallo
    ich habe eine Frage.
    In dem Beispiel werden die Positionen in der Rechnung immer vollständig auf einer Seite angezeigt. Wenn jedoch ein Artikelposition einen sehr langen Text über mehr als eine Seite hat, so funktioniert der Umbruch nicht korrekt und die Tabellenrahmen gehen über den vordefinierten Bereich raus bzw. fehlen teilweise.
    Ist es zu realisieren, dass auch Umbrüche in dem Artikeltext umgebrochen werden können?

  29. 29. Stefan

    Kommentar vom 11. Mai 2012 um 19:51

    Hallo,

    ich habe eine Frage zu dem Script, habe nun mein ganze Seite geändert da dieses Script leider kein Rechnungssystem hatte nun habe ich alles angepasst und alles erforderliche eingebaut und so das wenn einer auf sein pdf-icon klickt eine Rechnung mit diesem Script hier erstellt wird.

    Dies klappt auch alles wunder bar, leider erscheint in der Rechnung aber eine Position zuwenig =( ich vermute das es die erste Position ist die fehlt.

    Hier mal die Änderungen an dem Array für die Posten:

    // die Rechnungspositionen
    $arrPos = array();
    $pos = 0;
    while ($row = mysql_fetch_assoc($res))
    {
    $menge = 1;
    $einzelpreis = $row['amt'] – ($row['amt']*0.19);
    $arrPos[$pos] = array(
    ‘text’=>’Gebühren, Auktion-ID: ‘.$row['auc_id'].” vom: “.date(“d.m.Y”, $row['date']),
    ‘menge’ => $menge,
    ‘einzelpreis’ => $einzelpreis,
    ‘gesamtpreis’ => $einzelpreis * $menge,
    );
    $pos++;
    }

    Wäre sehr dankbar für einen Tip

    MFG: Stefan

  30. 30. Julian

    Kommentar vom 5. Juni 2012 um 21:13

    Hallo,

    erst einmal herzlichen Dank für die Entwicklung der PDF-Erstellung.

    Ist es möglich, die Position der Positionstabelle ab der zweiten Seite nach unten zu verschieben? Wenn ja, wo finde ich das im Code?

    Vielen Dank & viele Grüße
    Julian

  31. 31. Daniel B.

    Kommentar vom 17. Oktober 2012 um 22:44

    Hallo,
    dein Tutorial ist echt klasse und ich konnte die PDF auch schon nach meinen Bedürfnissen anpassen.

    Ich möchte aber die Tabelle mit Daten aus der Datenbank bestücken. Ich habe zwar in den Kommentaren schon was über das Thema gelesen, nur leider hilft mir das nicht ganz weiter.

    Vielleicht kannst du mir erläutern, wo ich den Code anpassen bzw. erweitern muss, damit ich das umsetzen kann. Mir fehlt ehrlich gesagt auch der überblick…

    Vielen Dank

    Daniel

  32. 32. Thomas

    Kommentar vom 18. Oktober 2012 um 08:46

    Um die Rechnungstabelle mit Daten aus einer Datenbank zu bestücken muss einfach das ‘$arrPos’ in der Datei ‘rechnung.php’ dementsprechend mit den Werten aus der Datenbank gefüllt werden.
    Wie man Werte aus einer Datenbank ausliest gehört eigentlich nicht in dieses Tutorial hier. Falls das ganz neu für dich ist, kannst du eventuell erstmal hier nachlesen.

    Falls du gar nicht klarkommst und es die Sache wert ist schreib mich an, dann kann ich auch (kostenpflichtig) ein Skript nach deinen Ansprüchen erstellen.

  33. 33. Stefan

    Kommentar vom 23. November 2012 um 10:01

    Hallo,

    wirklich gutes Tutorial und gute PHP-class, vielen Dank dafür!

    Nun ich würde gerne die Zahlen die Ausgegeben werden ein wenig formatieren.
    Bei Menge zb. da habe ich nur Ganze zahlen benötige also die Nachkommastelle nicht.

    Als zweites versuche ich den Punkt durch ein Komma zu ersetzten wir leben ja nicht in den USA =)

    Leider blick ich da überhaupt nicht durch wo die Zahlen formatiert werden, ich wäre über Hilfe sehr sehr dankbar!

    MFG: Stefan

  34. 34. Thomas

    Kommentar vom 23. November 2012 um 10:46

    Hallo Stefan,

    die “Formatierung” der Zahlen sollte vorher erfolgen. Trotzdem eventuell noch zwei Tipps:

    Die Beträge der Rechnungspositionen haben ja mit dem PDF in dem Sinne gar nichts zu tun, sondern werden irgendwo vorher ermittelt (in der Demo in der Datei rechnung.phpso etwa bei Zeile 20).

    Zum zweiten kann man jedoch im pdf-Skript die Ausgabe auch noch ein wenig steuern. Suche in der TwPdfRechnung nach Zeilen mit “sprintf(“. Wenn da sowas wie “%9.2f” steht, bedeutet das eine “Kommazahl mit zwei Nachkommastellen.
    “%9.3f” würde drei Nachkommastellen und “%9.0f” (oder “%9d”) keine Nachkommastellen bedeuten. ;-)

    Die Punkt-Komma-Sache bekommt man in PHP im Allgemeninen so hin:
    $strAlt = ’12,34′;
    $strNeu = str_replace(‘,’, ‘.’, $strAlt);

    …Aber wie oben schon gesagt, die Zahlen sollten vor der Verwendung im PDF-Skript schon “formatiert” sein.

  35. 35. Stefan

    Kommentar vom 23. November 2012 um 14:07

    Hallo,

    ok Danke, das mit der Nachkomastelle hat schon mal funktioniert. Aber das mit dem Formatieren klappt nach wie vor nicht…

    Wird das nicht in der twPDF classe definiert?
    Egal was ich mache also natürlich in der rechnung.php entweder nimmt er das nciht und schriebt nur 0.00 oder er macht halt immer 4.99 aber ich bekomme zum verrecken kein Komma dort hin o.O

  36. 36. Thomas

    Kommentar vom 23. November 2012 um 14:28

    str_replace(‘.’, ‘,’ ’12.34);
    gibt ’12,34′ aus
    ~~~~~~~~~~~~

  37. 37. Stefan

    Kommentar vom 23. November 2012 um 15:31

    Hallo,

    Danke für deine Mühe, aber wie gesagt, es funktioniert nicht, aus Testzwecken habe ich dierechnung.php angepasst und habe folgende Zeile:

    $arrPos[0]['einzelpreis'] = str_replace(‘.’, ‘,’, 12.34);

    Im PDF-Dokument erscheint weder das Komma noch die Nachkommastelle 34.
    Wie gesagt ich kann des alles drehen und wenden und auch mit number_format habe ich es versucht, es klappt einfach nicht!

  38. 38. Thomas

    Kommentar vom 23. November 2012 um 15:46

    Du musst unterscheiden zwischen float und String.
    Float geht nicht mit Komma und String geht (in diesem Beispiel) nicht zum Berechnen.

    So, wenn du nix berechnen willst, sondern nur die Ausgabe haben willst, dann schreib’s in der rechnung.php doch gleich so wie es ausgegeben werden soll, also als String:
    $arrPos[0]['einzelpreis'] = ’20,00′;
    und lass im pdf das sprintf weg, also anstatt:
    sprintf(“%9.2f”, $pos['einzelpreis']),
    nur:
    $pos['einzelpreis'],

    Aber du solltest die String-Float-Sache wirklich erst ganz begreifen/verinnerlichen, sonst kommst du immer wieder damit in Konflikt. Man kann die Sache auch auf vielen anderen Wegen lösen, meins war nur ein sehr einfaches Beispiel…

    Wie gesagt, das hat aber mit der pdf-Erstellung ansich nix zu tun.

  39. 39. Stefan

    Kommentar vom 23. November 2012 um 18:21

    Hallo,

    na klar mit der PDF-Erstellung ansich nicht, aber war halt etwas unklar warum beim erzeugen dort immer auf die blöden Punkte behart wird.

    Naja minimal gerechnet wird da schon, aber dein Beispiel ist da doch sehr verständlich und genau das was mein Problem löst. Sofern das sprintf() nicht entfernt wird, wird er da wohl immer Punkt statt Komma setzen und ohne des wird bestimmt auch meine Formatierung Im Vorfeld klappen, werde es heut Abend mal noch ausprobieren!

    Vielen vielen lieben Dank!

    MFG: Stefan

  40. 40. Bill

    Kommentar vom 21. Februar 2013 um 14:24

    Hallo,

    wo kann ich einstellen, dass der Seitenumbruch eine Zeile früher durchgeführt wird?

    MfG

    Bill

  41. 41. Thomas

    Kommentar vom 21. Februar 2013 um 15:36

    In der TwPdfRechnung.php mit SetAutoPageBreak().
    So in etwa die Zeile 45:
    $this->SetAutoPageBreak(true, 50); // 50mm von unten erfolgt ein Seitenumbruch

  42. 42. Bill

    Kommentar vom 26. Februar 2013 um 16:56

    Hi,
    vielen Dank.
    Ist es auch möglich unterhalb der Tabelle eine Multi cell anzuhängen? Damit direkt nach der Tabelle noch beliebiger Text kommt.

    MfG

    Bill

  43. 43. Thomas

    Kommentar vom 27. Februar 2013 um 07:33

    Unterhalb der Tabelle kann man ganz normal MulziCell’s, Cell’s usw. einbringen.

  44. 44. Bill

    Kommentar vom 27. Februar 2013 um 11:21

    Hi

    ok, jetzt wird leider im Text, welcher nach der Tabelle kommt umbrochen.
    Ist es auch möglich den Seitenumbruch so zu setzen, dass der Text immer zusammen bleibt?

    Schönen Gruß

    Bill

  45. 45. Thomas

    Kommentar vom 27. Februar 2013 um 12:01

    Sollte mit
    twCheckSeitenumbruch()
    funktionieren.

  46. 46. Bill

    Kommentar vom 27. Februar 2013 um 12:59

    Hallo,

    in twCheckSeitenumbruch kann ich ja nur an der höhe drehen, funktioniert auch nicht so wie ich mir das vorstelle.

    Wenn ich die höhe des Textes dazurechne hab ich auf der ersten Seite zu viel Platz.

    Hast du vielleicht noch eine Idee?

    Gruß

    Bill

  47. 47. Thomas

    Kommentar vom 27. Februar 2013 um 13:05

    Am Besten guckst du dir ab wie in der Funktion
    twShowZeileMitMultiCell()
    die $hoeheGesamt ermittelt wird, um damit dann zu checken, ob ein Seitenumbruch (mit twCheckSeitenumbruch() ) nötig ist.

  48. 48. Bill

    Kommentar vom 27. Februar 2013 um 15:04

    Hi

    ich habe jetzt eiine zweite Funktion twShowZeileMitMultiCell() geschrieben.

    Sollte nun der Text auf der ersten Seite Platz haben wird der Inhalt ganz links dargestellt.

    Auf der Zweiten Seite würde es passen.

    Wie bekomme ich das noch gebacken?

    Danke nochmals

    Gruß

    Bill

  49. 49. Thomas

    Kommentar vom 27. Februar 2013 um 20:25

    …ich versteh nicht was du meinst :(

  50. 50. Bruno

    Kommentar vom 19. März 2013 um 13:14

    Hallo
    Ich habe das mit der Rechnung versucht. Auf dem Server läuft das alte PHP. Jedoch kommt immer die Fehlermeldung;

    Notice: Undefined index: firmaNameZeile01 in TwPdfRechnung.php on line 89
    Notice: Undefined index: firmaNameZeile02 in TwPdfRechnung.php on line 92
    usw.

    Was ist da falsch?
    danke und Grüsse
    Bruno

  51. 51. Thomas

    Kommentar vom 19. März 2013 um 13:19

    Guck mal so in etwa Zeile 15 nach
    ///session_start();
    und entferne dort die ‘///’
    .

  52. 52. Bruno

    Kommentar vom 19. März 2013 um 13:42

    Danke. Habe ich gemacht.
    Jetzt kommt die Meldung:

    Notice: A session had already been started – ignoring session_start() in TwPdfRechnung.php on line 15

  53. 53. Thomas

    Kommentar vom 19. März 2013 um 14:31

    Dann liegts nicht am alten php
    (http://de2.php.net/session_start).
    Du musst die Variablen in der ‘rechnung.php’ mit Werten füllen und in die Session schreiben…
    (sollte aber in der Demo so drin sein).

  54. 54. Anonymous

    Kommentar vom 19. März 2013 um 19:17

    Vielen Dank für deine Geduld. Aber ich glaube ich steh auf dem Schlauch.
    Ich habe die Datei als ZIP code downgeloaded.
    Und dann haben ich diese Sachen geändert (weil ich immer eine Fehlermeldung erhalten habe):

    Zeile 15:
    ///session_start(); die /// entfernt.

    Zeile 22-25:
    private durch var ersetzt

    dann in allen Zeilen
    public function durch function ersetzt
    private function durch function ersetzt

  55. 55. Anonymous

    Kommentar vom 19. März 2013 um 21:37

    Hallo, ich noch einmal.

    Ich habe es jetzt auf einen anderen Server geladen. Der unterstützt auch PHP5.
    Und dort funktioniert es einwandfrei.

    Falls du noch eine Idee hast, zu meiner Frage im vorderen Mail, wäre es nicht schlecht. Aber ansonsten funktioniert es ja jetzt.

Einen Kommentar schreiben