I am using FPDF to create a report from a Mysql database. The PDF is created fine but I would like to display the headers for each column at the top of every page for easier navigation. Does anyone have any idea on how to do this?
Thanks for the help.
try to extend fpdf class, and implement your Ln function: every time you add a line, decrement counter of line number, and when is 0, add new page with header.
class _PDF extends FPDF
{
var $_num_Rows = null;
var $_heightCell = null;
const NUM_ROWS = 48; // set number line in page
function _PDF($orientation = 'P',$unit = 'mm' ,$page = 'A4')
{
$this->_numRows = self::NUM_ROWS;
$this->_heightCell = 4;
$this->SetAutoPageBreak(true,10);
$this->FPDF($orientation, $unit, $page);
}
public function init_numRows()
{
$this->_numRows = self::NUM_ROWS;
}
public function dec_numRows()
{
$this->_numRows--;
}
function Ln()
{
if ( $this->_numRows )
{
parent::Ln();
$this->dec_numRows();
}
else
{
$this->addHeader();
}
}
function addHeader()
{
$this->init_numRows();
$this->AddPage();
// ...
}
}
$pdf = new _PDF();
Related
I'm still stuck with symfony2 and phpexcel..
First I don't know why my HTML writer doesn't generate <thead></thead> tags..
I don't understand why blanks columns still displaying as you can see on this screenshot, a ReadFilter is applied:
I just want to load the first 13 columns:
public function showClientAction()
{
$excel = glob(''.path.'\\'.tofile.'\\'.$file.'.{xlsx,xls,xlsm,xlsm.ink}', GLOB_BRACE);
$filterSubset = new \PHPExcel_Reader_DefaultReadFilter('A','N');
$objReader = \PHPExcel_IOFactory::createReaderForFile($excel[0]);
$objReader->setReadFilter($filterSubset);
/** Read the list of worksheet names and select the one that we want to load **/
$worksheetList = $objReader->listWorksheetNames($excel[0]);
$sheetname = $worksheetList[0];
/** Advise the Reader of which WorkSheets we want to load **/
$objReader->setLoadSheetsOnly($sheetname);
$objPHPExcel = $objReader->load($excel[0]);
$writer = \PHPExcel_IOFactory::createWriter($objPHPExcel, "HTML");
$writer->generateSheetData();
$writer->generateStyles();
return $this->render('SocietyPerfclientBundle:Default:testexcel.html.twig', array(
'excelHtml'=>$writer
));
}
My Filter :
class PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter {
public function __construct($fromColumn, $toColumn) {
$this->columns = array();
$toColumn++;
while ($fromColumn !== $toColumn) {
$this->columns[] = $fromColumn++;
}
}
public function readCell($column, $row, $worksheetName = '') {
// Read columns from 'A' to 'AF'
if (in_array($column, $this->columns)) {
return true;
}
return false;
}
}
I can't understand why these blank column are here...
ReadFilter is not working with HTML Writer ?
I can't just do :
.column14 { display:none;!important;}
.column15 { display:none;!important;}
.column16 { display:none;!important;}
.column17 { display:none;!important;}
etc...
Because I use jQuery Plugin "floatThead" to create a fixed <thead></thead>
In my view :
var table = $('#sheet0'); // select the table of interest
var thead = $('<thead/>').prependTo(table);
// create <thead></thead>
table.find('tbody tr.row0').appendTo(thead);
// Now the table is ready to have your chosen method applied to fix the position of the thead.
$('table.sheet0').floatThead({
position: 'fixed',
index: '8',
overflow: 'auto'
});
Please help me..
i think :
$this->columns[] = $fromColumn++;
do nothing .
try :
for ($i = $fromColumn; $i != $toColumns ; $i++)
{
$this->columns[$i]=$i;
}
I want to divide page in to two column using FPDF. I am using below code which created pdf in two cloumn but issue is that the gap is some bit more between column. I want to reduce gap between the column only.
My code here
class PDF extends FPDF
{
protected $col = 0; // Current column
protected $y0; // Ordinate of column start
function Header()
{
}
function Footer()
{
}
function SetCol($col)
{
// Set position at a given column
$this->col = $col;
$x = 10+$col*50;
$this->SetLeftMargin($x);
$this->SetX($x);
}
function AcceptPageBreak()
{
if($this->col<2)
{
// Go to next column
$this->SetCol($this->col+2);
// Set ordinate to top
$this->SetY($this->y0);
// Keep on page
return false;
}
else
{
// Go back to first column
$this->SetCol(0);
// Page break
return true;
}
}
function ChapterBody($file)
{
$txt = file_get_contents($file);
$this->SetFont('Times','',12);
$this->MultiCell(100, 7, $txt);
$this->Ln();
$this->SetCol(0);
}
function PrintChapter($num, $title, $file)
{
// Add chapter
$this->AddPage();
$this->ChapterBody($file);
}
}
$pdf = new PDF();
$title = '20000 Leagues Under the Seas';
$pdf->SetTitle($title);
$pdf->SetAuthor('Jules Verne');
$pdf->PrintChapter(1,'A RUNAWAY REEF','20k_c1.txt');
$pdf->Output();
In the below image you can see
You are skipping to third column. See bellow with two columns per page:
function AcceptPageBreak()
{
if($this->col<1)
{
// Go to next column
$this->SetCol($this->col+1);
// Set ordinate to top
$this->SetY($this->y0);
// Keep on page
return false;
}
else
{
// Go back to first column
$this->SetCol(0);
// Page break
return true;
}
}
I am generating a pdf from the mPDF library using the Yii framework. For this PDF I need to add charts generated on the server, so I'm using the pChart library to generate them. I created a simple object class to set the pChart properties in an easier way for the PDF.
This is the class object:
<?php
Class Chart {
protected $fontsFolder = null;
protected $data = array();
protected $resolution = array();
public $chartType = null;
public $fontSize = 18;
public $displayValues = false;
public $dirFile = null;
function __construct() {
Yii::import('application.vendors.pChart.class.*', true);
$this->fontsFolder = Yii::getPathOfALias('application.vendors.pChart.fonts');
}
// Set data points
public function data($data) {
if(!isset($data))
throw new CException('Data array missing');
if(!is_array($data))
throw new CException('Data must be an array');
$this->data[] = $data;
}
// Set label points
public function labels($labels) {
if(!isset($labels))
throw new CException('Labels data must be assgined');
if(!is_array($labels))
throw new CException('Labels data must be an array');
if(isset($this->data['labels']))
throw new CException('Labels data is already assigned');
$this->data['labels'] = $labels;
}
// Set resolution image
public function resolution($x, $y) {
if(isset($x) && isset($y)) {
if(is_array($x) && is_array($y))
throw new CException('Array to String error');
$this->resolution['x'] = $x;
$this->resolution['y'] = $y;
} else
throw new CException('Resolution data missing');
}
public function Debug() {
var_dump($this->fontsFolder, $this->data, $this->resolution);
}
// Render chart with given data
public function renderChart() {
if(!$this->data)
throw new CException('Data property must be assigned');
if(!$this->resolution)
throw new CException('Resolution property must be assigned');
if(!$this->chartType)
throw new CException('Chart type cannot be null');
if(!$this->dirFile)
throw new CException('Directory file must be assigned');
$this->render();
}
protected function render() {
switch ($this->chartType) {
case 'lineChart':
$this->lineChart();
break;
default:
throw new CEXception('"'.$this->chartType.'" is not a valid chart type');
break;
}
}
protected function lineChart() {
include('pDraw.class.php');
include('pImage.class.php');
include('pData.class.php');
$data = new pData();
foreach($this->data as $key => $value) {
if(is_int($key))
$data->addPoints($value);
}
$data->addPoints($this->data['labels'], 'labels');
$data->setAbscissa('labels');
$picture = new pImage($this->resolution['x'], $this->resolution['y'], $data);
$picture->setFontProperties(array('FontName'=>$this->fontsFolder.'/Forgotte.ttf'), $this->fontSize);
$picture->setGraphArea(60, 40, 970, 190);
$picture->drawScale(array(
'GridR'=>200,
'GridG'=>200,
'GridB'=>200,
'DrawXLines'=>false
));
$picture->drawLineChart(array('DisplayValues'=>$this->displayValues));
$picture->render($this->dirFile);
}
}
?>
And here is how I'm instantiating the object with PDF settings:
<?php
Class SeguimientoController extends Controller {
// public $layout = '//layouts/column2';
public function actionIndex() {
// Cargar libreria pdf y estilos
$mPDF = Yii::app()->ePdf->mpdf();
$mPDF->debug = true;
$mPDF->showImageErrors = true;
$stylesheet = file_get_contents(Yii::getPathOfAlias('webroot.css.reporte') . '/main.css');
$mPDF->WriteHTML($stylesheet, 1);
// Generate first chart
$chart = new Chart;
$chart->data(array(1,2,3,4,5));
$chart->Labels(array('asd', 'dead', 'eads', 'daed', 'fasd'));
$chart->resolution(1000, 200);
$chart->chartType = 'lineChart';
$chart->displayValues = true;
$chart->dirFile = Yii::getPathOfAlias('webroot.images').'/chart.png';
$chart->renderChart();
$mPDF->WriteHTml(CHtml::image('/basedato1/images/chart.png', 'chart'), 2);
// Generate second chart
$chart1 = new Chart;
$chart1->data(array(1,2,3,4,5));
$chart1->Labels(array('asd', 'dead', 'eads', 'daed', 'fasd'));
$chart1->resolution(1000, 200);
$chart1->chartType = 'lineChart';
$chart1->displayValues = true;
$chart1->dirFile = Yii::getPathOfAlias('webroot.images').'/chart.png';
$chart1->renderChart();
$mPDF->WriteHTml(CHtml::image('/basedato1/images/chart.png', 'chart'), 2);
$mPDF->OutPut();
}
}
?>
By testing the output of the view step by step, everything goes fine, the chart is rendered and saved as a temp file so the pdf can gather it. But when I have to render the second chart, I get a fatal error.
I have tried creating another class to be accessed by static functions because I thought the error could be made from multiple instances of the same object. But again, on second render I get the same error.
Just in case, if you need to know how the error outputs, here it is: Fatal error: Cannot redeclare class pDraw in C:\Servidor\basedato1\protected\vendors\pChart\class\pDraw.class.php on line 104.
Use include_once instead of include.
include_once('pDraw.class.php');
include_once('pImage.class.php');
include_once('pData.class.php');
Fatal error: Using $this when not in object context in plugins/newsarticles/controller/NewsArticleController.php on line 29
I can see where it is erroring, line 29 is this line:
$sqlFetch = $this->model->getAllNewsArticlesByDate();
Below I have submitted my code, can anyone shed any light on this?
<?php
require_once("plugins/newsarticles/model/NewsArticleDB.php");
class NewsArticleController
{
private $model;
public function __construct()
{
$this->model = new NewsArticleDB();
} //end constructor
/**
*Grab all the News Articles using the function
*Filter by date
*return the most recent 10
*/
function newsArticleHome()
{
//Grab the News Articles by date
$sqlFetch = $this->model->getAllNewsArticlesByDate();
foreach ($sqlFetch as $row)
{
//Insert posts into an object array
$objNewsArticle[] = new NewsArticle($row['newsId'],$row['newsTitle'], $row['newsPreview'], $row['newsDisplayPicture'], $row['newsContet']." ".$row['newsCategories'], $row['newsSubmissionDate']);
}
//Count the array incase it's less than 10 posts
//If it's more than 10, then set to 10, if it's less then set to x
if(count($objNewsArticle) > 10)
{
$tempObjectCount = 10;
}
else
{
$tempObjectCount = count($objNewsArticle);
}
//Store them in an array for output
for($tempLoopNumber = 0; $tempLoopNumber<$tempObjectCount; $tempLoopNumber++)
{
$recentNewsArticles[$tempLoopNumber] = $objNewsArticle[$tempLoopNumber];
}
return $recentNewsArticles;
}
function newsArticleId($id)
{
//Grab the Posts by date
$sqlFetch = $this->model->getAllNewsArticlesByDate();
$tempOptions = $sqlFetch->fetchAll();
$tempOpNumber = count($tempOptions);
for($tempNewsArticleNumber = 0; $tempNewsArticleNumber<$tempOpNumber; $tempNewsArticleNumber++)
{
if($tempOptions[$tempNewsArticleNumber]['newsId'] == $id)
{
$singlePost = $tempOptions[$tempNewsArticleNumber];
}
}
return $singlePost;
}
} //end class
?>
I am calling this from another file named testing:
include_once("plugins/newsarticles/controller/NewsArticleController.php");
echo "out";
echo NewsArticleController::newsArticleHome();
NewsArticleController::newsArticleHome(); is calling the function as if it were a static function. You need rather to create an instance of the class.
$nacont = new NewsArticleController();
$nacont->newsArticleHome();
The script works fine and is setting the data, but the website code is unable to use it and is instead setting its own memcached values. My website code is written in codeIgniter framework. I don't know why this is happening.
My script code :-
function getFromMemcached($string) {
$memcached_library = new Memcached();
$memcached_library->addServer('localhost', 11211);
$result = $memcached_library->get(md5($string));
return $result;
}
function setInMemcached($string,$result,$TTL = 1800) {
$memcached_library = new Memcached();
$memcached_library->addServer('localhost', 11211);
$memcached_library->set(md5($string),$result, $TTL);
}
/*---------- Function stores complete product page as one function call cache -----------------*/
function getCachedCompleteProduct($productId,$brand)
{
$result = array();
$result = getFromMemcached($productId." product page");
if(true==empty($result))
{
//------- REST CODE storing data in $result------
setInMemcached($productId." product page",$result,1800);
}
return $result;
}
Website Code :-
private function getFromMemcached($string) {
$result = $this->memcached_library->get(md5($string));
return $result;
}
private function setInMemcached($string,$result,$TTL = 1800) {
$this->memcached_library->add(md5($string),$result, $TTL);
}
/*---------- Function stores complete product page as one function call cache -----------------*/
public function getCachedCompleteProduct($productId,$brand)
{
$result = array();
$result = $this->getFromMemcached($productId." product page");
if(true==empty($result))
{
// ----------- Rest Code storing data in $result
$this->setInMemcached($productId." product page",$result,1800);
}
return $result;
}
This is saving data in memcached. I checked by printing inside the if condition and checking the final result
Based on the CodeIgniter docs, you can make use of:
class YourController extends CI_Controller() {
function __construct() {
$this->load->driver('cache');
}
private function getFromMemcached($key) {
$result = $this->cache->memcached->get(md5($key));
return $result;
}
private function setInMemcached($key, $value, $TTL = 1800) {
$this->cache->memcached->save(md5($key), $value, $TTL);
}
public function getCachedCompleteProduct($productId,$brand) {
$result = array();
$result = $this->getFromMemcached($productId." product page");
if( empty($result) ) {
// ----------- Rest Code storing data in $result
$this->setInMemcached($productId." product page",$result,1800);
}
return $result;
}
}
Personally try to avoid 3rd party libraries if it already exists in the core framework. And I have tested this, it's working superbly, so that should fix this for you :)
Just remember to follow the instructions at http://ellislab.com/codeigniter/user-guide/libraries/caching.html#memcached to set the config as needed for the memcache server