Getting Garbled Text while using PHPExcel - php

I am trying to generate an .ods document using PHP Excel.
Below is the code i am using :
public function init() {
$this->objPHPExcel = new PHPExcel();
}
public function indexAction(){
$iexpertsMapper = new Application_Model_IExpertsMapper();
$response = $iexpertsMapper->getAllIExpertsPaymentDues();
$this->objPHPExcel->getProperties()->setCreator("D")
->setLastModifiedBy("D")
->setTitle("D")
->setSubject("D")
->setDescription("D")
->setKeywords("D")
->setCategory("D");
// Headers
$this->objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'H')
->setCellValue('B1', strtotime("today"))
->setCellValue('C1', 'CTPL');
// Redirect output to a client’s web browser (OpenDocument)
header('Content-Type: application/vnd.oasis.opendocument.spreadsheet');
header('Content-Disposition: attachment;filename=bank.ods');
$objWriter = PHPExcel_IOFactory::createWriter($this->objPHPExcel, 'OpenDocument');
ob_end_clean();
$objWriter->save('php://output');
exit;
}
Whenever i hit the code from the browser, an ods document is downloaded with gibberish text. I tried various things including adding ob_end_clean(); in my code. But nothing seems to work. Following text appears in my ODS document : �QĿi!��K�y3�J<���Z1�0?Y�L%zV.
This is what i see when i open the document :

Related

Not saving excel with PHPSpreadsheet in symfony 4

I'm using "phpoffice/phpspreadsheet": "^1.13", can not save updates into uploaded file. I can read data from it but can not save. The other thing to mention I am running it in the Process in background.
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
//read from file
$reader = new Xlsx();
$reader->setLoadSheetsOnly(["Gifts"]);
$spreadsheet = $reader->load($file);
$worksheet = $spreadsheet->getActiveSheet();
$highestRow = $worksheet->getHighestRow();
for ($row = 5; $row < $highestRow; $row++) {
$results[] = [
'id' => $worksheet->getCell('K'.$row)->getValue(),
];
}
//write to file
$spreadsheet = IOFactory::load($file);
$sheet = $spreadsheet->getSheetByName('Gifts');
$sheet->setCellValue('A1', 'Import Status');
$writer = new XlsxWriter($spreadsheet);
ob_end_clean();
$writer->save($file);
If not use ob_end_clean(); the file is saving corrupt and LibbreOffice cannot open it with ob_end_clean(); the file is opening but without changes.
The purpose is to create entities in db reading data from Excel, but because the file can be large I want to run it in the background, maybe it is not the best approach but the best I could do for now so the process is as follows:
upload file
start new process
Process::fromShellCommandline('php /var/www/app/bin/console app:import:excel "'.$file.'"')->start();
redirect user to another page
send an email with a report of imported stuff
All the steps are working fine except saving Excel, when I am opening the uploaded file it does not have any changes, in other question I have found advice like to add ob_end_clean(); or die() it helped at least to open the file without ob_end_clean(); it shows that it is broken.

PHPExcel file is not downloading

I'm attempting to download a spreadsheet using PHPExcel but so far nothing but a blank page.
$items = array("test 1", "test 2", "test 3");
/** PHPExcel */
require_once dirname(__FILE__) . '/../../Classes/PHPExcel.php';
// Create new PHPExcel object
//echo date('H:i:s') . " Create new PHPExcel object\n";
$objPHPExcel = new PHPExcel();
// Set properties
$objPHPExcel->getProperties()->setCreator("User 1");
$objPHPExcel->getProperties()->setLastModifiedBy("User 1");
$objPHPExcel->getProperties()->setTitle(" Quotes");
$objPHPExcel->getProperties()->setSubject("Quotes");
$objPHPExcel->getProperties()->setDescription("Quotes");
// Add some data
$objPHPExcel->setActiveSheetIndex(0);
$loop = 0;
foreach($items as $value) {
$objPHPExcel->getActiveSheet()->SetCellValue('No', $loop);
$objPHPExcel->getActiveSheet()->SetCellValue('Item Name', $value);
$loop++;
}
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="quotes.xls"');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
exit;
I've enabled errors and still blank page.
How do i solve? No file is downloading?
Well you should should be getting errors, or something written to your logs, because your code will throw a fatal
Fatal error: Uncaught exception 'PHPExcel_Exception' with message 'Invalid cell coordinate NO' in ...
Because NO is not a valid cell address in an Excel worksheet, nor is Item Name
The problem is these lines:
$objPHPExcel->getActiveSheet()->SetCellValue('No', $loop);
$objPHPExcel->getActiveSheet()->SetCellValue('Item Name', $value);
A valid cell address is a column (like A) combined with a row (like 1) to give a cell address of A1
Perhaps you meant something like:
$objPHPExcel->getActiveSheet()->SetCellValue('A'.($loop+1), 'No');
$objPHPExcel->getActiveSheet()->SetCellValue('B'.($loop+1), 'Item Name');
$objPHPExcel->getActiveSheet()->SetCellValue('C'.($loop+1), $loop);
$objPHPExcel->getActiveSheet()->SetCellValue('D'.($loop+1), $value);

Error while generating an Excel file

I use the library PHPExcel for generating ".xlsx" files. The file is generated, but when I try to open it I get an error: Excel found some unreadable content. Do you want to fix the content? When I click on "yes" it opens my file with the content I want.
How can I avoid this error? I've already deleted all the spaces after the <?php ?> tags, I've already checked that I don't have HTML before the file is generated, but I still don't know where my error is.
Here is my code:
<?php
include ('/lib/PHPExcel/PHPExcel.php');
include ('/lib/PHPExcel/PHPExcel/IOFactory.php');
// I use session for now when the excel is generate
$_SESSION['downloadstatus'] = array(
"status" => "pending"
);
// Creation of the Excel File
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()
->setCreator("Temporaris")
->setLastModifiedBy("Temporaris")
->setTitle("Template Relevé des heures intérimaires")
->setSubject("Template excel")
->setDescription("Template excel permettant la création d'un ou plusieurs relevés d'heures")
->setKeywords("Template excel");
$objPHPExcel->setActiveSheetIndex(0);
$sheet = $objPHPExcel->getActiveSheet();
// Add the content of Excel File
$indiceColumn = "A";
$indiceLine = 1;
$defaultColumns = array("Matricule", "Nom_Prenom", "Siret_etablissement", "Regate_etablissement", "Centre_analytique", "Date");
foreach ($defaultColumns as $columnName) {
$sheet->SetCellValue($indiceColumn . $indiceLine, $columnName);
$indiceColumn++;
}
$listColumnName = EDIXIS_db_query("select csv_nom_col FROM temporaris_eu_config_ent_csv WHERE id_config = " . $id_sel . " ORDER BY id");
while ($columnName = EDIXIS_db_fetch_object($listColumnName)) {
$sheet->SetCellValue($indiceColumn . $indiceLine, $columnName->csv_nom_col);
$indiceColumn++;
}
// Send the Excel File to the user
$writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="template.xlsx"');
header('Cache-Control: max-age=0');
$writer->save('php://output');
$_SESSION['downloadstatus'] = array(
"status" => "finished",
"message" => "Done"
);
?>
----- Edit -----
I try to check the difference between a repair file and the error file so i open them with notpad++.
Their is some caracters who are differents between the error file and the repair file :
some • who became «
some " who became « too
This line
‚›.›”Ò© +#SdÕ Eë ݲäÄfÃH*²?ÙÑý®³+ # î幜ᨽ]YC^!&íÝŒVSN 8é•v‹}œßOn(IY8%Œw0£kHô¶{×ÊÐHá{ôbÖ‚\jd˜ÑeΡa,É%X‘¦èp(>ûhEÆe\° ä‹X «9ÿÄ,d¡DlNÂHwH%ÈÐGS J20ÁåĪiÅŽÞѦ77åÄiu^xÓºîUÒã0ÓáºXñüûõðíg)u¢ÝØ* ´k•ld‘}ìæƒ"êÔ²“ÏcHù›ý¬A}YŸ9/ÕvWÜ– Šà¡šm {åéúîëüžv5¯>N8>æüsS󦮯xÝp>žàr¤Ú]Òÿa÷”Ò¬³R•Á,ò¯ìuCËúˆ/íò&j+4.Js¶;ƽè’Q‡Œsy$ÀJ‚!883ØéLŒ 2nÄè"ê}ïˆïI0}ÒÈO$–À„Ê6¯Dœ‚Ç Ôÿþ2ÿR¬{i¼ªX>ªtá;ÕÊoÚÂG¼/v¹:ûeº¿PK ”J¤Fs‘{Y³ ¦ xl/theme/theme1.xmlíYOoÛ6¿ïSº·²lÉu‚:EìØëÖ¦
who became this line
Ë7\ ÖIDiV´W¬„ +¸5ölkÖ;›ö‘ûLܺwH‘"çÇ3ž´·kgÙ32ÁÏy=­8¯‚6~9ç‹»ÉÎR–^K<Ìù¿í^µ*6* |óÄäS£âœ¯rŽI­ÀÉ4%‡'ñ1 “™–¸Qª'¹1«ª÷ÂA–Zf)Fà$‰|Ôꈌ=ÚÐJ€>'QOkqòf#—^ÜP”3§3yáEëA<º×ÉÃ0L‡›b¥ó×â×ý×¥Ô‰ñc«ð®ÕªQ2ìàb#‰&µâìóØB+S¾§f?П6ÎkµÝ·#€ft¨fWÂAùyóùËâŽw³ª~7©èy»¨>6³º©goªYSUã . 'ªÛ'ýö#)È&[(UYÊbßéÊž·LÓ°¬ GzŸ·hœ4´(ÍÙí÷’K¡‰™æòD€µËh>hf¨Ó™YÉnåèbúuïYèY´}2ÄOK"e—W"ÎÁcPêÿ•ÿ )Öƒ4^Õl†€:]ùεò[¶H÷%®W¿L÷PK «J¤Fs‘{Y³ ¦ xl/theme/theme1.xmlíYOoÛ6¿ïSº·²lÉu‚:EìØëÖ¦
So i think it's an encode problem. But i still don't know how can i resolve it.
the issue is your $_SESSION code at the end.
$_SESSION['downloadstatus'] = array(
"status" => "finished",
"message" => "Done"
);
Since the headers have already been output, I'm almost certain you are getting a php warning appended to the end of your excel document. Make the following changes and it should work.
$_SESSION['downloadstatus'] = array(
"status" => "finished",
"message" => "Done"
);
// Send the Excel File to the user
$writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="template.xlsx"');
header('Cache-Control: max-age=0');
$writer->save('php://output');
exit;
I find the problem it was so stupid. It's just that it's not allow to put some specials characters in $objPHPExcel->getProperties() so i replace every 'é' by 'e' and now it's work.

Why PHP continue to output to CSV file after fclose()?

On a web page, I am writing some data into a CSV file using the below code and finally closing with fclose();
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$filename);
$out = fopen('php://output', 'w');
fputcsv($out, $cvs_cols);
fclose($out);
echo "HELLO WORLD"; // sneaks into CSV!?
Why is it that "HELLO WORLD" gets into the CSV download file when it has already fclose()? I want to output the rest of the HTML for the page to be displayed in the browser. How can I do that?
After 1 HTTP request follows 1 response. You cannot send content type text/csv and content type text/html at the same time (maybe yes with SPDY, but not with pure HTTP).
fclose closes your file descriptor but not the output to the browser.
You should also set a Content-Length header and put in the filesize.
Mark Baker already gave the most important point in the comments:
echo and writing to php://output puts content into the same stream: STDOUT. Other options would be to write the CSV to memory (but its senseless if you don't use it) or to a file. Read more about the those streams: http://www.php.net/manual/en/features.commandline.io-streams.php
Possible solution:
You need 2 HTTP requests. 1 For the download, the other for your HTML. Most popular way is it to first use the HTML response and put something in like
<meta http-equiv="refresh"
content="3; URL=http://yourserver.com/download.php?id=pdf&id=123" />
This starts the download after 3 seconds.
There is no 'CSV File' (yet).
What you are doing is sending a data stream to the client, and telling the client that this stream has a Content-Type of text/csv and a filename of $filename. The client can then chose to save this as a CSV file or just display it in the browser.
This code:
$out = fopen('php://output', 'w');
fputcsv($out, $cvs_cols);
fclose($out);
Is effectively doing the same thing that echo $cvs_cols would do (with a little extra stuff to format a csv output).
So when there is a call to echo "HELLO WORLD"; it gets sent in the same data steam as the contents of the $cvs_cols variable.
When you call fopen('php://output', 'w') you are creating a second file handle to php://output as one is created by default to output from calls to echo etc. So when you are calling fclose($out) you're only closing the second file handle.
A very old thread here but to fix this I just added a simple exit(); command. So a button calls the same page with a query string of 'action=export_csv' then that action is run with the exit(); on the last line, hope that helps out.
Export CSV
Then the 'action' on the page is:
if(isset($_GET['action']) && $_GET['action']=='export_csv'){
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=email-responses.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Email address'));
$db = new PDO('mysql:host=hostname_mysql;dbname=database_mysql;charset=UTF8', username_mysql, password_mysql);
$query = "SELECT XXX FROM XXXX";
$result = $db->query($query);
$data = $result->fetchAll(PDO::FETCH_ASSOC);
// loop over the rows, outputting them
foreach($data as $row){
fputcsv($output, $row);
}
fclose($output);
exit();
}
use
ob_clean() : ob_clean — Clean (erase) the output buffer
flush() : flush — Flush the output buffer(flush)
ob_start();
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$filename);
$out = fopen('php://output', 'w');
fputcsv($out, $cvs_cols);
fclose($out);
ob_end_clean(); // the buffer and never prints or returns anything.
echo "HELLO WORLD"; // sneaks into CSV!?

CP1251 Encoding issue in html2pdf

I was download and setup script from:http://www.html2pdf.fr/en
It works fine with default encoding, but when I try to generate docs with characters in CP-1251, I got white spaces instead of characters.
Also All my files in CP-1251,data in base in CP-1251 and as you can see I use simple font -Arial
Please, maybe exist some solution to get it to work.
P/s sorry for my english
ob_start();
include(dirname(__FILE__).'/res/exemple00.php');
$content = ob_get_clean();
require_once(dirname(__FILE__).'/../html2pdf.class.php');
try
{
$html2pdf = new HTML2PDF('P','A4','fr');
$html2pdf->setDefaultFont('Arial');
$html2pdf->writeHTML($content, isset($_GET['vuehtml']));
$content1=$html2pdf->Output('', 'S');
// Some php code
$db->query("set names cp1251");
$query="SELECT data from files Where id=$file_id ";
$result=$db->query($query);
$row=$result->fetch_assoc();
$content=($row['data']);
header('Content-Type: application/pdf');
header("Content-Length: ".strlen(content));
header('Content-Disposition: attachment; filename=Invoice#'.$invoice_id.'.pdf');
print $content;
}
catch(HTML2PDF_exception $e) { echo $e; } enter code here
I am not using this library, but are you setting your encoding in the HTML2PDF constructor?
$html2pdf = new HTML2PDF('P','A4','fr', true, 'CP-1251');
If it does not work, try 'cp1251' or 'CP1251', I do not find list of recognized encodings in the documentation. You can also use iconv and convert to UTF-8 as it seems to be a default.

Categories