【问题标题】:PHP/MYSQL to CSV Export code printing to screen instead of CSV filePHP/MYSQL 到 CSV 将代码打印导出到屏幕而不是 CSV 文件
【发布时间】:2014-01-28 01:42:25
【问题描述】:

我无法让浏览器提示下载。输出改为显示在屏幕上。我在这个网站上尝试了很多关于这个主题的其他主题,但无济于事。我可以将fopen("php://output","w") 更改为fopen("export.csv","w"),但这会在服务器上保存export.csv 文件的副本,这是我不想要的。我希望将文件下载到客户端而不将其保存在服务器上。这是我的代码:

$sql = mysql_query($_SESSION["export-query"]);
$fields = mysql_num_fields($sql);
$header = array();

for ($i = 0; $i < $fields; $i++) {
    $header[] = mysql_field_name($sql, $i);
}

$f = fopen("php://output","w"); 
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=export.csv');
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate');
fputcsv($f, $header);

while ($row = mysql_fetch_row($sql)) {
    fputcsv($f, $row);
}
fclose($f);

请帮忙!非常感谢。

【问题讨论】:

  • 我的代码和这个非常相似,那里没有带引号的字符串,它工作正常。
  • @spsc_tech 我也只是在检查我自己的一个有效的方法,发现它也没有被引用。
  • @spsc_tech - 你指的是哪个带引号的字符串?
  • 不确定这是否适用,但 AJAX 函数正在调用上述导出到 csv 代码,并且 AJAX 返回 (xmlHttp.responseText) 设置为显示在
    元素中。这会覆盖上面 php 代码中设置的标头吗?
  • 哦,是的,是的,这是你的问题。已发送的标头无法发送。

标签: php mysql csv export-to-csv


【解决方案1】:

你的代码和我的很接近,但我有这个

header("Content-type: application/vnd.ms-excel");

对于内容类型。我认为这是可行的,因为浏览器知道如何处理文本/csv,但他们不知道如何处理 excel。它会提示下载,因为它本身不会打开此类文件。

我也没有“必须重新验证”,但我认为这没有什么不同。

编辑:

这是我的完整标题,它们 100% 的时间都有效。与您的略有不同,所以也许其中之一就是原因。

    header("Content-type: application/vnd.ms-excel");
    header("Content-disposition: attachment; filename=".$filename.".csv");
    header("Pragma: no-cache");
    header("Expires: 0");

编辑 2:

从您对答案的评论来看,您将所有这些代码作为 ajax 调用放在 div 中。不起作用的原因是您只能在初始调用页面时设置标题。在 ajax 调用上设置标头将被忽略。

这是我的系统处理 csv 生成的方式。因为我需要不同 csv 文件之间可能不同的特定信息,所以我将生成器文件的名称放入表单的“操作”中并提供了一个提交按钮:

<form action="thegeneratorpage.php" method="get"><fieldset>
     <p>Download [...] in .csv (Excel) form.  You can narrow by [...].</p>
     <!-- code here that allows users to narrow down what is in the csv -->
     <input type="submit" value="Download" />
</fieldset></form>

如果信息没有变化,您可以这样做:

<a href="thegeneratorpage.php">Download CSV</a>

我们一直在讨论的所有代码都在thegeneratorpage.php

【讨论】:

  • 我添加了我的项目的所有标题,这些标题都可以满足您的需求。我也使用 fopen 和 fputcsv 等。
  • 我用你的标题试过了,但结果一样。它仍然只打印到屏幕上。
  • 我已经添加了更多关于如何做你想做的事情的信息。
  • 我将用于导出 csv 的代码分离到它自己的 php 文件 (export.php) 中,并创建了一个单独的 JavaScript 函数,它只调用 export.php。基本上是 window.location.assign("export.php")。它终于开始工作了!!!...除了在 IE 上。我回去将 export.php 中标题的顺序更改为: header('Pragma: '); header('缓存控制:'); header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename=export.csv'); header('过期时间:0'); ...现在它适用于所有浏览器!谢谢@spsc_tech
  • 我忘记了 javascript window.location 之一。我倾向于在不必要的时候避免使用 javascript(有太多客户使用旧电脑),而且我发布的两种解决方案都不会导致大多数浏览器的页面刷新。很高兴你的工作顺利进行。
【解决方案2】:

我建议不要使用 fputcsv 函数,而是像这样回显 CSV 文件的行(请注意,我使用的标题与您的略有不同):

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename={$fileName}");
header("Content-Transfer-Encoding: binary");
while ($row = mysql_fetch_row($sql)) {
    // optionally enclose data if necessary
    foreach ($row as $k => $v) {
        if (strpos($v, ',') !== false) {
            $row[$k] = '"' . $v . '"';
        }
    }
    echo implode(',', array_values($row));
}

【讨论】:

  • fputcsv 效果很好。我不建议使用您发布的代码的原因是因为 fputcsv 会自动转义并正确放置引号。如果$v 中有双引号,那么您的代码将会中断。
猜你喜欢
相关资源
最近更新 更多
热门标签