I use a file to build an array from a database, and I want to write to an excel sheet based on this array.
As such I include the file in the following code
(the code below is a complete copy paste of the code used to read from an excel template, edit the data, and write the file and prompt a download for the user)
/** Error reporting */
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
date_default_timezone_set('Europe/London');
if (PHP_SAPI == 'cli')
die('This example should only be run from a Web Browser');
/** PHPExcel_IOFactory */
require_once '../Classes/PHPExcel/IOFactory.php';
$objReader = PHPExcel_IOFactory::createReader('Excel5');
$objPHPExcel = $objReader->load("template.xls");
//HERE IS MY INCLUDE FILE
include($_SERVER["DOCUMENT_ROOT"] . "/includes/excelwrite_data.php");
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A2', 'TEST')
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header ('Cache-Control: cache, must-revalidate');
header ('Pragma: public');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
This generates a garbled excel file output, and warnings of corrupted data (similar to what happens when your php results in some echod character that messes it up. I have checked that my included file echoes nothing.
What is bizarre, is if I literally copy paste the contents of the included file into the spot where the include is in the above code, it works perfectly.
Is there something about includes that doesn't play well with PHPExcel?
Many thanks for your thoughts in advance.
Related
I know PHPExcel is deprecated and replaced with PHPSpreadsheet. I am planning to migrate in the near future but would like to address this problem anyway.
When using MS Office 2016 Office Excel on a Windows 10 Pro environment I get this message:
We found a problem with some content in 'Myfile.xlsx'. Do you want us to try to recover as much as we can?
Click Yes
Microsoft Excel was attempting to open and repair the file. To start this process again, choose Open and Repair from the Open file dialog.
Code works fine using LibreOffice. Also if I open the file in LibreOffice and save it with a different filename then it opens fine in MS Excel. Below is my code snippet, is there anything in this code that would cause this to happen.
Thank you
$filename = "Myfile.xlsx";
$objWriter = PHPExcel_IOFactory::createWriter($this->excel, "Excel2007");
header('Content-Type: application/vnd.ms-excel; charset=UTF-8');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter->save('php://output');
Edit:
Snippet how rows and columns are built
if($data_type=="float" || $data_type=="decimal" || $data_type=="numeric"){
$this->excel->getActiveSheet()
->getStyle($cell)
->getAlignment()
->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$this->excel->getActiveSheet()
->setCellValueExplicit($cell, $this_val, PHPExcel_Cell_DataType::TYPE_NUMERIC);
}
else{
$this->excel->getActiveSheet()
->setCellValueExplicit($cell, $this_val, PHPExcel_Cell_DataType::TYPE_STRING);
}
If I change from XLSX to XLS
From this
$filename = "Myfile.xlsx";
$objWriter = PHPExcel_IOFactory::createWriter($this->excel, "Excel2007");
To this
$filename = "Myfile.xls";
$objWriter = PHPExcel_IOFactory::createWriter($this->excel, "Excel5");
It works ok. It only fails if using Excel2007
I'm trying to store Excel generated file to server directory instead of downloading after reaching path.
My code:
// worksheet
$objPHPExcel->getActiveSheet()->setTitle('Podaci');
$objPHPExcel->setActiveSheetIndex(0);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="mjesecni_podaci.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header ('Cache-Control: cache, must-revalidate');
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
//$objWriter->save('php://output');
$putanja_spremanja_fajla = 'mail/mjesecni_podaci.xlsx';
$objWriter->save($putanja_spremanja_fajla);
sleep(1);
slanje_maila($db, $datum);
I tried to remove some of header lines, but then my file is corrupted or I get some of errors.
Any suggestions?
Remove all header()'s
Use full path's: e.g /home/database/public_html/application/mail/
Cron job: Remove if (PHP_SAPI == 'cli') die('This example should only be run from a Web Browser'); because this line of code checks if script is "called" by server(cgi-fcgi) or user(cli).
After that, you can use cron jobs or similar (if sever trying to run .php script).
If you trying to reach link trough web browser, you must use headers because headers talk with browser.
the following lines tell the browser to expect a file. (The Excelfile mjesecni_podaci.xlsx to be exact)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="mjesecni_podaci.xlsx"');
If you tell PHPExcel to save the file to disk, no file is delivered to the browser.
If there is no output at all or some kind of echo or something else, you will either get an Error-Message or the browser "downloads" the file "mjesecni_podaci.xlsx" with the output you produced.
For example:
<?php
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="mjesecni_podaci.xlsx"');
echo "Hello World!"
?>
This code will download the File "mjesecni_podaci.xlsx" with the content "Hello World!". (Save the file to disk and open it with an editor like Notepad++ or similar)
In your code, you should just remove the two lines, and make sure that your program can write to the subfolder "mail". Your code should work after that. (at least the part before sleep(1);) .
OK, now I read examples of phpexcel. As I understand there shouldn't be any other output on page, to make proper xls-file. I think so, because when I have
echo "some output and my form for query";
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()->setCreator("Administrator");
$objPHPExcel->getProperties()->setLastModifiedBy("Administrator");
$objPHPExcel->getProperties()->setTitle("test");
$objPHPExcel->getProperties()->setSubject("test");
$objPHPExcel->getProperties()->setDescription("test");
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->SetCellValue('A1', 'Hello');
$objPHPExcel->getActiveSheet()->SetCellValue('B2', 'world!');
$objPHPExcel->getActiveSheet()->SetCellValue('C1', 'Hello');
$objPHPExcel->getActiveSheet()->SetCellValue('D2', 'world!');
$objPHPExcel->getActiveSheet()->setTitle('Simple');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
// Redirect output to a client’s web browser (Excel5)
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
echo"some other code";
And get xls, it has warnings that it doen't have css links there and moreover it puts a lot of text except Hello world!, such as links in excel file.
It looks like this:
I can put all work with xls in other php file and get it with ajax, but how can I give results of query to this file? All queries should be in my main file, because I don't want to have multiple connections to database. How it is clear, what I want. Any advices?
To download xls(x) file, you have to set right headers and clean the buffer to avoid bad stream.
As documentation explains you can try with this code:
//------------- Enter your code before this line --------- //
// Cleaning buffer
ob_clean();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
/* Or you can use
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
*/
// redirect output to client browser
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="your_filename.xls"');
/* Use this for Writer Excel2007
header('Content-Disposition: attachment;filename="your_filename.xlsx"');
*/
header('Cache-Control: max-age=0');
//Start Download
$objWriter->save('php://output');
You can refer here for the Developers Documentation of PHPExcel
I am using PHPEXxcel to export an HTML Table generated using MYSQL and its like this.
<?php $query = "SELECT `Firstname`,`Lastname`,`Branch`,`Gender`,`Mobileno`, `Email`
FROM `student_details` WHERE Branch IN ('$branch') and `Year`='$year'
and Tenthresult > '$tenth' and
Twelthresult > '$twelth' and (CGPA > '$cgpa' || CGPA = '$cgpa')";
$result = mysql_query($query);
confirm_query($result);
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$rowCount = 1;
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowCount,'Firstname');
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowCount,'Lastname');
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount,'Branch');
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount,'Gender');
$objPHPExcel->getActiveSheet()->SetCellValue('E'.$rowCount,'Mobileno');
$objPHPExcel->getActiveSheet()->SetCellValue('F'.$rowCount,'Email');
while($row = mysql_fetch_array($result)){
$rowCount++;
$objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowCount, $row['0']);
$objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowCount, $row['1']);
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount, $row['2']);
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount, $row['3']);
$objPHPExcel->getActiveSheet()->SetCellValue('E'.$rowCount, $row['4']);
$objPHPExcel->getActiveSheet()->SetCellValue('F'.$rowCount, $row['5']);
}
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->save('some_excel_file.xlsx');
?>
Its working but it saves the xlsx file in the root folder without showing to user any signs that its being downloaded.
This code rund when i click a button.now, can i make it to be downloaded like we download a mail attachment and showing the user in the front end that its being downloaded along with the location.
I tried using
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="01simple.xls"');
header('Cache-Control: max-age=0');
With this, i am getting what i wanted above but the xls file downloaded when opened shows
the message
'The File you are trying to open 'filename' is in a different format than the specified extension.....etc.Do you want to open now?
On opening it contains either the entire HTML Page or its simply blank...
Can anybody help me..?
Spreadsheets 101
There are many different spreadsheet file formats, each with their own different filename extensions, and that can be sent to a web browser using different mime types. These are described in the PHPExcel documentation, and each has its own different Writer in PHPExcel. You're mismatching two different formats
BIFF Format
Used by Microsoft Excel between versions 95 and 2003 File
extension: xls
PHPEXcel Writer: PHPExcel_Writer_Excel5
Mime Type: application/vnd.ms-excel
OfficeOpenXML Format
Used by Microsoft Excel since version 2007
File extension: xlsx
PHPEXcel Writer: PHPExcel_Writer_Excel2007
Mime Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Don't mix and match: if you do, then Excel will (and justifiably) complain. If you want a BIFF file, use PHPExcel's BIFF Writer (Excel5), a file extension of .xls, and the mime type listed above for BIFF Format. If you want an OfficeOpenXML file, then use PHPExcel's Excel2007 Writer, a file extension of .xlsx, and the mime type listed above for OfficeOpenXML.
EDIT
Note that the examples provided with the PHPExcel distribution include 01simple-download-xls.php and 01simple-download-xlsx.php to demonstrate exactly what you want
Just adding those headers only sends those headers. The rest of your code is still the same, so you're saving your xls to your root folder like you used to.
Sending the headers only makes the page you would normally see be send with xls headers. Something which is not what you want, and you're getting your HTML page but with the wrong headers.
What you need to do is send those headers and then stream the xlsx.
Looking at a random thread (I know, bad idea, but this'll get you a headstart on what to do) here, you can find examples like this:
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.xls");
header("Content-Transfer-Encoding: binary ");
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->setOffice2003Compatibility(true);
$objWriter->save('php://output');
I do it with using below snippet.
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="test_file.xlsx"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
try this ..
header('Content-Type: application/vnd.ms-excel');
$filename = "Reports".date("d-m-Y-His").".xls";
header('Content-Disposition: attachment;filename='.$filename .' ');
header('Cache-Control: max-age=0');
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output');
I'm trying to download Excel files (xlsx) using PHPExcel as follows.
require_once("../../phpExcel/Classes/PHPExcel.php");
require_once("../../phpExcel/Classes/PHPExcel/IOFactory.php");
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()->setCreator("Tiny")
->setLastModifiedBy("Tiny")
->setTitle("Office 2007 XLSX Test Document")
->setSubject("Office 2007 XLSX Test Document")
->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.");
$objPHPExcel->setActiveSheetIndex(0);
$sheet=$objPHPExcel->getActiveSheet();
$sheet->setCellValue('A1', 'Hello');
$sheet->setCellValue('B2', 'world!');
$sheet->setCellValue('C1', 'Hello');
$sheet->setCellValue('D2', 'world!');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="test.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
It works but when I try to open the Excel file, it asks for a confirmation in a conform dialog.
Excel found unreadable content in 'test.xlsx'. Do you want to recover
the contents of this workbook? If you trust the source of this
workbook, click Yes.
I also tried to change the header as follows
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=test.xlsx");
header("Content-Transfer-Encoding: binary");
It still asks for the same confirmation. What am I doing wrong here, please?
As told by questioning user Tiny on his own comment:
Finally, it worked. I just added exit at the end of my PHP script (at
the end of the first code snippet in the question). Thanks very much
all of you for giving me useful hints.
To give some constructive additional tips on this kind of problems:
A good tip is that you can omit the closing tag ?> on all your PHP script files, that way you know that you're not sending any aditional invisible whitespace at the end of it.
Also enconding PHP script files on UTF-8 on wrongfully configured web server can send an undesirable couple bytes at the begining of the script. Open the PHP file on Notepad++, check if it's UTF-8, and in that case, convert it to ANSI. If that makes it work, check your webserver/php configuration.
Just before the header calls, you can check if headers has been wrongfully sent with:
if ( headers_sent() ) die("**Error: headers sent");
If you can't prevent that some function call sends undesirable strings to the browser, you can "erase" all of it using at the very beginning of your script:
ob_start();
and then, just before the first headers call, use:
ob_clean();
Be careful that with doing so will prevent you for receiving error feedback.
And lastly, as already said, if nothing has to be executed afterwards some point on the script, call exit or die.
Well I had this problem, my solution was changing the header Content-type to :
header('Content-Type: application/openxmlformats-officedocument.spreadsheetml.sheet');
I had before:
header('Content-Type: application/vnd.ms-excel');
and I changed the format to Excel2007, I was using Excel5 for excel 2003 xls format.
I tried all the solutions from this page and all the other pages with the same question but not luck.
So basically, I just changed the output format of my excels and that solved the problem.
This error can also be triggered by serving the file without the Content-Length headers.
Look at the example given here in php.net
Give the active sheet a title:
$sheet->setTitle('Some title string here');
I Put just exit; After
PHPExcel_IOFactory::createWriter($phpExcelObject, 'Excel2007')->save("php://output");
and it work's for me :)
$file_name .= "_".\Carbon\Carbon::now()->format('d_m_Y_H_i').'.xlsx';
// Prepare To Download
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename='.$file_name);
header('Cache-Control: max-age=0');
header('Pragma: public');
PHPExcel_IOFactory::createWriter($phpExcelObject, 'Excel2007')->save("php://output");
exit;
This might help to someone who tries to download excel using https://github.com/Maatwebsite/Laravel-Excel package in laravel with get route with ajax
I got response something like PK ¾#G’D²X ð [Content_Types].xml”MNÃ0…÷œ"ò%nY „švAa •(0ö¤±êØ–gúw{&i‰#ÕnbEö{ßøyìÑdÛ¸l mð¥‘×ÁX¿(ÅÛü)¿’òF¹à¡;#1_滘±Øc)j¢x/%ê…Eˆày¦ ©QÄ¿i!£ÒKµ y3ÜJ<§œZ1½0?YÙL%zV cäÖIb7؇û‰ìa/lÙ¥P1:«qáríÍjªÊj0A¯–Íuë""íàÙ(Œ ”Á€WìMä)Tjå and much more content
i tried many of the solution but fails
finally i achieved by doing this in onclick event
$(document).on('click','#elementId',function(e){
e.preventDefault();
window.location.assign('your action url'+'?param='+ param_data);
}
my php : 7.4.1 os: Ubuntu 18.04 frameword: Yii2.0.37 I had also this problem and my solution is that I use exit and ob_clean()
$objPHPExcel = new \PHPExcel();
$objPHPExcel->getProperties()->setCreator("Murodjon Abduvohidov")
->setLastModifiedBy("Murodjon Abduvohidov");
$objPHPExcel->getActiveSheet()->getPageSetup()-> setOrientation(\PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)
->setPaperSize(\PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(70);
$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScaleNormal(82);
$objPHPExcel->getActiveSheet()->getSheetView()->setView(\PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW);
$objPHPExcel->getActiveSheet()->getPageSetup()->setScale(63);
$objPHPExcel->getActiveSheet()->getPageMargins()->setTop(0.4);
$objPHPExcel->getActiveSheet()->getPageMargins()->setRight(0.4);
$objPHPExcel->getActiveSheet()->getPageMargins()->setLeft(0.4);
$objPHPExcel->getActiveSheet()->getPageMargins()->setBottom(0.4);
$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial');
$objPHPExcel->getDefaultStyle()->getFont()->setSize(10); $objPHPExcel->getActiveSheet()->getCell('A2')->setValue('salom');
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');ob_clean();
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="abdulqodir.xlsx"');
header('Cache-Control: max-age=0');
header('Cache-Control: max-age=1');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
$objWriter->save("php://output");exit;`