使用PHPExcel创建的Excel文件在打开时出现“Excel发现无法读取的内容”警告

18

我正在尝试使用PHPExcel下载Excel文件(xlsx)。

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');

代码可以正常工作,但在尝试打开Excel文件时,会在确认对话框中要求确认。

Excel 在 'test.xlsx' 中发现不可读内容。是否要恢复此工作簿的内容?如果信任此工作簿的来源,请单击“是”。

我还尝试将标题更改为以下内容

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");

它仍然要求相同的确认。我在这里做错了什么,请问?


3
在文本编辑器中打开文件,查看文件开头或结尾是否有任何空格字符,或者是否有任何明显的错误信息可见。 - Mark Baker
在文本编辑器(记事本)中,它会显示这样的内容 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å等大量内容。 - Tiny
1
你的内容类型头被最后一次调用简单地覆盖了,你能试试 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 吗?另外,我建议添加一个 "Content-length"(带有文档字节计数的头)[http://stackoverflow.com/a/10630871/61795],使用 strlen,这样可以避免下载问题。 - Scuzzy
6
最终成功了。我在 PHP 脚本的末尾添加了 exit(在问题的第一个代码片段的结尾处)。非常感谢你们所有人给我提供有用的提示。 - Tiny
2
@Tiny,你能把这个加到答案部分并标记为正确吗?以便于未来的人知道解决方法。 - Chris
显示剩余4条评论
7个回答

40

以下是用户Tiny在他自己的评论中提出的问题:

  

终于好了。我只是在我的 PHP 脚本的结尾处(即问题中第一段代码片段的结尾)添加了 "exit" 命令。非常感谢你们给我提供有用的提示。

以下是关于此类问题的一些有建设性的额外提示:

  • 一个好的提示是,您可以在所有的 PHP 脚本文件中省略关闭标签?>,这样你就知道你没有发送任何额外的不可见的空格。
  • 如果错误配置的 Web 服务器上编码 PHP 脚本文件为 UTF-8,则可能会在脚本开头发送几个不必要的字节。在 Notepad++ 中打开 PHP 文件,检查它是否是 UTF-8,在这种情况下,将其转换为 ANSI。如果这样可以使它正常工作,请检查您的 Web 服务器 / PHP 配置。
  • header 调用之前,您可以使用以下方法检查是否已经误发送了标头:

    if ( headers_sent() ) die("**错误:标头已发送");

  • 如果无法防止某些函数调用向浏览器发送不必要的字符串,则可以在脚本的开头使用以下语句“擦除”所有内容:

    ob_start();

    然后,在第一个 headers 调用之前,使用:

    ob_clean();

    请注意,这样做将阻止您接收错误反馈。

  • 最后,如前所述,如果在脚本的某一点之后没有需要执行的代码,请调用 exitdie


感谢您的进一步解释。 - Tiny
我也遇到了类似的问题。我正在使用PHP Pear电子表格编写器。我尝试了你的解决方案,但仍然出现相同的错误消息。还有其他建议或意见吗? - MANISH ZOPE

5

我曾经遇到过这个问题,我的解决方案是将头部的 Content-type 改为:

header('Content-Type: application/openxmlformats-officedocument.spreadsheetml.sheet');

我之前有:

header('Content-Type: application/vnd.ms-excel'); 

我将格式更改为Excel2007,之前使用的是Excel5,用于excel 2003 xls格式。

我尝试了这个页面和其他所有相同问题的页面上的所有解决方案,但都没有成功。 因此,基本上,我只是更改了我的Excel输出格式,这解决了问题。


4

1
我尝试了所有其他建议,添加Content-Length解决了我的问题。 - llanato

2

给活动工作表加一个标题:

$sheet->setTitle('Some title string here');

0

我只是在

PHPExcel_IOFactory::createWriter($phpExcelObject, 'Excel2007')->save("php://output");

后面加了 exit; 就可以了 :)

   $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;

0

这可能对那些尝试使用https://github.com/Maatwebsite/Laravel-Excel包在Laravel中通过get路由和ajax下载Excel的人有所帮助。

我得到了类似于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å等更多内容的响应。

我尝试了很多解决方案,但都失败了。

最终我通过在onclick事件中这样做来实现

$(document).on('click','#elementId',function(e){
  e.preventDefault();
  window.location.assign('your action url'+'?param='+ param_data);
}

0
我的 PHP 版本是:7.4.1,操作系统是:Ubuntu 18.04,框架是:Yii2.0.37
我之前也遇到过这个问题,我的解决方案是使用 exitob_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;`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接