I trying to create a custom table using FPDF Cell/MultiCell.
My 1st cell is a MultiCell that has two lines of text. The next cell should then just be placed right next to it.
Problem : no matter what I do to the next cell, it is always on the next line of the page instead of being placed right next to the 1st cell - and it's driving me crazy.
Here is my code:
require_once 'config.php';
require 'fpdf.php';
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','',10);
$pdf->MultiCell(150,10,'Certificate of foreign Currency usage in respect of materials and components in terms of the notes to rebate item ',1);
$pdf->SetFont('Arial','',10);
$pdf->MultiCell(40,10,'DA190',1);
$pdf->Output();
The cell containing the text "DA190" should be placed next to the previous cell, but is being positioned underneath the previous cell.
Before printing your first multicell, record the cursor position:
$x=$this->GetX();
$y=$this->GetY();
add your multicell using $this->Multicell($w,5,'Content');
Reset the cursor position to the start height (y) and the start horizontal + the width of the 1st multicell:
$this->SetXY($x+$w,$y);
Add your next multicell and repeat as necessary.
this worked for me
$pdf->multicell(120, 5, ' ' . $actividad, 0, 'l', true);
$x = $pdf->GetX();
$y = $pdf->GetY();
$pdf->SetXY($x + 120, $y);
$pdf->Cell(70, -5, ' ' . $claseActividad, '', 0, 'l', true);
result
I found the solution - fpdf has an extension (#3) focussed on using multicells.
Related
I wrote below code , it working fine but multicell row heights are not working properly.I wrote below code , it working fine but multicell row heights are not working properly.I wrote below code , it working fine but multicell row heights are not working properly.
$x=$pdf->GetY();
$pdf->SetY($x+1);
include_once("config.php");
$result = mysqli_query($mysqli, "SELECT * FROM prd"); // using mysqli_query instead
$i = 1;
while($res = mysqli_fetch_array($result))
{
$current_y = $pdf->GetY();
$current_x = $pdf->GetX();
$pdf->MultiCell(30, 5, $i, 1, 'L');
$end_y = $pdf->GetY();
$prdid = $res[0];
$empid = $res[1];
$specification = $res[2];
$prn = $res[3];
$current_x = $current_x + 30;
$pdf->SetXY($current_x, $current_y);
$pdf->MultiCell(30, 5, $empid, 1, 'L');
$end_y = ($pdf->GetY() > $end_y)?$pdf->GetY() : $end_y;
$current_x = $current_x + 30;
$pdf->SetXY($current_x, $current_y);
$pdf->MultiCell(30, 5, $specification, 1, 'L');
$end_y = ($pdf->GetY() > $end_y)?$pdf->GetY() : $end_y;
$current_x = $current_x + 30;
$pdf->SetXY($current_x, $current_y);
$pdf->MultiCell(30, 5, $prn, 1, 'L');
$end_y = ($pdf->GetY() > $end_y)?$pdf->GetY() : $end_y;
$i++;
$pdf->SetY($end_y);
}
$pdf->Output();
?>
My Result :
How to adjust row height automatically ?
So a multi cell is essentially dynamic is height. The height you put into the function is a "row" height. So what happens is that fpdf goes to write the multi cell and let's say we defined the height to be 5, it'll create a "cell" of height 5 and start writing. Then it hits the hard stop at the width and goes "i have to create a new row", which it then adds a new "cell" of height 5 directly below the top "cell". This repeats until all text is written out. Obviously this is great for dynamic content, but has its own challenges that you have hit.
The path I normally take is to record the start point, write out the multi cell first, and then record the stopping point. You can then go back and write the other cells to make for better alignment. For this GetX, GetY, SetX, SetY will be your friends. You can set heights and such dynamically with simple math.
The "lazy" option is to re-do the layout to allow for the document to scale, that being to take your way too long multi cell and put it UNDER the row so you'll have:
|1 |46 |PR2.....|
|really long text
that will scale
down here|
|2 |........
Hope that helps get you moving forward!
I'm developing an e-Certificate web page.
I've managed loading the certificate template and writing on top of it (Attendee Name, Event Title and Event Date).
But in positioning those three pieces of information, I couldn't position them at the center no matter how long they are. they always start from x point.
Check my work result:
Code:
<?php
require_once('fpdf.php');
require_once('fpdi.php');
$pdf =& new FPDI();
$pdf->addPage('L');
$pagecount = $pdf->setSourceFile('Certificate.pdf');
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx);
$pdf->SetFont('Times','I',18);
$pdf->SetTextColor(0,0,0);
$pdf->SetXY(120, 62);
$pdf->Write(0, "Attendee Name");
$pdf->SetXY(120, 102);
$pdf->Write(0, "Event Name");
$pdf->SetXY(120, 140);
$pdf->Write(0, "Event Date");
$pdf->Output();
?>
Is there away to center the text no matter how long is it?
meaning without fixing the x point. however, the y point result is very good.
So 2 ways I've done this before, the most likely easiest way:
Since you only have 1 entry on the row (Attendee Name or Event Name, etc)
Start a cell at the left most point, and have the cell run the full width of the page, then specify the center option:
$pdf->SetXY(0,62);
//0 extends full width, $height needs to be set to cell height.
$pdf->Cell(0, $height, "Attendee Name", 0, 0, 'C');
The other option is to calculate the center, and set X accordingly:
//how wide is the page?
$midPtX = $pdf->GetPageWidth() / 2;
//now we need to know how long the write string is
$attendeeNameWidth = $pdf->GetStringWidth($attendeeName);
//now we need to divide that by two to calculate the shift
$shiftLeft = $attendeeNameWidth / 2;
//now calculate our new X value
$x = $midPtX - $shiftLeft;
//now apply your shift for the answer
$pdf->setXY($x, 62);
$pdf->Write(0, "Attendee Name");
You can then repeat the above for each of the other elements.
You need a way to calculate the string length in pixels of the string (say, 120 pixels) and you need to know the page width in pixels.
At that point you position the string at x = (pagewidth/2 - stringwidth/2) and Bob's your uncle.
In FPDI you do this with GetStringWidth and GetPageWidth.
You can do the same adjustment with the height. For example you can split the string in words, calculate the width of each one, and determine when it is too much. This way you can split the string in two, and center each section.
I am printing the contents of MySql table on PDF using FPDF.
I have a column for text where usually long strings are input. When i am printing this on FPDF using Cell function the whole string is exceeding the cell it should be in.
I want that whole string should be made visible in one single cell by putting breaks in the string and also expanding the height of the cell automatically according to number of lines printed.
Following is the relevant part of my PHP code. I am also attaching a screenshot of generated PDF to give better idea.
$module = $_POST['module'];
$client = $_POST['client'];
$severity = $_POST['severity'];
$issue = $_POST['issue'];
$date = date('Y-m-d',strtotime($_POST['date']));
mysql_select_db($database);
$res = mysql_query("select * from parent");
require("fpdf/fpdf.php");
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFillColor(224,235,255);
$pdf->SetFont("Arial", "B", "20");
$pdf->Cell(187,15, "Detailed Bugs Report",1,0,C);
$pdf->Ln();
$pdf->Ln();
$pdf->SetFont("Times","B","15");
$pdf->Cell(48,10, "MODULE",1,0,C);
$pdf->Cell(22,10, "CLIENT",1,0,C);
$pdf->Cell(30,10, "SEVERITY",1,0,C);
$pdf->Cell(27,10, "DATE",1,0,C);
$pdf->Cell(60,10, "ISSUE",1,0,C);
$pdf->Ln();
$pdf->SetFont("Arial","","12");
while($row=mysql_fetch_row($res))
{
$pdf->Cell(48,10, "$row[0]",1,0);
$pdf->Cell(22,10, "$row[1]",1,0,C);
$pdf->Cell(30,10, "$row[2]",1,0,C);
$pdf->Cell(27,10, "$row[3]",1,0,C);
//$cellWidth = $pdf->GetStringWidth($row[4]);
$pdf->Cell(60, 10, $row[4], 1, 0);
$pdf->Ln();
}
$pdf->Output();
You can use MultiCell instead of Cell to put your text in. It should add a line break at the end of the cell and wrap the text automatically or you can use \n as a line break to explicitly wrap the text.
Why is there spaces before initial words and more than usual spaces. it is still somewhat exceeding the boundary of cell.
into cell tag how can i use text in left top if the text block is large.
there is the main problem in Multicell i can't use twomulticell parallel .
$pdf->MultiCell(60, 6, "".$row['particular'], 1, 'L', FALSE);
$pdf->Cell(40,50,"".$row['quantity'],1,0,"l");
The MultiCell method has no $ln parameter like the Cell method (Just a side note: Internally a MultiCell creates the lines by several Cell calls). If you need to stay at the same line with a multicell you have to do this with your own logic. E.g.:
$y = $pdf->GetY();
$x = $pdf->GetX();
$width = 60;
$pdf->MultiCell($width, 6, 'particular', 1, 'L', FALSE);
$pdf->SetXY($x + $width, $y);
$pdf->Cell(40,50, 'quantity', 1, 0, "l");
I'm trying to go through the code of TCPDF to understand how it calculates the height of the text to be rendered, but it's too much for me to handle without asking.
What I want to know: in the PDF from example 5 http://www.tcpdf.org/examples/example_005.pdf it gives the cell a yellow background. I'm guessing that at the basic level, it first draws a box with this fill color, then adds the text, so what method is it calling to get the height of the text to know the height of the box to fill?
I can see from the example code that MultiCell() is the entry point, but it's not clear what's the method it calls to get the height of the text. I pasted the code for MultiCell() in this pastebin
http://pastebin.com/A1niGrQG
Anyone knows how to trace this, because doing it by hand and looking through the code isn't working at all for me.
TCPDF (at least the latest version) includes the method getStringHeight() which get the estimated height needed for printing a simple text string using the Multicell() method.
Additionally, the getNumLines() method gives you the estimatad number of lines.
Check the source code documentation at http://www.tcpdf.org for further information.
The cell is being drawn by MultiCell:
http://www.tcpdf.org/examples/example_005.phps
$pdf->MultiCell(55, 5, '[LEFT] '.$txt, 1, 'L', 1, 0, '', '', true);
and from: http://api.joomla.org/com-tecnick-tcpdf/TCPDF.html
int MultiCell (float $w, float $h, string $txt, [mixed $border = 0], [string $align = 'J'], [int $fill = 0], [int $ln = 1], [int $x = ''], [int $y = ''], [boolean $reseth = true], [int $stretch = 0])
So as you can see, the first two values are statically assigning a width (55) and a height (5) to the MultiCell
Additionally:
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
You can see the unit of measurement is the program/class default PDF_UNIT
The font size is then set with
$pdf->SetFont('times', '', 10);
(or just use SetFontSize for the size only)
Just as a very simple proof of concept for what i said in my last comment on my other answer...
** You need to use a monospaced font and a line height equal to your text height (that or modify the code for line height instead of text height) fairly simple fix...
You also have to figure out your aproximate monospaced width.. Best thing to do is use a capitol M (M is the widest char - so monospaced chars are set to this width..)
<html><head></head><body style="font-family:'Courier New', Courier, monospace; line-height:12px;">
<?php
//If you are using a monospace font, this kinda works
$divWidth = 300; // in px;
$fontSize = 12; // (in px);
$fontWidth = 7; // in px - aprox monospace font width
$lineChars = floor($divWidth / $fontWidth);
$text = <<<EOT
MMMMMMMMMM (capital M is the widest character)I'm trying to go through the code of TCPDF to understand how it calculates the height of the text to be rendered, but it's too much for me to handle without asking.
What I want to know: in the PDF from example 5 it gives the cell a yellow background. I'm guessing that at the basic level, it first draws a box with this fill color, then adds the text, so what method is it calling to get the height of the text to know the height of the box to fill?
I can see from the example code that MultiCell() is the entry point, but it's not clear what's the method it calls to get the height of the text. I pasted the code for MultiCell() in this pastebin
EOT;
$wrappedText = wordwrap($text, $lineChars, "LINEHERE");
$lines = substr_count($wrappedText, "LINEHERE");
$newlines = substr_count($text, "\n");
$text = str_replace("\n", "<br>",$text);
$lines += $newlines;
$divHeight = $lines * $fontSize;
echo "With a width of: " . $divWidth . "<br>";
echo "Number of Lines: " . $lines . "<br>";
echo "Height Required: " . $divHeight . "px<br>";
echo "Wrapped Text at: " . $lineChars . " characters<br><br>";
$divsize = "width:$divWidth px; height:$divHeight px; font-size:$fontSize px; ";
$outStr = "<div style='overflow:auto; display:inline-block; background-color:aqua; $divsize'>$text</div>";
$outStr .= "<div style=' display:inline-block; background-color:fuchsia; $divsize'> </div>";
echo $outStr;
?>
</body></html>