FPDF - Fix start position text in cell - php

I have this part of code to generate PDF (FPDF lib) file with PHP.
He display some text values. I use "Cell" function to put text. But texts start never at the same position : https://i.stack.imgur.com/gof36.png. I think it's due to text length or position of my cell. Could you help me please ? Thanks.
$pdf->SetFont( "Arial", "B", 12 );
$pdf->SetXY( 1, 121 ); $pdf->SetFont('Arial','B',8); $pdf->Cell( 40, 8, utf8_decode("Type de livraison"), 0, 0, 'C');
$pdf->SetXY( 1, 131 ); $pdf->SetFont('Arial','B',8); $pdf->Cell( 60, 8, utf8_decode("Date et heure livraison souhaitée"), 0, 0, 'C');
$pdf->SetFont('Arial','',8);
$pdf->SetXY( 1, 121 ); $pdf->Cell( 88, 8, $lieu_livraison, 0, 0, 'R');
$pdf->SetXY( 1, 131 ); $pdf->Cell( 120, 8, $_POST['date_livraison'] . ' à ' . $_POST['heure_livraison'], 0, 0, 'R');

Related

How to auto adjust cell height in fpdf

How can I auto adjust the cell height in fpdf?
My pdf looks a little bit bad ;)
Screenshot of PDF
My code:
$pdf->SetFont('Arial', 'B', 13);
$pdf->SetLeftMargin(30);
$pdf->SetFillColor(193,229,252);
$pdf->Cell(15, 20, '', 0, 1, 'C');
$pdf->Cell($width_cell[0], 10, 'Datum', 1, 0, 'C', true);
$pdf->Cell($width_cell[1], 10, 'Von', 1, 0, 'C', true);
$pdf->Cell($width_cell[2], 10, 'Bis', 1, 0, 'C', true);
$pdf->Cell($width_cell[3], 10, 'Grund', 1, 1, 'C', true);
$pdf->SetFont('Arial', '', 13);
$fill = false;
while ($z = $stmt->fetch(PDO::FETCH_ASSOC)) {
$pdf->Cell($width_cell[0],10,date("d.m.Y", strtotime($z['date'])),1,0,'C',$fill);
$pdf->Cell($width_cell[1],10,substr($z['startTime'], 0, 5) . ' Uhr',1,0,'C',$fill);
$pdf->Cell($width_cell[2],10,substr($z['endTime'], 0, 5) . ' Uhr',1,0,'C',$fill);
$pdf->Cell($width_cell[3],10,$z['reason'],1,1,'C',$fill);
}
$pdf->Output();
To output multiple lines into a cell you'll need to use MultiCell instead of Cell.

Download fpdf with a given name?

I am trying to download a pdf file. I can download it but I want the name of the file to be specific to a MySQL data. That is, in the code below. I want the name of the file to be the data inside $id. How to achieve this?
<?php
//include connection file
ob_start();
include_once('fpdf/fpdf.php');
include_once('connection.php');
class PDF extends FPDF
{
// Page header
function Header()
{
$this->SetFont('Arial','B',14);
$this->Cell(276, 5, 'Details', 0, 0, 'C');
$this->Ln();
$this->SetFont('Times', '', 12);
$this->Cell(276, 10, 'Details of students', 0, 0, 'C');
$this->Ln(20);
}
// Page footer
function Footer()
{
// Position at 1.5 cm from bottom
$this->SetY(-15);
// Arial italic 8
$this->SetFont('Arial','I',8);
// Page number
$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
}
function headerTable()
{
$this->SetFont('Times', 'B', 12);
$this->Cell(40, 10, 'ID', 1, 0, 'C');
$this->Cell(20, 10, 'Name', 1, 0, 'C');
$this->Cell(90, 5, 'Score', 1, 0, 'C');
$this->Cell(30, 10, 'Percentage', 1, 0, 'C');
$this->Cell(20, 10, 'Age', 1, 0, 'C');
$this->Cell(0, 5, '', 0, 1, 'C');
//mini cell open
$this->Cell(60, 5, '', 0, 0, 'C');
$this->Cell(45, 5, 'Wrongs', 1, 0, 'C');
$this->Cell(45, 5, 'Rights', 1, 0, 'C');
//mini cell close
//$this->Cell(20, 10, 'Wrongs', 1, 0, 'C');
//$this->Cell(20, 10, 'Rights', 1, 0, 'C');
$this->Ln();
}
function viewTable($db)
{
$this->SetFont('Times', '', 12);
$id=$_GET['id'];
$sql = "SELECT * FROM Datas WHERE ID = '$id'";
$stmt = $db->query($sql);
//$stmt->bindParam('s',$id);
//$stmt->query();
//$result=$stmt->get_result();
//$stmt->get_result();
while($data = $stmt->fetch(PDO::FETCH_OBJ)){
$this->Cell(40, 10, $data->ID, 1, 0, 'C');
$this->Cell(20, 10, $data->Name, 1, 0, 'L');
$this->Cell(45, 10, $data->Wrongs, 1, 0, 'L');
$this->Cell(45, 10, $data->Rights, 1, 0, 'L');
$this->Cell(30, 10, $data->Percentage, 1, 0, 'L');
$this->Cell(20, 10, $data->Age, 1, 0, 'L');
$this->Ln();
}
}
}
$pdf = new PDF();
$pdf->AliasNbPages();
$pdf->AddPage('L','A4',0);
$pdf->headerTable();
$pdf->viewTable($db);
$pdf->Output("D", "test.pdf"); //How to change test.pdf to $id.pdf? $id value obtained from viewTable()
ob_end_flush();
?>
Nevermind, got it. It was simple by adding $id to the name. The complete script:
<?php
//include connection file
ob_start();
include_once('fpdf/fpdf.php');
include_once('connection.php');
class PDF extends FPDF
{
// Page header
function Header()
{
$this->SetFont('Arial','B',14);
$this->Cell(276, 5, 'Details', 0, 0, 'C');
$this->Ln();
$this->SetFont('Times', '', 12);
$this->Cell(276, 10, 'Details of students', 0, 0, 'C');
$this->Ln(20);
}
// Page footer
function Footer()
{
// Position at 1.5 cm from bottom
$this->SetY(-15);
// Arial italic 8
$this->SetFont('Arial','I',8);
// Page number
$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
}
function headerTable()
{
$this->SetFont('Times', 'B', 12);
$this->Cell(40, 10, 'ID', 1, 0, 'C');
$this->Cell(20, 10, 'Name', 1, 0, 'C');
$this->Cell(90, 5, 'Score', 1, 0, 'C');
$this->Cell(30, 10, 'Percentage', 1, 0, 'C');
$this->Cell(20, 10, 'Age', 1, 0, 'C');
$this->Cell(0, 5, '', 0, 1, 'C');
//mini cell open
$this->Cell(60, 5, '', 0, 0, 'C');
$this->Cell(45, 5, 'Wrongs', 1, 0, 'C');
$this->Cell(45, 5, 'Rights', 1, 0, 'C');
//mini cell close
//$this->Cell(20, 10, 'Wrongs', 1, 0, 'C');
//$this->Cell(20, 10, 'Rights', 1, 0, 'C');
$this->Ln();
}
function viewTable($db)
{
$this->SetFont('Times', '', 12);
$id=$_GET['id'];
$sql = "SELECT * FROM Datas WHERE ID = '$id'";
$stmt = $db->query($sql);
//$stmt->bindParam('s',$id);
//$stmt->query();
//$result=$stmt->get_result();
//$stmt->get_result();
while($data = $stmt->fetch(PDO::FETCH_OBJ)){
$this->Cell(40, 10, $data->ID, 1, 0, 'C');
$this->Cell(20, 10, $data->Name, 1, 0, 'L');
$this->Cell(45, 10, $data->Wrongs, 1, 0, 'L');
$this->Cell(45, 10, $data->Rights, 1, 0, 'L');
$this->Cell(30, 10, $data->Percentage, 1, 0, 'L');
$this->Cell(20, 10, $data->Age, 1, 0, 'L');
$this->Ln();
}
}
}
$id=$_GET['id'];
$pdf = new PDF();
$pdf->AliasNbPages();
$pdf->AddPage('L','A4',0);
$pdf->headerTable();
$pdf->viewTable($db);
$pdf->Output("D", "$id.pdf");
ob_end_flush();
?>

Page Break issues in fpdf and php

I have to generate multiple pages in fpdf by php.on first section i am using multicell.that works fine.after that i am using cell in a loop.
$GetMultiCellHeight = $pdf->y - $y;
$y = $y + $GetMultiCellHeight;
$pdf->SetXY($x, $y);
$pdf->Cell(30, 10, 'FILE NO', 1, 0, 'C');
$pdf->Cell(80, 10, 'FILE NAME', 1, 0, 'C');
$pdf->Cell(30, 10, 'DATE', 1, 0, 'C');
$pdf->Cell(50, 10, 'TYPE', 1, 0, 'C');
$y = $y + 10;
$pdf->SetXY($x, $y);
while ($rowSubmission_files = oci_fetch_row($parse_Submission_files)) {
$pdf->Cell(30, 10, $rowSubmission_files [1], 1, 0, 'C');
$pdf->Cell(80, 10, $rowSubmission_files [2], 1, 0, 'L');
$pdf->Cell(30, 10, $rowSubmission_files [5], 1, 0, 'C');
$pdf->Cell(50, 10, $rowSubmission_files [6], 1, 0, 'L');
$y = $y + 10;
$pdf->SetXY($x, $y);
}
I have two rows in my database to print file details.
after generation of pdf i am getting each rows in a new page. how to solve this?thanks in advance.

How can I choose "at least n" of each type of item in an ordered list

I have a list of results (see JSON below), and I need to choose the top 10. Here they're in json but I'm json_decoding them into an array like $coureValues["BUS1067"] == 117.1
I use arsort($courseValues) to get them in order like JSON below.
I need to choose the top 10, but I need to enforce a constraint of at least 4 "BUS", at least 2 "CMP", and at least 1 SAF. So for example, if there is no SAFxxxx in the top 10, but there are 6 BUS and 2 CMP, I want to remove the lowest scoring BUS and add the highest scoring SAF. In the end, all I want is a php array with the top 10, taking into consideration the constraints.
JSON
{
"BUS1067": 117.1,
"BUS1057": 86.06,
"BUS1073": 79,
"BUS1068": 74.08,
"BUS1077": 74,
"BUS1001": 71,
"BUS1066": 68,
"BUS1076": 67.05,
"BUS1011": 64,
"BUS1054": 64,
"BUS1006": 63,
"CMP1091": 62,
"BUS1000": 60,
"CMP1083": 59,
"SAF1007": 58,
"CMP1073": 56,
"CMP1044": 55,
"CMP1029": 55,
"CMP1082": 53,
"CMP1089": 50,
"CMP1042": 48,
"CMP1070": 46,
"CMP1074": 45,
"BUS1074": 31,
"BUS1009": 20,
"BUS1003": 10,
"BUS1058": 1.09,
"BUS1061": 1.07,
"BUS1056": 1.04,
"CMP1081": 1.03,
"SAF1021": 1.01,
"CMP1064": 0,
"CMP1039": 0,
"CMP1047": 0,
"SAF1045": 0,
"SAF1047": 0,
"CMP1063": 0,
"SAF1020": 0,
"SAF1043": 0,
"SAF1032": 0,
"SAF1038": 0,
"BUS1075": 0,
"SAF1002": 0,
"CMP1037": 0,
"BUS1040": 0,
"CMP1078": 0,
"BUS1013": 0,
"CMP1080": 0,
"BUS1002": 0,
"BUS1048": 0,
"BUS1071": 0,
"CMP1072": 0,
"CMP1088": 0,
"CMP1084": 0,
"BUS1031": 0,
"BUS1055": 0,
"BUS1063": 0,
"BUS1072": 0,
"SAF1013": 0,
"BUS1012": 0,
"SAF1006": 0,
"CMP1049": -20,
"CMP1048": -20,
"CMP1050": -20,
"CMP1075": -20,
"CMP1038": -925,
"CMP1041": -929,
"CMP1079": -933.98
}
what I'm looking for is a simple, elegant way to do that. I could "get it done", but the code that comes to mind is messy and unclear, and it seems that there's some general "algorithm" or sorting function that I should be using.
UPDATE: CODE:
as requested, here is my awful code to do a simple thing
<?php
$jsonWeights='{ "BUS1067": 117.1, "BUS1057": 86.06, "BUS1073": 79, "BUS1068": 74.08, "BUS1077": 74, "BUS1001": 71, "BUS1066": 68, "BUS1076": 67.05, "BUS1011": 64, "BUS1054": 64, "BUS1006": 63, "CMP1091": 62, "BUS1000": 60, "CMP1083": 59, "SAF1007": 58, "CMP1073": 56, "CMP1044": 55, "CMP1029": 55, "CMP1082": 53, "CMP1089": 50, "CMP1042": 48, "CMP1070": 46, "CMP1074": 45, "BUS1074": 31, "BUS1009": 20, "BUS1003": 10, "BUS1058": 1.09, "BUS1061": 1.07, "BUS1056": 1.04, "CMP1081": 1.03, "SAF1021": 1.01, "CMP1064": 0, "CMP1039": 0, "CMP1047": 0, "SAF1045": 0, "SAF1047": 0, "CMP1063": 0, "SAF1020": 0, "SAF1043": 0, "SAF1032": 0, "SAF1038": 0, "BUS1075": 0, "SAF1002": 0, "CMP1037": 0, "BUS1040": 0, "CMP1078": 0, "BUS1013": 0, "CMP1080": 0, "BUS1002": 0, "BUS1048": 0, "BUS1071": 0, "CMP1072": 0, "CMP1088": 0, "CMP1084": 0, "BUS1031": 0, "BUS1055": 0, "BUS1063": 0, "BUS1072": 0, "SAF1013": 0, "BUS1012": 0, "SAF1006": 0, "CMP1049": -20, "CMP1048": -20, "CMP1050": -20, "CMP1075": -20, "CMP1038": -925, "CMP1041": -929, "CMP1079": -933.98 }';
$courseValues=json_decode($jsonWeights,true);
arsort($courseValues);
$minRequired=array("BUS"=>4, "CMP"=>2, "SAF"=>1);
$pathLength=10;
$selected=array();
//get top results to satisfy minimum required
foreach ($minRequired as $courseType => $min) {
foreach($courseValues as $key => $val){
if(substr($key, 0, 3) == $courseType && $min)
{
$selected[$key]=$val;
$min--;
if($min==0)
break;
}
}
}
//fill in the remaining with the top results
foreach($courseValues as $k=>$v){
if(count($selected)<$pathLength)
{
if(!array_key_exists($k, $selected))
$selected[$k]=$v;
}
else
break;
}
arsort($selected);
foreach($selected as $k=>$v)
echo "$k: $v<br>";
?>
$topten = array_keys( array_slice( arsort( $courseValues ), 0, 10) ); ?
okay, sorry for not reading the question thoroughly :)
I would start with creating a php array that has the prefixes as keys and the number needed as values like so:
$prefixes = array("BUS" => 4, "CMP" => 2, "SAF" => 1);
Then, since you need 10 elements and the sum of the values is 7, you pick 3 elements from any category. The loop then should be something like this:
Basic idea:
While you don't have 10 elements from the sorted list:
Get element.
Extract prefix.
If (the prefix exists in the prefix array, and the corresponding value is greater than 0),
or (the sum of the remaining prefix values is less than the number of elements needed), then add it to your result.
In code:
$results = array();
foreach ($courseValues as $course => $courseValue) {
$prefix = substr($course, 0, 3);
if (isset($prefixes[$prefix]) && $prefixes[$prefix--] >= 0) {
$results[$course] = $courseValue;
}
else if (array_sum($prefixes) < 10 - count($results)) {
$results[$course] = $courseValue;
}
if (count($results) == 10) {
break;
}
}
Note: this is assuming $courseValues is sorted by $courseValue
MY SOLUTION:
Ok, I've got it down to one foreach loop. here's the full solution:
$jsonWeights='{ "BUS1067": 117.1, "BUS1057": 86.06, "BUS1073": 79, "BUS1068": 74.08, "BUS1077": 74, "BUS1001": 71, "BUS1066": 68, "BUS1076": 67.05, "BUS1011": 64, "BUS1054": 64, "BUS1006": 63, "CMP1091": 62, "BUS1000": 60, "CMP1083": 59, "SAF1007": 58, "CMP1073": 56, "CMP1044": 55, "CMP1029": 55, "CMP1082": 53, "CMP1089": 50, "CMP1042": 48, "CMP1070": 46, "CMP1074": 45, "BUS1074": 31, "BUS1009": 20, "BUS1003": 10, "BUS1058": 1.09, "BUS1061": 1.07, "BUS1056": 1.04, "CMP1081": 1.03, "SAF1021": 1.01, "CMP1064": 0, "CMP1039": 0, "CMP1047": 0, "SAF1045": 0, "SAF1047": 0, "CMP1063": 0, "SAF1020": 0, "SAF1043": 0, "SAF1032": 0, "SAF1038": 0, "BUS1075": 0, "SAF1002": 0, "CMP1037": 0, "BUS1040": 0, "CMP1078": 0, "BUS1013": 0, "CMP1080": 0, "BUS1002": 0, "BUS1048": 0, "BUS1071": 0, "CMP1072": 0, "CMP1088": 0, "CMP1084": 0, "BUS1031": 0, "BUS1055": 0, "BUS1063": 0, "BUS1072": 0, "SAF1013": 0, "BUS1012": 0, "SAF1006": 0, "CMP1049": -20, "CMP1048": -20, "CMP1050": -20, "CMP1075": -20, "CMP1038": -925, "CMP1041": -929, "CMP1079": -933.98 }';
$courseValues=json_decode($jsonWeights,true);
arsort($courseValues);
$required=array("BUS"=>4, "CMP"=>2, "SAF"=>1,"Total" => 10);
$selected=array();
foreach($required as $type => $min)
foreach($courseValues as $key => $val)
if(count($selected)<$required['Total']
&&($type=='Total'||(substr($key,0,3)==$type && $min-->0)))
$selected[$key]=$val;
I'll leave it open in case anyone has a better idea

Count entries in a JSON Array?

How do I count the entries I am scraping from JSON?
The below example has 6 entries, but as you can see.. if an entry is added, my code will ignore it. I could loop it 10 times and if it picks up nothing, then stop, but I think that's a bad way of doing it.
Is there any simple code that picks up 6 'seasons' in the following JSON?
MYPAGE.PHP
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
$season1 = $jsonarray['season_history'][0][0];
$season2 = $jsonarray['season_history'][1][0];
$season3 = $jsonarray['season_history'][2][0];
$season4 = $jsonarray['season_history'][3][0];
$season5 = $jsonarray['season_history'][4][0];
$season6 = $jsonarray['season_history'][5][0];
//the rest of the info here..
JSON
{
"season_history": [
["2006/07", 2715, 12, 11, 0, 45, 0, 0, 0, 1, 0, 0, 26, 0, 91, 169],
["2007/08", 2989, 15, 11, 0, 56, 0, 0, 0, 3, 0, 0, 18, 0, 95, 177],
["2008/09", 2564, 9, 10, 0, 20, 0, 0, 0, 2, 0, 0, 14, 0, 95, 138],
["2009/10", 2094, 12, 6, 0, 13, 0, 0, 0, 1, 0, 0, 8, 0, 92, 130],
["2010/11", 2208, 21, 4, 8, 28, 0, 0, 0, 1, 0, 0, 26, 0, 92, 176],
["2011/12", 521, 7, 0, 2, 6, 0, 0, 0, 0, 0, 0, 5, 146, 89, 49]
]
}
A foreach loop may be the approach you're looking for.
For example, this code would output the years for each season in your JSON data, regardless of how many seasons there were:
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
foreach($jsonarray['season_history'] as $season) {
echo $season[0] . PHP_EOL;
}
Alternatively, if you just need to know the number of seasons, this would be a solution:
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
$numberOfSeasons = count($jsonarray['season_history']);
You could combine that with a for loop as well, if you wanted:
for($i = 0; $i < $numberOfSeasons; $i++) {
echo $jsonarray['season_history'][$i][0];
}
Nevermind.. I figured it out... Here is the code I used.
//Get the page
$str = file_get_contents('http://myjsonurl.here/');
$jsonarray = json_decode($str, true);
//FOR EACH SEASON
foreach ($jsonarray['season_history'] as $var)
{
for ($i = 0; $i <= 15; $i++)
{
echo $var[$i];
//do more stuff here
}
}

Categories