PHPExcel exporting "corrupted" .xlsx file - laravel-4

I have a function in Laravel that allows the user to export reports from their application. So far exporting .csv is working fine, though when giving them the option to export out to .xlsx it throws an error about the extension not being valid.
Below is the function that is called for exporting.
public function export($fileName, $data, $fileType) {
$xls = new PHPExcel();
$xls->setActiveSheetIndex(0);
if (count($data) > 0) {
$acols = array_keys($data[0]->toArray());
$xls->getActiveSheet()->fromArray($acols, NULL, 'A1');
$xls->getActiveSheet()->fromArray($data->toArray(), NULL, 'A2');
switch ($fileType) {
case 'csv':
$objWriter = new PHPExcel_Writer_CSV($xls);
break;
case 'xlsx':
$objWriter = new PHPExcel_Writer_Excel2007($xls);
$objWriter->setOffice2003Compatibility(true);
break;
case 'html':
$objWriter = new PHPExcel_Writer_HTML($xls);
return $objWriter->generateSheetData();
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=$fileName");
header("Content-Transfer-Encoding: binary ");
$objWriter->save('php://output');
return;
}
return Redirect::back();
}

This tampering is due to space/ spaces in your code files which corrupt your data passed into excel. you have to debug every corner file by file to identify if there is any space which is not required. It can be at the start of the file i.e. before
If using linux, this command might help to look for right files
find . "*" | xargs grep -il \ \<\?php >> php.txt

The trick: ob_end_clean. It seems that the buffer does not get properly cleaned up, so there is an extra space added. But by doing this, the file was downloaded and was able to be opened.
ob_end_clean();

Related

The file doesn't exist laravel

public function readPDF($file_id)
{
$file_id = SiteHelpers::encrypt_decrypt($file_id, 'd');
$file_details = $this->model->getFileDetails($file_id);
if($file_details){
$file = Storage::url('app/public/course/'.$file_details->course_id.'/'.$file_details->file_name.'.'.$file_details->file_extension);
print_r($file);
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename=document.pdf');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
// #readfile($file);
return response()->file($file);
}
}
I have this function to display uploaded pdf file. I removed the former #readfile($file); as it does nothing and displays nothing. I did troubleshoot on my file path ($file) and the resulted url displayed pdf. But when I used latter function return response()->file($file); it displayed error that file doesn't exist but my $file string is correct. Could someone help me with that?

Return response to client before running event Laravel

Is there an less ugly way to do this:
ignore_user_abort(true);
set_time_limit(0);
ob_start();
echo $response; // send the response
header('Connection: close');
header('Content-Length: '.ob_get_length());
ob_end_flush();
ob_flush();
flush();
in Laravel? Basically i need the server to return response to user before running the events, I can't do this using queue because there's a lot of things that will be done, and a lot of clients simultaneously doing this action and those things need to be done instantly, so they can't be executed one by one. The events consist in sending mails, alerts, updating data on website tables, etc.
I have a similar need in a project where I was creating a tracking pixel. I wanted to immediately return a response to them and then Laravel continue running. I put this as the very first thing in index.php:
if($_SERVER['REQUEST_URI'] == '/pixel'){
require "pixel.php";
}
Then in that file (some of this may not be relevant to you, i needed to make sure they didnt cache it so it continues to load the pixel:
ignore_user_abort(true);
// turn off gzip compression
if ( function_exists( 'apache_setenv' ) ) {
apache_setenv( 'no-gzip', 1 );
}
ini_set('zlib.output_compression', 0);
// turn on output buffering if necessary
if (ob_get_level() == 0) {
ob_start();
}
// removing any content encoding like gzip etc.
header('Content-encoding: none', true);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo ' ';
} else {
header("Content-type: image/gif");
header("Content-Length: 42");
header("Cache-Control: private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
header("Expires: Wed, 11 Jan 2000 12:59:00 GMT");
header("Last-Modified: Wed, 11 Jan 2006 12:59:00 GMT");
header("Pragma: no-cache");
echo sprintf('%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%',71,73,70,56,57,97,1,0,1,0,128,255,0,192,192,192,0,0,0,33,249,4,1,0,0,0,0,44,0,0,0,0,1,0,1,0,0,2,2,68,1,0,59);
}
// flush all output buffers. No reason to make the user wait for OWA.
ob_flush();
flush();
ob_end_flush();
That's it. Now, Laravel continues to run, but the user's browser has ended its request. So then I added a route like normal at /pixel and did all of the stuff I needed to do (add to database, fire events, etc).

How to Use PdfCrowd Api In codeigniter?

Hello Iam Using pdfCrowd Api to convert to pdf. If i use convertfile To specify view it says path is not not valid? How to Pass view to pdfCrowd's Convertfile Function?
function download() { require('pdfcrowd.php'); $user_id=$this->session->userdata('user_id'); $data = array(); $data['result']=$this->user_data_model->getcertificate($user_id); try { // create an API client instance $client = new Pdfcrowd('username','api');
// convert a web page and store the generated PDF into a $pdf variable $pdf = $client->convertFile('certificate_template'); // set HTTP response headers header("Content-Type: application/pdf"); header("Cache-Control: max-age=0"); header("Accept-Ranges:
none"); header("Content-Disposition: attachment; filename=\"google_com.pdf\""); // send the generated PDF echo $pdf; } catch(PdfcrowdException $why) { echo "Pdfcrowd Error: " . $why; } }
function download() {
require('pdfcrowd.php');
$user_id=$this->session->userdata('user_id');
$data = array();
$data['result']=$this->user_data_model->getcertificate($user_id);
try
{
// create an API client instance
$client = new Pdfcrowd('username','api');
// convert a web page and store the generated PDF into a $pdf variable
$pdf = $client->convertFile('certificate_template');
// set HTTP response headers
header("Content-Type: application/pdf");
header("Cache-Control: max-age=0");
header("Accept-Ranges: none");
header("Content-Disposition: attachment; filename=\"google_com.pdf\"");
// send the generated PDF
echo $pdf;
}
catch(PdfcrowdException $why)
{
echo "Pdfcrowd Error: " . $why;
}
}
convertFile method accepts local HTML file only, it can't be template.
You have 2 options:
use convertURI with your rendered template instead convertFile
or
render your template to temporary local HTML file and use it in convertFile method

Cannot get file created with fopen

I've created a file with fopen as so
$string = '<?php
define ("DB_HOST", "'. $_POST["dbhost"]. '");
define ("DB_USER", "'. $_POST["dbuname"]. '");
define ("DB_PASS","'. $_POST["dbpass"]. '");
define ("DB_NAME","'. $_POST["dbname"]. '")
?>';
$confile = "../lib/con.php";
if (!file_exists($confile)) {
$fp = fopen($confile, "x") or die("can't open file ".$confile);
fwrite($fp, $string);
fclose($fp);
} else {
$fp = fopen($confile, "w") or die("can't open file ".$confile);
fwrite($fp, $string);
fclose($fp);
}
However now if I try to download the file using Dreamweaver or Filezilla it won't download the file unless I rename it. Can anyone work out what I may be doing wrong here?
Con in a web server sense is considered a reserve, to some web hosts, and that when writing to a file named con, it sometimes fail, if you rename the the file to conn.php it should work.

Codeigniter force download CSV file bug

Here's the problem
I wanted to convert my data into csv format and download it. everything is fine, until the csv file that i had downloaded and there's a little bug on the file which there will be a space at the first line of the file.
for example
Before force download
"name","age",
"brad pit","40",`
After force download
"name","age",
"brad pit","40",
The csv file that i had downloaded and I try to open wit my excel will appear like this
"name" |age
brad pit|40
I believe that is because of the csv file that i had downloaded appeared an external space line in the first line of the data.
Here's the code
//write csv data
$data = $this->dbutil->csv_from_result($query, $delimiter);
//create random file name
$name = rand().'_salesperson_data_'.date('d-m-y').'.csv';
if ( ! write_file('./csv/'.$name, $data))
{
echo 'Unable to write the CSV file';
}
else
{
//perform download
$file = file_get_contents("./csv/".$name); // Read the file's contents
$filename = 'salesperson_data_'.date('d-m-y').'.csv';
force_download($filename, $file);
}
source of force_download()
if ( ! function_exists('force_download'))
{
function force_download($filename = '', $data = '')
{
if ($filename == '' OR $data == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
#include(APPPATH.'config/mimes'.EXT);
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}
exit($data);
}
}
i thought TRIM will be last solution for me and I try to put any where possible but is stil the same. I couldn't found any solution for this problem. Please help. this stuck me for 2days already.
Thanks in advanced.
I don't know if need to use CSV only, but a good plugin/function that I use is this one: http://codeigniter.com/wiki/Excel_Plugin/
It's works with CodeIgniter Query system for exporting stuff to Excel. I use it a lot and never have problems with it.
try to print on the browser, if you see some extra space then remove.
if the extra is still on the csv file when you download, then this extra space is coming from any of your include file.
when you start writing your code try not to leave some space on the top/bottom of the code.
Use ob_clean(); before writing CSV to remove White spaces.

Resources