Export With Box Spout - php

I am trying to implement Box/Spout into a project of mine and I want to export some data.
The thing is that when I tried to make a test file to get downloaded it doesn't work, it's just a simple white page and the .xlsx download is not triggered.
Below is my code:
<?php
require_once 'vendor/box/spout/src/Spout/Autoloader/autoload.php';
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Common\Entity\Row;
function xlsx(){
$writer = WriterEntityFactory::createXLSXWriter();
// $writer = WriterEntityFactory::createODSWriter();
// $writer = WriterEntityFactory::createCSVWriter();
$writer->setShouldUseInlineStrings(true); // default (and recommended) value
$writer->setTempFolder($customTempFolderPath);
$fileName = 'test.xlsx';
// $writer->openToFile($filePath); // write data to a file or to a PHP stream
$writer->openToBrowser($fileName); // stream data directly to the browser
$cells = [
WriterEntityFactory::createCell('Carl'),
WriterEntityFactory::createCell('is'),
WriterEntityFactory::createCell('great!'),
];
/** add a row at a time */
$singleRow = WriterEntityFactory::createRow($cells);
$writer->addRow($singleRow);
/** add multiple rows at a time */
$multipleRows = [
WriterEntityFactory::createRow($cells),
WriterEntityFactory::createRow($cells),
];
$writer->addRows($multipleRows);
/** Shortcut: add a row from an array of values */
$values = ['Carl', 'is', 'great!'];
$rowFromValues = WriterEntityFactory::createRowFromArray($values);
$writer->addRow($rowFromValues);
$writer->close();
}
This is a sample taken from the official documentation: https://opensource.box.com/spout/
Is there something I missed? What I am doing wrong?

It looks good to me. You just need to call the xlsx() function from your index.php to actually trigger the download.
To test if it really works, just move the contents of the xlsx() function directly inside index.php; that could help debug your issue

Related

Using the mikehaertl\php-pdftk library for manipulating PDFs, chaining commands fails when getDataFields is called first

I'm attempting to create a wrapper class around the mikehaertl\php-pdftk\pdf object for the purposes of populating PDF form fields. When trying to chain commands via the documentation the pdf fails to correctly execute the second command (or any after the first). It looks as though this is an issue with the underlying temp file handling and the tmep file not being written out as I watch my temp folder. As I debug, the temp file is there, but of 0 size.
Sample code demonstrating the issue
use mikehaertl\pdftk\Pdf;
class PDFTKTest extends TestCase
{
public function testPdfTkOperations()
{
$cmdPath = 'D:\PDFtk\bin\pdftk.exe';
$formPath = 'D:\test\sample_files\test.pdf';
$options = ['command' => $cmdPath];
$pdf = new Pdf($formPath, $options);
$this->assertNotNull($pdf);
//Get fields from PDF
$fields = $pdf->getDataFields();
$this->assertNotNull($fields);
//Set some field Values
$values = ['full_name' => 'John Q. Programmer'];
$pdf2 = new Pdf($pdf, $options); //chaining broken
//$pdf2 = new Pdf($formPath, $options); //works fine creating a new Pdf object
$this->assertNotNull($pdf2);
$res = $pdf2->fillForm($values)->execute();
//Next assertion fails using chaining
$this->assertTrue($res, "Execute failed: \n". $pdf2->getError());
//Get fields with the updates
$fields = $pdf2->getDataFields();
$this->assertNotNull($fields);
//Next assertion fails, getDataFields fails on a chained command
$this->assertGreaterThan(0, count($fields));
}
}
I've got a work around where I use separate \Pdf objects for each action and manage my own temp file, I was just hoping to take advantage of the classes functionality a bit more and not have to do so much of the mundane. Is this functionality broken, or am I using it incorrectly?
After looking deeper in to the PDFTK library which mikehaertl\php-pdftk\pdf wraps and reading the documentation on the dump_data_fields option I came up with the folowing observations:
PDFTK doesn't produce an output file for the dump_data_fields command
The php-pdftk class does create the underlying temp file when calling getDataFields, but it is empty and remains that way.
When chaining another Pdf object, it references the empty temp file from the previous command. Here lies the rub.
Solution
When I call getFieldData I create a new Pdf object and chain it to the previous, however I don't save a reference to that. I only save the newly chained object if it is form a command that creates actual output.
Here's an exmaple to demonstate:
<?php
use mikehaertl\pdftk\Pdf;
class PDFTKFormService
{
protected $pdf = null;
/**
* #return array|bool|\mikehaertl\pdftk\DataFields
*/
public function getDataFields()
{
//get data fields doesn't output a new file
//so we need to use the existing instance or create a new one and
$pdf = $this->getNextPdf();
$fields = $pdf->getDataFields();
if ($fields === false)
return [];
return $fields;
}
/**
* #param array $data
*
* #return resource The stream resource
*/
public function setDataFieldValues($data = [])
{
$this->pdf = $this->getNextPdf();
$this->pdf->fillForm($data)->execute();
}
protected function getNextPdf()
{
$options = ['command' => 'Path\To\PDFTK\binary'];
if ($this->pdf === null) {
return new Pdf($this->getTemplatePath(), $options);
} else {
return new Pdf($this->pdf, $options);
}
}
}
Hopefully this can help someone else.

no caching file for writing last update content into file with Symfony into controller

I would like to create a file based on template Twig (and one parameter).
My file generated correctly with replace variable with my data. But if I change data my controller symfony generated always the same file with the same content.
My varDumper content (the text/plain character represent file) is good. It's change always with change variable content. But the writing file always generate the same content...
PHP seems do not caching with fwrite ou file_put_contents function but my content never change. I also disable caching for twigEngine but same result.
Can you help me to writing file with good last content.
All code is in a controller symfony. I keep comment code for your understanding all my test :
public function createEntityAction()
{
$rootDir = $this->getParameter('kernel.root_dir');
$templateDir = $rootDir . '/../src/CmsBundle/Resources/views/Entity/templateFile/';
$filename = 'test.php';
$pathFile = $templateDir . $filename;
$twigEngine = $this->get('twig');
$twigEngine->setCache(false);
$twigEngine->disableAutoReload();
// $loader = new Twig_Loader_Filesystem($templateDir);
// $twig = new Twig_Environment($loader, [
// 'cache' => '/path/to/compilation_cache',
// 'cache' => false,
// ]);
$baseTemplate = $twigEngine->loadTemplate('#Cms/Entity/templateFile/baseEntity.html.twig');
$script = $baseTemplate->render(['slug' => 'product-333']);
\Symfony\Component\VarDumper\VarDumper::dump($script);
if (file_exists($pathFile))
{
clearstatcache(true);
$ret = unlink($pathFile);
\Symfony\Component\VarDumper\VarDumper::dump($ret);
}
$file = fopen($pathFile, 'w+');
fwrite($file, $script);
fclose($file);
// file_put_contents($pathFile, $script);
return $this->render('#Cms/Entity/create.html.twig', []);
}
The final file content is always the same if I change the "slug" variable.
It looks to me like you're missing a variable in your controller. There should be something like this createEntityAction($slug), then this line should be $baseTemplate->render(['slug' => $slug); Right now it is doing exactly what you are telling it, you have a hard coded string for the slug...
If you post your controller definition it would help (annotations or yaml)

dompdf->render(); not working in api class

I'm having a problem when trying to render html to pdf using dompdf.
I have the code placed inside a class and after the procedure code I would like it to create a pdf of the html.
This is the code I have at the moment:
$templatefile = file_get_contents("templates/costreport.htm");
//fill headers
$templatefile = str_replace("%DATES%",stripslashes($startdate)." - ".stripslashes($enddate),$templatefile);
if ($siteid>0) {
$pdfname = "costreport-".$clientid.".pdf";
} else {
$pdfname = "costreport-".$clientid."-".$siteid.".pdf";
}
//insert into database
//Close and output PDF document
$pdfname = str_replace("/","-",$pdfname);
$pdfname = str_replace("\\","-",$pdfname);
//create pdf
// unregister Yii's autoloader
spl_autoload_unregister('my_autoloader');
// register dompdf's autoloader
require_once("../system/dompdf/dompdf_config.inc.php");
// register Yii's autoloader again
spl_autoload_register('my_autoloader');
$dompdf = new DOMPDF();
$dompdf->set_paper("A4","portrait");
$dompdf->load_html($templatefile);
//set_time_limit(240);
$dompdf->render();
$pdf = $dompdf->output();
// You can now write $pdf to disk, store it in a database or stream it
// to the folder.
file_put_contents('../tmp/'.$clientid.'/'.$pdfname, $pdf);
The code fails when the dompdf->render(); is in but once I take that line out the code works and the file is created but I cant open it if it hasn't rendered.
I've tried debugging the code and made the template is HTML valid but I'm at a loss now.
The error I am getting back is just boolen false when I run the script with the dompdf->render(); in it.
The problem was that I had this piece of code at the top of my class.
/set up path to new dir including dir to be created
chdir("../tmp/");
$newdirpath = getcwd()."/".$clientid;
//if an old invoice ticket pack exists unlink it so as not to get things confused with the new pack being created.
if (file_exists(getcwd()."/$clientid_$siteid_CostReport.pdf")) {
unlink(getcwd()."/$clientid_$siteid_CostReport.pdf");
}
//setup temp dir
if (!is_dir($newdirpath)) {
//create new dir if it doesn't already exist!
mkdir($newdirpath);
} else {
//dir already exists we need to empty it out first incase there's old stuff in there we don't want to duplicate data
//$this->removedirectory($newdirpath,false);
}

How to close excel file in php-excel-reader

I am reading two excel file, using php-excel-reader (From this)
After reading two files of 1st row, I am comparing it. If they are same then I am appending contain of on file to other. To write the file I am using this
Now for doing this I want to close one file, but that function is not available in php-excel-reader
here is my code
compare file
{
$data = new Spreadsheet_Excel_Reader($filepath);
$data1 = new Spreadsheet_Excel_Reader($destinationfilepath);
}
unset($data);
unset($data1);
if($flag==0)
{
$excel = new ExcelWriter($destinationfilepath);
// read the source file
$finalarray= array();
for($m=1;$m<$sourcefilerowcount;$m++)
{
$charvalue='A';
$temprow=$m+1;
for($n=0;$n<$destinationcolnum;$n++)
{
$data = new Spreadsheet_Excel_Reader($filepath);
$finalarray[$n]=$data->val($temprow,$charvalue);
$charvalue++;
}
print_r($finalarray)."<br/>";
$excel->writeLine($finalarray);
}
There is no need to explicitly call close() function, because the file is automatically closed in the load() method. If you look at Excel2007.php, where PHPExcel_Reader_Excel2007 is defined, you'll see:
public function load($pFilename)
{
...
$zip = new ZipArchive;
$zip->open($pFilename);
...
$zip->close();
return $excel;
}
Just unset your PHPExcel_Reader object, and the data will be removed from memory:
$objReader = PHPExcel_IOFactory::createReader('Excel2003XML');
$objPHPExcel = $objReader->load("Excel2003XMLTest.xml");
...
unset($objPHPExcel);
unset($objReader);

Generating a PDF using CodeIgniter

I am using dompdf to create a pdf file out of an html file that gets created on-the-fly for the sole purpose of it serving as input for the pdf generator, however I am having trouble doing this, I implemented the code in this thread and everything works fine (I could output a simple pdf) however when I try to give it a more specific url I get this error:
An Error Was Encountered Unable to
load the requested file
here's the code that has the problem:
function printPDF(){
//write_file() usa un helper (file)
$this->load->library('table');
$this->load->plugin('to_pdf');
// page info here, db calls, etc.
$query = $this->db->get('producto');
$data['table'] = $this->table->generate($query);
$path_url = base_url().'print/existencias.html';
write_file($path_url, $data['table']);
$html = $this->load->view($path_url, 'consulta', true);
pdf_create($html, 'consulta');
}
Not sure about the exact problem, but please check this:
1) as stated in CI's manual, load->view's second parameter should be an associative array or an objet, translated to vars via extract. That may generate some problem generating $html.
2) try making $path_url relative to application/views directory, as read in CI's manual.
you should use tcpdf to create a pdf.
//create controller for example :
public function create_pdf()
{
$this->load->library("Pdf");
$data['results'] = // your data
$this->load->view('pdfview',$data);
}
//pdfview is the page having tcpdf code and your pdf code.
You can try it like this
public function export_pdf() {
$filename = 'FILENAME.pdf';
header("Content-Description: Advertise Report");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/pdf; ");
$file = fopen('php://output', 'w');
$header = array("Question", "Answer", "Name", "Email", "Phone", "Date");
fputpdf($file, $header);
fputpdf($file, 'YOUR DATA');
fclose($file);
exit;
}

Categories