Zend PDF Tables Helper - php

Is there any Zend Helper that can make PDF document with tables.
i need to pass result of my Query and the helper will return a PDF document with data in a table.
Just like the below Csv Helper.
what i did here is that i put the given class in
Zend/Controller/Action/Helper
and than in my Action i do so
public function getcsvAction() {
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNeverRender();
try{
$clModel = new Application_Model_DbTable_Mytable();
$select = $clModel->clCSV());
$this->_helper->Csv($select, "genertadfile name");
}catch(Exception $e){
echo 'Oops! Something went wrong.';
}
exit;
}
and this the class
<?php
// Zend_Controller_Action_Helper_Csv
class Zend_Controller_Action_Helper_Csv extends Zend_Controller_Action_Helper_Abstract{
public function direct($aryData = array(), $strName = "csv", $bolCols = true){
$this->printExcel($aryData, $strName, $bolCols);
}
public function printExcel($aryData = array(), $strName = "csv", $bolCols = true){
if (!is_array($aryData) || empty($aryData)){ exit(1); }
// header
header('Content-Description: File Transfer');
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=" . $strName . "-export.csv");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-control: private, must-revalidate');
header("Pragma: public");
if ($bolCols){
$aryCols = array_keys($aryData[0]);
array_unshift($aryData, $aryCols);
}
ob_start();
$fp = fopen("php://output", "w");
if (is_resource($fp)){
foreach ($aryData as $aryLine) {
fputcsv($fp, $aryLine, ',', '"');
}
$strContent = ob_get_clean();
$strContent = preg_replace('/^ID/', 'id', $strContent);
$strContent = utf8_decode($strContent);
$intLength = mb_strlen($strContent, 'utf-8');
header('Content-Length: ' . $intLength);
echo $strContent;
exit(0);
}
ob_end_clean();
exit(1);
}
}
?>

There is a official module for pdf on zend framework 2: zendpdf
You can install it by adding zendframework/zendpdf to your composer.json file.
Its not finnished yet, that why you can't find any information about it. You can find here the previous documentation... just look for zend.pdf.*.rst files.
There is a ZF2 module for the DOMPDF library too. Find more info here. The code you can finde here. Easy installation by adding "dino/dompdf-module": "dev-master" to your composer.json file.
ADDING:
DOMPDF can be used like this:
public function dompdfAction()
{
return new DOMPDFModule\View\Model\PdfModel\PdfModel(
array(), // Variable assignments per Zend\View\Model\ViewModel
array(
'fileName' => 'monthly-report', // Optional; triggers PDF download, automatically appends ".pdf"
'paperSize' => 'a4',
'paperOrientation' => 'landscape'
)
);
}
It will generate an pdf file for the dompdfAction's viewscript.
ZendPdf can be used like this:
public function pdfAction()
{
$pdf = new \ZendPdf\PdfDocument();
$pdf->pages[] = ($page = $pdf->newPage(\ZendPdf\Page::SIZE_A4));
$font = \ZendPdf\Font::fontWithName(\ZendPdf\Font::FONT_HELVETICA);
$page->setFont($font, 36);
$page->drawText('<h1>html não funciona...</h1>', 10, 536, 'utf-8');
$page->drawText('PDF FUNCIONA', 10, 500, 'utf-8');
$image = \ZendPdf\Image::imageWithPath('public/images/zf2-logo.png');
$page->drawImage($image, 100, 100, 400, 300);
$pdf->save("teste.pdf");
}

Related

get empty file after download

i want to download a file of projet but i get it empty. i'am using a spreadsheet librairy
Notice : i a make a dump after save function , my file is full and not empty in the path directory of project
Someone can help me !
bellow is my code :
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('template.xlsx');
$worksheet = $spreadsheet->getActiveSheet();
$filename = 'write.xls';
$worksheet->getCell('A1')->setValue('John');
$worksheet->getCell('A2')->setValue('Smith');
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save($filename); die;
// to download file
header('Content-Type: application/vnd.ms-excel');
header("Content-Length:".filesize($filename));
header("Content-Disposition: attachment;filename=$filename");
header('Cache-Control: max-age=0');
$writer->save('php://output');
exit();
i except a full file after downloading it
This function would work:
define ("ONE_DAY", 86400);
function getExisting()
{
$rootFolder = "pathTodirectory";
//first clear old files
$files = scandir($rootFolder,1);
array_pop($files); array_pop($files);
foreach($files as $file)
{
$fp = $rootFolder . DIRECTORY_SEPARATOR . $file;
$filemtime=filemtime($fp);
if (time() - $filemtime >= (2 * ONE_DAY))unlink($fp);
}//end clearing old files
//second rescan folder for current files
$files = scandir($rootFolder,1);
array_pop($files); array_pop($files);
$existing = array_reverse($files);
return $existing;
}
$existing = getExisting();
echo "\n<p> Select file or enter office number to review inventory:";
echo "\n <ul>";
foreach($existing as $rpt)
{
$spd = "pathTodirectory" . $rpt; \\make sure to follow up with relative path name here also
echo "\n <li><a href=\"$spd\" >" . $rpt ."</a></li>";
}
echo "\n </ul>";
I think it is the load() usage issue, your code works with following correction in my site :
$file_loc = 'template.xlsx';
$file_type = \PhpOffice\PhpSpreadsheet\IOFactory::identify($file_loc);
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($file_type);
// $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('template.xlsx');
$spreadsheet = $reader->load($file_loc);
$worksheet = $spreadsheet->getActiveSheet();
$filename = 'write.xls';
$worksheet->getCell('A1')->setValue('John');
$worksheet->getCell('A2')->setValue('Smith');
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
// save a physical file in server, you can skip this actually
$writer->save($target_dir . $filename);
// die; // don't die, be happy (^_^)
// to download file
header('Content-Type: application/vnd.ms-excel');
header("Content-Length:" . filesize($filename));
header("Content-Disposition: attachment;filename=$filename");
header('Cache-Control: max-age=0');
$writer->save('php://output');
exit();

PhpSpreadsheet - Download file instead of saving it

I need to generate an excel file (xls) and trigger the download after it is generated.
I found this example in the documentation.
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');
$writer = new Xlsx($spreadsheet);
$writer->save('hello world.xlsx');
It shows how to create a excel file and save it on the server.
How can I serve the result to the client instead and "force" him to download it?
I need to get the data of the $writer somehow.
I am currently solving it without PhpSpreadsheet:
// Excel Export
$filename = 'export_'.date('d-m-y').'.xls';
$filename = $validator->removeWhitespace($filename);
header('Content-type: application/ms-excel');
header('Content-Disposition: attachment; filename='.$filename);
exit($response["output"]); // <-- contains excel file content
But it is not working with my delimiter (semicolon). The semicolon is not getting interpreted and everything is getting written into one column.
If I export it as .csv, then it works. But I need it as .xls or .xlsx
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class DownloadExcel
{
public static function createExcel(array $data, array $headers = [],
$fileName = 'data.xlsx')
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
for ($i = 0, $l = sizeof($headers); $i < $l; $i++) {
$sheet->setCellValueByColumnAndRow($i + 1, 1, $headers[$i]);
}
for ($i = 0, $l = sizeof($data); $i < $l; $i++) { // row $i
$j = 0;
foreach ($data[$i] as $k => $v) { // column $j
$sheet->setCellValueByColumnAndRow($j + 1, ($i + 1 + 1), $v);
$j++;
}
}
$writer = new Xlsx($spreadsheet);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="'. urlencode($fileName).'"');
$writer->save('php://output');
}
}
This is what I use to create a spreadsheet with PhpSpreadsheet and output directly to php://output for download.
I had the same problem and found a solution here : https://github.com/PHPOffice/PhpSpreadsheet/issues/217
I ended my method with $writer->save('php://output'); then exit()
My answer :
PHP:
$writer = new Xlsx($spreadsheet);
ob_start();
$writer->save('php://output');
$ret['data'] = base64_encode(ob_get_contents());
ob_end_clean();
JS:
var linkSource = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,'+ response.data ;
var downloadLink = document.createElement("a");
var fileName = 'clients.' + format;
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
I solved it with a workaround. I temporarily save the file on the server, then I load the content into a variable and serve it as a download file. Then I delete the file from the server.
Workaround:
$date = date('d-m-y-'.substr((string)microtime(), 1, 8));
$date = str_replace(".", "", $date);
$filename = "export_".$date.".xlsx";
try {
$writer = new Xlsx($response["spreadsheet"]);
$writer->save($filename);
$content = file_get_contents($filename);
} catch(Exception $e) {
exit($e->getMessage());
}
header("Content-Disposition: attachment; filename=".$filename);
unlink($filename);
exit($content);
call ob_end_clean(); just before the $writer->save('php://output').
ob_end_clean();
$writer->save('php://output');
This worked for me:
$excel = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $excel->getActiveSheet();
$sheet->setTitle('This is a test', true);
ob_end_clean();
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="filename_' . time() . '.xlsx"');
header('Cache-Control: max-age=0');
$xlsxWriter = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($excel, 'Xlsx');
$xlsxWriter = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($excel);
exit($xlsxWriter->save('php://output'));
If you have problems where the files download corrupted, it is always good to check if there is any extra whitespace at the top of your file output. If your PHP files have blank white lines, whilst HTML won't have a problem, your phpspreadsheet file will. Spent a good chunk of time trying to fix these issues but the problem was with the whitespace!

View Image via controller function with absolue Path Yii1

I want to View Original Image when i click on thubnail image in gridview.
$file = 'http://localhost/myapp/upload/item_original/'.$model->image;
$type = 'image/jpg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
i tried above code and it didn't work.
then i tried easyimage extension.
public function actionViewImg($id){
$model = $this->loadModel($id);
Yii::import('application.extensions.easyimage.EasyImage');
$image = new Image('http://localhost/obhre/upload/item_original/1235.jpg'); //get the image
$image->save('upload/viewimg/1235.jpg');//save it to another folder
echo Yii::app()->easyImage->thumbOf('upload/viewimg/1235.jpg'); //view the image
}
above code is working if i put relative path.but not with the absolute path.
error is "Dont have a image"
This code should work:
public function actionViewImg($id)
{
$model = $this->loadModel($id);
$file = 'http://localhost/myapp/upload/item_original/'.$model->image;
header('Content-Type: image/jpg');
header('Content-Length: '.filesize($file));
echo file_get_contents($file);
exit;
}

How do I restfully return images using laravel 4?

I have a server set up to serve web pages on different domains (specifically a mobile device or localhost:9000 where laravel is serving on localhost:8000). I'm trying to return image requests on these pages to my laravel server but I'm running into problems. From a forum post, I thought that setting headers on a request would do the trick but, when I navigate to /api/v1/images/default.jpg, no default cat image is shown. Instead, I get a box with no image.
Now, the image is in my public folder so if I browse to /public/images/default.jpg I do see my cat image, but I'd rather serve images within my /api/v1/... route.
Route::get('images/{imageName}', function($imageName){
$img = 'public/images/' . $imageName;
// return $img;
echo $img . "\n\n";
if(File::exists($img)) {
// return "true";
// return Response::make($img, 200, array('content-type' => 'image/jpg'));
// return Response::download($img, $imageName);
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: inline; filename=\"".$imageName."\"");
header("Content-Type: image/jpg");
header("Content-Transfer-Encoding: binary");
//stream the file out
readfile($img);
exit;
} else {
return "false";
}
return $img;
// return File::exists($img);
// return File::isFile('/images/' . $imageName);
// return $imageName;
// if(File::isFile('images/' + $imageName)){
// return Response::make('images/' + $imageName, 200, array('content-type' => 'image/jpg'));
// }
});
Use the Response::stream method to do it:
Route::get('/image', function () {
return Response::stream(function () {
$filename = '/path/to/your/image.jpg';
readfile($filename);
}, 200, ['content-type' => 'image/jpeg']);
});
In case you want to stream your image from a ftp server ($imageName is the parameter)
$server = \Config::get('ftpconfig.server');
$usuario = \Config::get('ftpconfig.user');
$password = \Config::get('ftpconfig.password');
$path = \Config::get('ftpconfig.path');
$file_location = "ftp://$usuario:".urlencode($password)."#".$server.$path.$imageName;
$headers = [
"Content-Type" => "image/jpeg",
"Content-Length" => filesize($file_location),
"Content-disposition" => "inline; filename=\"" . basename($file_location) . "\"",
];
return \Response::stream(function () use ($file_location){
readfile($file_location);
}, 200, $headers)
#Andrew Allbright,
If your images are located inside the laravel app directory then you can use
$img = app_path().'/api/v1/images/' . $imageName;
For image manipulation you can try Intervention

Flash doesnt recognize the file type to get AS3 PHP

Im programming in as3 flash and php a button where you can download a file .zip file.
This gets the path from a php (proxy), but it cant recognize the file type and also fails to run the COMPLETE event. The idea of ​​this is to hide where the zip file is located.
I dont understand where the problem is.
The as3 code:
package {
imports...
public class Main extends MovieClip{
var download_button:MovieClip;
var req:URLRequest;
var file:FileReference;
var proxy:String = "http://www.domain.com/audio/proxy.php?url=";
var filename:String = "file.zip";
var status:TextField = new TextField();
public function Main() {
download_btn.addEventListener(MouseEvent.CLICK, promptDownload);
status.text = "Bienvenido";
addChild(status);
}
private function promptDownload(e:MouseEvent):void {
req = new URLRequest(proxy + filename);
file = new FileReference();
file.addEventListener(Event.COMPLETE, completeHandler);
file.addEventListener(Event.CANCEL, cancelHandler);
file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
file.download(req, "file.zip");
}
private function cancelHandler(event:Event):void {
trace("User canceled the download");
status.text = "Cancelado";
}
private function completeHandler(event:Event):void {
trace("Download complete");
status.text = "Completado";
}
private function ioErrorHandler(event:IOErrorEvent):void {
trace("ioError occurred");
status.text = "Error";
}
}
}
and the php code:
$filename = "http://www.domain.com/audio/files" . $_GET['url'];
$archivo = "file.zip";
$len = filesize($filename);
$outname = $archivo;
header("Content-type: application/zip");
// Optional but the error is the same
//header("Expires: -1");
//header("Last-Modified: " . gmdate('D, d M Y H:i:s') . " GMT");
//header("Content-Transfer-Encoding: binary");
//header("Cache-Control: no-store, no-cache, must-revalidate");
//header("Cache-Control: post-check=0, pre-check=0");
//header("Pragma: no-cache");
//header("Content-Length:".$len);
//header("Content-Disposition: attachment; filename=".$outname);
readfile($filename);
thank you very much
The actionscript work perfectly on my localhost, I download the zip file. You should check the PHP, you don't need to use http url to read file on the same server.
$filename = "http://www.domain.com/audio/files" . $_GET['url'];
This line is really a security hole, a hacker can get all your file, you need to escape this variable and check if the filename is legit.

Categories