下载时PHP生成的Excel文件不同

Posted

技术标签:

【中文标题】下载时PHP生成的Excel文件不同【英文标题】:PHP generated Excel file is different when downloaded 【发布时间】:2011-04-11 21:15:42 【问题描述】:

我有一个 php 文件,它使用位于 http://pear.php.net/package/Spreadsheet_Excel_Writer/ 的模块生成 xls 文件

我可以很好地创建示例文档,当我打开它时,它看起来很好。

我的下一步是把它变成一个可下载的链接。为此,我这样做了:

    $mimeType = "application/vnd.ms-excel";
    $file_name = "test.xls";
    $file_path = "/tmp/".$file_name;
    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-Type: application/' . $mimeType);
    header('Content-Length: '.$size);
    header("Content-Disposition: attachment;filename=$file_name ");
    header("Content-Transfer-Encoding: binary ");

    // open the file in binary read-only mode
    // display the error messages if the file can´t be opened
    $file = & fopen($file_path, 'rb');

    if ($file) 
        // stream the file and exit the script when complete
        fpassthru($file);
        exit;

     else 
        echo $err;
    

但是,当我下载该文件时,它在 Excel 和 OpenOffice 中都包含大量垃圾数据。差异表示 /tmp 文件夹中的二进制文件和下载的文件彼此不同。我猜它与标头或 fpassthru 有关,但我在调试问题时运气不佳。

对问题所在有什么想法吗?

【问题讨论】:

如果您只是读取文件内容并将其传送到浏览器,我会使用 file_get_contents() 而不是 fpassthru。 readfile() 更好,因为它会流式传输文件,而不是将整个内容吞入内存。您可以使用 file_get_contents 轻松超过 PHP memory_limit 你得到解决方案了吗? 【参考方案1】:

多个 Content-Type 标头是不必要的。您实际上是在说文件同时是松饼、比萨饼和福特金牛座。您只需要 application/octet-stream 版本,除非您想提供确切的 mime 类型。

还有,您是否有任何理由试图将fopen() 返回的文件句柄转换为引用?

尝试一些更简单的东西:

<?php

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment;filename=$file_name");

readfile("/tmp/test.xls");

exit();
?>

看看会不会更好。

【讨论】:

我尝试用给定的代码替换我的代码,但仍然存在同样的问题。另外,我只是复制了将其作为参考传递的代码部分,因此我承认我不确定自己为什么要这样做。我尝试了使用和不使用&符号,它对输出没有影响。 您是否使用文本编辑器查看了文件内部的垃圾内容?可能是来自 PHP 的错误消息/警告,一个愚蠢的浏览器插件,等等......【参考方案2】:

请确保在发送实际文件内容之前不向浏览器发送任何内容。

Spreadsheet_Excel_Writer 正在生成的可能只是一些 php 的“错误”甚至是“通知”,而您甚至都看不到。或者它可能是一个结束的 '?>' 标记,后面跟着一个简单的空格或换行符。

在 Web 文件夹中生成的文件正常工作时,我遇到了类似的错误。但是使用 header('...') 的传递给了我损坏的文件。这是由于在一个 php 文件的末尾在结束 '?>' 标记之后有一个空格。

【讨论】:

【参考方案3】:

我使用的是同一个库,我刚刚发现库中的文件本身正在创建空白。

解决方案:在以下文件中删除文件末尾的空格,或删除末尾的?&gt;结束标记。

要编辑的文件(Spreadsheet_Excel_Writer package 中的所有文件):

Writer.php 
Workbook.php
Worksheet.php
PPS.php
Parser.php
OLE.php
Parser.php
File.php
BIFFWriter.php
Validator.php
Root.php

【讨论】:

【参考方案4】:

在生成excel文件的页面顶部添加如下代码

ob_clean();

这将清除所有乱码数据。同时检查任何 echo 语句。如果存在 echo 语句,请将其删除。数据应始终以 excel 包指定的格式呈现。

【讨论】:

以上是关于下载时PHP生成的Excel文件不同的主要内容,如果未能解决你的问题,请参考以下文章

PHP导出生成Excel文件

PHP 实时生成并下载超大数据量的 Excel 文件

PHP 使用 PHPExcel 库生成 Excel 文件

生成的 Excel 文件在不同系统中显示不同的日期值(Asp.net Web 应用程序)

php导出excel表后,打包成压缩包,然后下载到本地如何实现?

使用 Qt 浏览器下载 excel 文件作为附件