问题
I know this might have been asked in several pieces, but I could not find an exact answer to the issue. I am using PHPExcel to generate an Excel file (obviously), and the code works to generate the file, but not when I include the code for Force Download, it corrupts the file. My latest version of the script looks like this:
function make_xls_spreadsheet(){
/** Error reporting */
error_reporting(E_ALL);
/* Set the save path */
define('XLSX_SAVE_PATH', 'tmp/');
/** Include path **/
set_include_path(get_include_path() . PATH_SEPARATOR . 'Classes/');
/** PHPExcel */
include 'PHPExcel.php';
/** PHPExcel_Writer_Excel2007 */
include 'PHPExcel/Writer/Excel2007.php';
/* Create a new PHPExcel Object */
$objPHPExcel = new PHPExcel();
/* Add some metadata to the file */
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw");
$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw");
$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document");
$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document");
$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.");
/* Set active worksheet to first */
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setTitle('Segments');
/* Add some data to the worksheet */
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->SetCellValue('A1', 'Hello');
$objPHPExcel->getActiveSheet()->SetCellValue('B2', 'world!');
$objPHPExcel->getActiveSheet()->SetCellValue('C1', 'Hello');
$objPHPExcel->getActiveSheet()->SetCellValue('D2', 'world!');
/* Write to server */
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$filename = "tony1.xlsx";
// Works fine up to here
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
//$objWriter->save('php://output');
$objWriter->save(XLSX_SAVE_PATH . $filename);
readfile(XLSX_SAVE_PATH . $filename);
echo "DONE!";
$objPHPExcel->disconnectWorksheets();
unset($objPHPExcel);
}
Remember, when I remove the force code section, the file generates and I can FTP it down fine. However, doing both generating and forcing the file gives me a corrupt file. Normally I can click "Open & Repair" (Office2011 MacOSX) but obviously this is not desirable.
Could someone please help me understand:
- Why it is being generated as corrupt? And why it works fine when I don't force download.
- What the proper order for saving/forcing is (using PHP's header() function)
- If there is a better way of doing this.
Much appreciated!!
**** Update **** Here is the code when I click "Fix & Repair":
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<logFileName>Repair Result to tony1 03178.xml</logFileName>
<summary>Errors were detected in file 'Macintosh HD:Users:tony.diloreto:Downloads:tony1.xlsx'</summary>
<additionalInfo><info>Excel completed file level validation and repair. Some parts of this workbook may have been repaired or discarded.</info></additionalInfo>
</recoveryLog>
回答1:
// answer actually belongs to @Dagon
The answer is actually straightforward, only needing a simple exit();
call.
Final code block:
function make_xls_spreadsheet(){
/** Include path **/
set_include_path(get_include_path() . PATH_SEPARATOR . 'Classes/');
/** PHPExcel */
include 'PHPExcel.php';
/** PHPExcel_Writer_Excel2007 */
include 'PHPExcel/Writer/Excel2007.php';
/* Create a new PHPExcel Object */
$objPHPExcel = new PHPExcel();
/** Determine filename **/
$filename = "tony1.xlsx";
/** Set header information **/
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
/* Add some metadata to the file */
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw");
$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw");
$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document");
$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document");
$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.");
/* Set active worksheet to first */
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setTitle('Segments');
/* Add some data to the worksheet */
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->SetCellValue('A1', 'Hello');
$objPHPExcel->getActiveSheet()->SetCellValue('B2', 'world!');
$objPHPExcel->getActiveSheet()->SetCellValue('C1', 'Hello');
$objPHPExcel->getActiveSheet()->SetCellValue('D2', 'world!');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
exit();
}
回答2:
This spits out the excel file to the browser:
readfile(XLSX_SAVE_PATH . $filename);
and then you spit this out, which becomes PART of the excel file as downloaded by the browser
echo "DONE!";
essentially you're sending
[excel data]DONE!
when Excel is expecting only
[excel data]
回答3:
Try to modify File.php like this :
protected static $_useUploadTempDirectory = TRUE;
in folder phpexcel/Classes/PHPExcel/Shared (it's not the best way but it worked for me).
来源:https://stackoverflow.com/questions/26265108/phpexcel-force-download-issue