I am using the FPDF class to create a pdf based on the results from a mysql query. The information was outputted in a table to pdf as expected but my problem occurred when I used SetMargins() to set the page margins. Everything except the first row is effected. The first line seems to be hardcoded to a certain position or margin definition.
Here is my code:
class Table extends FPDF
{
public function CreateTable($header, $data)
{
//Header
$this->SetFillColor(255);
$this->SetTextColor(0);
$this->SetFont('Arial','B', 12);
foreach ($header as $col) {
$this->Cell($col[1], 10, $col[0], 1, 0, 'C');
//Cell(float w [, float h [, string txt [, mixed border [, int ln [, string align [, boolean fill [, mixed link]]]]]]])
}
$this->Ln();
//Data
$this->SetFillColor(255);
$this->SetTextColor(0);
$this->SetFont('Arial', '', 8);
foreach ($data as $row) {
$i = 0;
foreach ($row as $field) {
$this->Cell($header[$i][1], 6, $field, 1, 0, 'C');
$i++;
}
$this->Ln();
}
}
}
//column headings for the department table
$dept_header = array(array('Name', 75), array('Phone', 40), array('Fax', 40));
//column headings for the team tables
$team_header = array(array('Name', 35), array('Role', 30), array('Office', 25), array('Cell', 25), array('Email', 45), array('Pager', 25));
//get data
$query = new ConnectQuery();
$dept_data = $query->all('SELECT * FROM Table');
$team_data = $query->all('SELECT CONCAT_WS(" ", FIRST_NAME, LAST_NAME), JOB_ROLE, OFFICE_PHONE, MOBILE_PHONE, EMAIL, PAGER_NUM FROM Table2');
$pdf = new Table('P', 'mm', 'Letter');
$pdf->AddPage();
$pdf->SetMargins(5, 5);
$pdf->CreateTable($team_header, $team_data);
$pdf->CreateTable($dept_header, $dept_data);
$pdf->Output();
?>
Just define the page margin BEFORE you add the first page. The position is not reset by setMargins() call, which results in the "hardcoded postition" which was set in AddPage():
$pdf = new Table('P', 'mm', 'Letter');
$pdf->SetMargins(5, 5);
$pdf->AddPage();
There's a property in the FPDF class called $cMargin, which is used to calculate the x-offset of the text before it gets printed within the cell, but there doesn't appear to be a setter for it. It's a public property, so after you've instantiated your FPDF class, just call:
$pdf = new fpdf('P','mm','A4');
$pdf->cMargin = 0;
Or you can workaround your 1st line like
$pdf->Ln(); //workaround for 1st line
$pdf->Cell(..);
Related
I found this code in an older post. It works absolutely fine for my project except one problem. If the string from the mysql db is too long it will overflow the cells. I want it to automatically break and start a new line in the particular cell.
Original post I got the code from: Basic table creation fpdf
<?php
require('fpdf.php');
class People {
public function all() {
try {
$db = new PDO('mysql:host=localhost;dbname=test;charset=UTF-8', 'user', 'password');
$query = $db->prepare("SELECT first_name, middle_name, last_name, age, email FROM people ");
$query->execute();
$people = $query->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
//echo "Exeption: " .$e->getMessage();
$result = false;
}
$query = null;
$db = null;
return $people;
}
}
class PeoplePDF extends FPDF {
// Create basic table
public function CreateTable($header, $data)
{
// Header
$this->SetFillColor(0);
$this->SetTextColor(255);
$this->SetFont('','B');
foreach ($header as $col) {
//Cell(float w [, float h [, string txt [, mixed border [, int ln [, string align [, boolean fill [, mixed link]]]]]]])
$this->Cell($col[1], 10, $col[0], 1, 0, 'L', true);
}
$this->Ln();
// Data
$this->SetFillColor(255);
$this->SetTextColor(0);
$this->SetFont('');
foreach ($data as $row)
{
$i = 0;
foreach ($row as $field) {
$this->Cell($header[$i][1], 6, $field, 1, 0, 'L', true);
$i++;
}
$this->Ln();
}
}
}
// Column headings
$header = array(
array('First Name', 30),
array('Middle Name', 30),
array('Last Name', 30),
array('Age', 12),
array('Email', 47)
);
// Get data
$people = new People();
$data = $people->all();
$pdf = new PeoplePDF();
$pdf->SetFont('Arial', '', 12);
$pdf->AddPage();
$pdf->CreateTable($header,$data);
$pdf->Output();
Here's the code for generating a PDF Table but it seems my code is not right regarding in foreach, the tutorial use file.txt. Guys its my first time using FPDF in php so i'm confused right now what i need to do with my error. Tutorials > Tutorial 4: Multi-columns FPDF Link
<?php
require('fpdf.php');
$hostname = "localhost";
$database = "brm_dbs";
$username = "root";
$password = "";
$conn = mysql_connect($hostname, $username, $password) or die(mysql_error());
mysql_select_db($database, $conn);
class PDF extends FPDF
{
// Load data
function LoadData($query)
{
// Read file lines
//$lines = file($file);
//$lines = file($query);
$result = mysql_query($query);
$data = array();
foreach($result as $line)
$data[] = explode(',',trim($line));
return $data;
}
// Simple table
function BasicTable($header, $data)
{
// Header
foreach($header as $col)
$this->Cell(40,7,$col,1);
$this->Ln();
// Data
foreach($data as $row)
{
foreach($row as $col)
$this->Cell(40,6,$row,1);
$this->Ln();
}
}
// Better table
function ImprovedTable($header, $data)
{
// Column widths
$w = array(40, 35, 40, 45);
// Header
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
// Data
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR');
$this->Cell($w[1],6,$row[1],'LR');
$this->Cell($w[2],6,$row[2],'LR',0,'R');
$this->Cell($w[3],6,$row[3],'LR',0,'R');
$this->Ln();
}
// Closing line
$this->Cell(array_sum($w),0,'','T');
}
// Colored table
function FancyTable($header, $data)
{
// Colors, line width and bold font
$this->SetFillColor(255,0,0);
$this->SetTextColor(255);
$this->SetDrawColor(128,0,0);
$this->SetLineWidth(.3);
$this->SetFont('','B');
// Header
$w = array(40, 35, 40, 45);
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',true);
$this->Ln();
// Color and font restoration
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
$this->SetFont('');
// Data
$fill = false;
foreach($data as $row)
{
$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
$this->Cell($w[1],6,$row[1],'LR',0,'L',$fill);
$this->Cell($w[2],6,$row[2],'LR',0,'R',$fill);
$this->Cell($w[3],6,$row[3],'LR',0,'R',$fill);
$this->Ln();
$fill = !$fill;
}
// Closing line
$this->Cell(array_sum($w),0,'','T');
}
}
//Create new pdf file
//Select the Products you want to show in your PDF file
$query=("SELECT name,service,type,status FROM permits");
//$name = $row['name'];
//$service = $row['service'];
//$type = $row['type'];
//$status = $row['status'];
$pdf = new PDF();
// Column headings
$header = array('Resident', 'Frontline Service', 'Type', 'Status');
// Data loading
$data = $pdf->LoadData($query);
$pdf->SetFont('Arial','',14);
$pdf->AddPage();
$pdf->BasicTable($header,$data);
$pdf->AddPage();
$pdf->ImprovedTable($header,$data);
$pdf->AddPage();
$pdf->FancyTable($header,$data);
$pdf->Output();
?>
Warning: Invalid argument supplied for foreach() in
C:\xampp\htdocs\project\heldeskback\sample_pdf3.php on line 19 FPDF
error: Some data has already been output, can't send PDF file
I have FPDF to generate a member list from a Mysql database to a list in PDF. But after my website-host has update the php version, has mine member list not worked !
Now it show :
Warning: Invalid argument supplied for foreach() in
/customers/8/f/b/xxx.com/httpd.www/test/printmedlemsliste.php on line
46 FPDF error: Some data has already been output, can't send PDF file
(output started at
/customers/8/f/b/xxx.com/httpd.www/test/printmedlemsliste.php:46)
My code :
<?php
require('fpdf.php');
class People {
public function all() {
try {
$db = new PDO('mysql:host=localhost;dbname=xxx_com;charset=UTF-8', 'xxx_com', 'xxx');
$query = $db->prepare("SELECT o.user_post, o.user_name1, o.user_name2, o.user_address1, o.user_address2, o.user_phone1, o.user_phone2, c.user_email, o.user_type FROM e107_user c, e107_user_extended o WHERE c.user_id = o.user_extended_id Order By user_name1");
$query->execute();
$people = $query->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
//echo "Exeption: " .$e->getMessage();
$result = false;
}
$query = null;
$db = null;
return $people;
}
}
class PeoplePDF extends FPDF{
// Create basic table
public function BasicTable($header, $data)
{
// Header
$this->SetFont('','B', 12);
$this->Cell(0,6,'Medlemsliste'.'',1,1,'C');
$this->SetFont('','B', 9);
$dateinvoice = substr( $invoice[ 'dateinvoice' ], 6 ).substr( $invoice[ 'dateinvoice' ], 3, 2 ).substr( $invoice[ 'dateinvoice' ], 0, 2 );
$dateinvoice = date_create( $dateinvoice );
$dateinvoice = false === $dateinvoice ? '' : $dateinvoice->format( 'd-M-Y' );
$this->Cell( 10 ); $this->Cell( 17, 5, 'Print Dato:' ); $this->Cell( 17, 5, $dateinvoice, 0, 1 );
$this->SetFillColor(255);
$this->SetTextColor(0);
$this->SetFont('','B');
foreach ($header as $col) {
//Cell(float w [, float h [, string txt [, mixed border [, int ln [, string align [, boolean fill [, mixed link]]]]]]])
$this->Cell($col[1], 5, $col[0], 1, 0, 'L', true); }
$this->Ln();
// Data
$this->SetFillColor(255);
$this->SetTextColor(0);
$this->SetFont('');
foreach ($data as $row)
{
$i = 0;
foreach ($row as $field) {
$this->Cell($header[$i][1], 6, $field, 1, 0, 'L', true);
$i++;
}
$this->Ln();
}
}
}
// Column headings
$header = array(
array('Post', 20),
array('Fornavn', 18),
array('Efternavn', 46),
array('Adresse', 40),
array('Postnummer & By', 40),
array('Telefon', 22),
array('Mobil', 22),
array('E-Mail', 57),
array('Type', 12)
);
// Get data
$people = new People();
$data = $people->all();
$pdf = new PeoplePDF();
$pdf->SetFont('Arial', '', 9);
$pdf->AddPage('L');
$pdf->Ln(0);
$pdf->SetTitle("Medlemsliste", boolean);
$pdf->SetAuthor("-");
$pdf->BasicTable($header,$data);
$pdf->Output('yourfilename.pdf','D');
?>
Line 46 is foreach ($data as $row).
If I set // front of foreach ($data as $row), it a new error on line 49. Line 49 is foreach ($row as $field) {
Also if I set // front of Line 49, it generate the PDF file, but with no data in !
Can anyone help ?
That's because $data contains nothing , so the loop fails.
Confirm that you've got the correct data in $data when you've performed the query with $data = $people->all();
Try var_dump($data); to see that your return in the all() function actually returns a result.
I would also change your try / catch to this.
try {
$db = new PDO('mysql:host=localhost;dbname=xxx_com;charset=UTF-8', 'xxx_com', 'xxx');
$query = $db->prepare("SELECT o.user_post, o.user_name1, o.user_name2, o.user_address1, o.user_address2, o.user_phone1, o.user_phone2, c.user_email, o.user_type FROM e107_user c, e107_user_extended o WHERE c.user_id = o.user_extended_id Order By user_name1");
$query->execute();
$people = $query->fetchAll(PDO::FETCH_ASSOC);
return $people;
} catch (PDOException $e) {
//echo "Exeption: " .$e->getMessage();
return false;
}
My fpdf.php file is
<?php
require('fpdf/fpdf.php');
$prod_data = array();
if($_POST['affiliate_pdf']){
$prod_data = unserialize($_POST['affiliate_pdf']);
}
class PDF extends FPDF
{
public $prod_data;
public function createData($input){
$this->prod_data = $input;
}
function Header()
{
// Page header
global $title;
$this->SetFont('Arial','B',15);
$w = $this->GetStringWidth($title)+6;
$this->SetX((210-$w)/2);
$this->SetDrawColor(0,80,180);
$this->SetFillColor(230,230,0);
$this->SetTextColor(220,50,50);
$this->SetLineWidth(1);
$this->Cell($w,9,$title,1,1,'C',true);
$this->Ln(10);
// Save ordinate
$this->y0 = $this->GetY();
}
// Load data
function LoadData($file)
{
// Read file lines
$lines = file($file);
$data = array();
foreach($lines as $line)
$data[] = explode(';',trim($line));
return $data;
}
}
$pdf = new PDF();
// Column headings
$title = 'Title';
$header = array('AFFILIATE CHANNELS', 'TOTAL CHANNEL REVENUE', 'TOTAL SHARE OF REVENUE', 'TOTAL AFFILIATE SHARE OF REVENUE');
// Data loading
$data = $pdf->LoadData('countries.txt');
$pdf->SetFont('Arial','',14);
$pdf->AddPage();
$pdf->Cell(10,10,'Affiliate Name', 0,0,'L');
$pdf->Output();
?>
affiliate_pdf is my array which i am passing to fpdf.php . Here i want to use its values. So, i just want to ask , how can i print this array in $pdf->Cell or can i write it at any other place.
Mainly i just want to print its value on this pdf. It may be in any array format.
You can use print_r(). By defaut, it print array values but you can set a param to return values.
$pdf->Cell(10,10,print_r($your_array, true), 0,0,'L');
hello guys i just need a little help here about accessing a data array outside a class i'm so confused on how to show the variable outside the class
Here's my code below:
<?php
date_default_timezone_set('Asia/Manila');
require('resources/fpdf/fpdf.php');
class PDF extends FPDF {
function Header(){
//HERE IS THE PLACE WHERE SHOULD I PUT THE ARRAY, BUT I CANT ACCESS IT INSIDE
$this->SetFont('Arial','B',10);
$this->Cell(180,5,'PURCHASE ORDER',0,0,'C');
$this->Ln();
$this->SetFont('Arial','',9);
$this->Cell(40,5,'Suppliers Name:'.$data['spname'].' ');
$this->Ln();
$this->SetFont('Arial','',9);
$this->Ln(20);
}
}
$query = "SELECT * FROM po_order_details WHERE order_code = '".$code."'";
$result = $this->db->query($query);
foreach($result->result_array() as $row){
$data[] = array($row['item_qty'], //THIS IS THE ARRAY THAT I NEED TO GET
$row['spname'],
$row['spaddress'],
);
}
$this->session->set_userdata('session_data',$data);
//Column titles
$pdf = new PDF();
$header = array('QTY','ITEM / DESCRIPTION' , 'UNIT PRICE', 'TOTAL AMOUNT'); // CHANGE THIS ALSO
$pdf->SetFillColor(255,0,0);
$pdf->Ln();
$pdf->AddPage();
$pdf->BuildTable($header,$data);
$pdf->Ln();
$pdf->Output();
?>
that's all i hope you can help me
Why not just change the prototype of your Header method and pass the array as a parameter like this.
<?php
date_default_timezone_set('Asia/Manila');
require('resources/fpdf/fpdf.php');
class PDF extends FPDF {
function Header( &$titles, &$data ){
//HERE IS THE PLACE WHERE SHOULD I PUT THE ARRAY, BUT I CANT ACCESS IT INSIDE
// use $titles and $data as you like here
$this->SetFont('Arial','B',10);
$this->Cell(180,5,'PURCHASE ORDER',0,0,'C');
$this->Ln();
$this->SetFont('Arial','',9);
$this->Cell(40,5,'Suppliers Name:'.$data['spname'].' ');
$this->Ln();
$this->SetFont('Arial','',9);
$this->Ln(20);
}
}
$query = "SELECT * FROM po_order_details WHERE order_code = '".$code."'";
$result = $this->db->query($query);
foreach($result->result_array() as $row){
$data[] = array($row['item_qty'], //THIS IS THE ARRAY THAT I NEED TO GET
$row['spname'],
$row['spaddress'],
);
}
$this->session->set_userdata('session_data',$data);
//Column titles
$pdf = new PDF();
$header = array('QTY','ITEM / DESCRIPTION' , 'UNIT PRICE', 'TOTAL AMOUNT'); // CHANGE THIS ALSO
$pdf->Header( $header, $data );
$pdf->SetFillColor(255,0,0);
$pdf->Ln();
$pdf->AddPage();
$pdf->BuildTable($header,$data);
$pdf->Ln();
$pdf->Output();
?>
Could you just pass it as a parameter and then return the result?
Like:
function Header($param_array = array()) {
// ... modifications, bla bla
return $result_array;
}
And then look up the function which calls that Header() and pass that array parameter all the way through that function.
Of course, the drawback here is that you would modify FPDF class and would not be able to properly update to an newer version, if you need it at some point in the future.