Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 23140
  • Last Modified:

Line break and text wrapping in FPDF

Dear all,

I'd like to have the text inside a cell to wrap so as not to go out of the cell border.

But it does not wrap.

So I tried t insert a line break with "\n" but it is not interpreted.

The "\n" does not work. Why is that..?

    $this->SetFont('Arial', '', 12);
    $sum = 0;
    $count = 0;
    $fillingColor = '';
    foreach($this->items as $item) {
      $itemPrice = $item[4] * $item[3];
      $strText = $item[0] . " " . $item[2] . "\n" . $item[1];       // <<<=== H E R E
      $this->Cell($width[0], 6, $strText, 'LR', 0, 'L', $fillingColor);
      $this->Cell($width[2], 6, number_format($item[4], 2) . ' <80>', 'LR', 0, 'R', $fillingColor);
      $this->Cell($width[1], 6, $item[3], 'LR', 0, 'C', $fillingColor);
      $this->Cell($width[3], 6, number_format($itemPrice, 2) . ' <80>', 'LR', 0, 'R', $fillingColor);

      $count++;
      $sum += $itemPrice;
      $this->Ln();
      }

Any clue..?

Stephane
0
stephaneeybert
Asked:
stephaneeybert
  • 7
  • 2
1 Solution
 
Richard QuadlingSenior Software DeverloperCommented:
Is http://www.fpdf.org/en/doc/multicell.htm what you are looking for?
0
 
stephaneeybertAuthor Commented:
I need to display a table of rows/cells for an invoice.

The text of the items on the invoice is too long for its cell, and is reaching out of the cell on the right hand side.

It should instead wrap to the next line. But it doesn't.

0
 
stephaneeybertAuthor Commented:
Are you saying I could replace these 4 Cell calls

      $this->Cell($width[0], 6, $strText, 'LR', 0, 'L', $fillingColor);
      $this->Cell($width[2], 6, number_format($item[4], 2) . ' <80>', 'LR', 0, 'R', $fillingColor);
      $this->Cell($width[1], 6, $item[3], 'LR', 0, 'C', $fillingColor);
      $this->Cell($width[3], 6, number_format($itemPrice, 2) . ' <80>', 'LR', 0, 'R', $fillingColor);

with Multicell calls..?

If so, how..?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Richard QuadlingSenior Software DeverloperCommented:
No.

From the manual ...

This method allows printing text with line breaks. They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other. Text can be aligned, centered or justified. The cell block can be framed and the background painted.

Is http://www.fpdf.org/en/script/ex3.pdf the sort of thing you are trying to do?

The source for this is at http://www.fpdf.org/en/script/script3.php
0
 
stephaneeybertAuthor Commented:
Yepp!

Only, I still have a problem with the vertical borders in the table.

If the text of a line is too long for a cell and it wraps to the next line, then the border on the other cells of the next line are not drawed.

0
 
stephaneeybertAuthor Commented:
Here is my code:

<?php

class FPDFTable extends FPDF {

  var $widths;
  var $aligns;
  var $borders;
  var $fills;

      // Set the array of column widths
  function SetWidths($w) {
        $this->widths=$w;
    }

      // Set the array of column alignments
  function SetAligns($aligns) {
        $this->aligns = $aligns;
    }

      // Set the array of column borders
  function SetBorders($borders) {
        $this->borders = $borders;
    }

      // Set the array of column filling colors
  function SetFills($fills) {
        $this->fills = $fills;
    }

  function Row($data) {
        // Calculate the height of the row
        $nbRows = 0;
        for ($i = 0; $i < count($data); $i++) {
              $nbRows = max($nbRows, $this->NbLines($this->widths[$i], $data[$i]));
      }
    $height = 6;
        $totalHeight = $height * $nbRows;

        // Issue a page break first if needed
        $this->CheckPageBreak($totalHeight);

        // Draw the cells of the row
        for ($i = 0; $i < count($data); $i++) {
              $text = isset($data[$i]) ? $data[$i] : ' ';
              $width = $this->widths[$i];
              $align = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
              $border = isset($this->borders[$i]) ? $this->borders[$i] : '';
              $fill = isset($this->fills[$i]) ? $this->fills[$i] : '';

              // Save the current position
              $x = $this->GetX();
              $y = $this->GetY();

              // Print the text
              $this->MultiCell($width, $height, $text, $border, $align, $fill);

              // Put the position to the right of the cell
              $this->SetXY($x + $width, $y);
          }

        // Go to the next line
        $this->Ln($totalHeight);
    }

  // If the height would cause an overflow, then add a new page immediately
  function CheckPageBreak($height) {
        if ($this->GetY() + $height > $this->PageBreakTrigger) {
              $this->AddPage($this->CurOrientation);
      }
    }

      // Computes the number of lines a MultiCell of width w will take
  function NbLines($w,$txt) {
  $cw=&$this->CurrentFont['cw'];
      if($w==0)
            $w=$this->w-$this->rMargin-$this->x;
      $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
      $s=str_replace("\r",'',$txt);
      $nbRows=strlen($s);
      if($nbRows>0 and $s[$nbRows-1]=="\n")
            $nbRows--;
      $sep=-1;
      $i=0;
      $j=0;
      $l=0;
      $nl=1;
      while($i<$nbRows)
      {
            $c=$s[$i];
            if($c=="\n")
            {
                  $i++;
                  $sep=-1;
                  $j=$i;
                  $l=0;
                  $nl++;
                  continue;
            }
            if($c==' ')
                  $sep=$i;
            $l+=$cw[$c];
            if($l>$wmax)
            {
                  if($sep==-1)
                  {
                        if($i==$j)
                              $i++;
                  }
                  else
                        $i=$sep+1;
                  $sep=-1;
                  $j=$i;
                  $l=0;
                  $nl++;
            }
            else
                  $i++;
      }
      return $nl;
    }

  }

?>

<?

require($gSystemPath . 'fpdf/fpdf.php');
require($gSystemPath . 'fpdf/FPDFTable.php');

define('FPDF_FONTPATH', $gSystemPath . 'fpdf/font/');

class ShopOrderPdfInvoice extends FPDFTable {                        

  var $recipientName;
  var $recipientAddress;
  var $recipientTelephone;
  var $recipientMobilePhone;
  var $recipientEmail;
  var $itemHeaders;
  var $items;
  var $totalQuantity;
  var $totalQuantityLabel;
  var $currency;
  var $totalPrice;
  var $totalFee;
  var $totalFeeLabel;
  var $totalGeneral;
  var $totalGeneralLabel;

      function setDate($invoiceDate) {
            $this->ln(3);
            $this->SetFont('Arial', '', 12);
            $this->MultiCell(0, 5, $invoiceDate, 0, 'L');
        }
      
      function setTitle($invoiceTitle) {
            $this->ln();
            $this->SetFont('Arial', 'B', 16);
            $this->MultiCell(0, 5, $invoiceTitle, 0, 'C');
        }
      
      function setInvoiceNumber($invoiceNumber) {
            $this->ln(10);
            $this->SetFont('Arial', '', 12);
            $this->MultiCell(0, 5, $invoiceNumber, 0, 'L');
        }
      
      function setClient($name, $address1, $address2, $zipCode, $city, $state, $country) {
            $y1 = 15;
            $this->SetY($y1);
            $this->SetFont('Arial', 'B', 12);
            $this->MultiCell(0, 4, $name, 0, 'R');
            $this->SetY($y1 + 6);
            $this->SetFont('Arial', '', 12);
    $address = $address1;
    if ($address2) {
      $address .= "\n" . $address2;
      }
    $address .= "\n" . $zipCode . ' ' . $city;
    if ($state) {
      $address .= "\n" . $state;
      }
    $address .= "\n" . $country;
            $this->MultiCell(0, 5, $address, 0, 'R');
        }

      function setRecipient($recipientName, $recipientAddress, $recipientTelephone, $recipientMobilePhone, $recipientEmail) {
    $this->recipientName = $recipientName;
    $this->recipientAddress = $recipientAddress;
    $this->recipientTelephone = $recipientTelephone;
    $this->recipientMobilePhone = $recipientMobilePhone;
    $this->recipientEmail = $recipientEmail;
    }

      function setBank($bank) {
            $this->Ln(10);
            $this->SetFont('Arial', '', 12);
            $this->MultiCell(0, 5, $bank, 0, "L");
        }

  function setItemHeaders($itemHeaders) {
    $this->itemHeaders = $itemHeaders;
    }

  function setItems($items) {
    $this->items = $items;
    }

  function setTotalQuantity($totalQuantity) {
    $this->totalQuantity = $totalQuantity;
    }

  function setTotalQuantityLabel($totalQuantityLabel) {
    $this->totalQuantityLabel = $totalQuantityLabel;
    }

  function setCurrency($currency) {
    $this->currency = $currency;
    }

  function setTotalPrice($totalPrice) {
    $this->totalPrice = $totalPrice;
    }

  function setTotalFee($totalFee) {
    $this->totalFee = $totalFee;
    }

  function setTotalFeeLabel($totalFeeLabel) {
    $this->totalFeeLabel = $totalFeeLabel;
    }

  function setTotalGeneral($totalGeneral) {
    $this->totalGeneral = $totalGeneral;
    }

  function setTotalGeneralLabel($totalGeneralLabel) {
    $this->totalGeneralLabel = $totalGeneralLabel;
    }

      function buildTable($rowPerPage = 10) {
            $this->ln(3);
            $this->SetFont('','B');
            
            // Header
            $width = array(100, 30, 30, 30);
            $this->SetFont('Arial','B',13);
            for($i = 0; $i < count($this->itemHeaders); $i++) {
                  $this->Cell($width[$i], 10, $this->itemHeaders[$i], 1, 0, 'C');
      }
            $this->Ln();

            // Items
            $this->SetFont('Arial', '', 12);
    $this->SetWidths(array(100, 30, 30, 30));
    $this->SetAligns(array('L', 'R', 'C', 'R'));
    $this->SetBorders(array('LR', 'LR', 'LR', 'LR'));
            $count = 0;
            foreach($this->items as $item) {
                  $totalItemPrice = number_format($item[4] * $item[3], 2, '.', '') . ' ' . $this->currency;
      $strText = $item[0] . " " . $item[2];
      $itemPrice = number_format($item[4], 2, '.', '') . ' ' . $this->currency;
      $quantity = $item[3];
      if ($item[1]) {
        $strText .= "\n" . $item[1];
        // To avoid gaps in the vertical borders
        $itemPrice .= "\n ";
        $quantity .= "\n ";
        $totalItemPrice .= "\n ";
        }
      $this->Row(array($strText, $itemPrice, $quantity, $totalItemPrice));

                  $count++;
              }

            // Fill up with empty rows
            while ($count++ <= $rowPerPage) {
      $this->Row(array('', '', '', ''));
              }

            $this->Cell(array_sum($width), 0, '', 'T');
        $this->Ln();

            $this->SetFont('Arial', '', 12);
            $this->Cell($width[0] + $width[1] + $width[2], 10, $this->totalQuantity . ' ' . $this->totalQuantityLabel, 1, 0, 'R');
            $this->SetFont('Arial', 'B', 12);
            $this->Cell($width[3], 10, number_format($this->totalPrice, 2, '.', '') . ' ' . $this->currency, 1, 0, 'R');
            $this->Ln();

            $this->SetFont('Arial', '', 12);
            $this->Cell($width[0] + $width[1] + $width[2], 10, $this->totalFeeLabel, 1, 0, 'R');
            $this->SetFont('Arial', 'B', 12);
            $this->Cell($width[3], 10, number_format($this->totalFee, 2, '.', '') . ' ' . $this->currency, 1, 0, 'R');
            $this->Ln();

            $this->SetFont('Arial', '', 12);
            $this->Cell($width[0] + $width[1] + $width[2], 10, $this->totalGeneralLabel, 1, 0, 'R');
            $this->SetFont('Arial', 'B', 12);
            $this->Cell($width[3], 10, number_format($this->totalGeneral, 2, '.', '') . ' ' . $this->currency, 1, 0, 'R');
            $this->Ln();
        }

      function Footer() {
            $this->Ln(10);
            $this->SetY(-30);
            $this->SetFont('Arial', '', 12);
            $this->SetTextColor(128);
    $recipient = $this->recipientName
      . "\n" . $this->recipientAddress
      . "\n" . $this->recipientTelephone . ' / ' . $this->recipientMobilePhone
      . "\n" . $this->recipientEmail;
            $this->MultiCell(0, 5, $recipient, 0, 'C');
        }

  }

?>
0
 
stephaneeybertAuthor Commented:
The pdf file can be seen at:

http://www.thalasoft.com/invoice.pdf
0
 
RoonaanCommented:
Hi,

On fpdf.org no the 'Scripts' page you will find an entry from Olivier called 'Table with MultiCells'. That might just be what you are trying to build yourself.

-r-
0
 
stephaneeybertAuthor Commented:
Hi Roonaan ,

You are refering to the script that RQuadling already mentioned.

But thanks anyway.

There is still a problem with this script.

If a cell has a text long enough to wrap on several lines, then the other cells on the same row will not properly display the vertical borders.

It's a bug of the FPDF product I dare say.

Regards,

Stephane
0
 
stephaneeybertAuthor Commented:
I can live wih that bug/problem in the fpdf product.

But if anyone has a workaround, it is welcome..

Thanks

Stephane
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 7
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now