10

我创建了一个 CSV 文件供我们的客户使用

$output = fopen('php://output', 'w');

fputcsv()用于将数据写入客户端下载的 CSV 文件。

我在 Linux 上运行 PHP,因此许多 Windows 应用程序不会解释行尾。

我可以将 CSV 文件写入服务器上的目录,将其读回并执行str_replace()from \nto \r\n,但这似乎是解决问题的一种相当笨拙的方法。有没有办法在不创建物理文件的情况下执行转换?

4

5 回答 5

23

您可以使用流过滤器来完成此操作。此示例写入物理文件,但它也应该可以正常工作php://output

// filter class that applies CRLF line endings
class crlf_filter extends php_user_filter
{
    function filter($in, $out, &$consumed, $closing)
    {
        while ($bucket = stream_bucket_make_writeable($in)) {
            // make sure the line endings aren't already CRLF
            $bucket->data = preg_replace("/(?<!\r)\n/", "\r\n", $bucket->data);
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}
// register the filter
stream_filter_register('crlf', 'crlf_filter');

$f = fopen('test.csv', 'wt');
// attach filter to output file
stream_filter_append($f, 'crlf');
// start writing
fputcsv($f, array('1 1', '2 2'));
fclose($f);
于 2012-10-04T08:52:40.800 回答
2

不确定您是否可以使用 PHP 本身执行此操作。可能有一种方法可以更改 PHP 的文件写入 EOL,但这可能取决于系统。您没有可以 ping 通的 Windows 系统,是吗?;)

至于一个真正的解决方案,而不是str_replace逐行,你可以使用 Linux 程序unix2dos(逆dos2unix)假设你已经安装了它:

fputcsv($fh ...)
exec("unix2dos " . escapeshellarg($filename));
于 2012-10-04T08:41:03.310 回答
1
  1. 在 Linux 机器上创建带有 \n 行尾的文件
  2. 将文件作为 ASCII 从 Linux 机器 FTP 到 Windows 机器
  3. 嘿,快!所有行结尾现在都在 Windows 机器上的文件中 \r\n
于 2013-06-18T22:56:30.593 回答
0

而不是写入文件,更好的解决方案是使用输出缓冲

function output($buffer) {
    return str_replace("\n", "\r\n", $buffer);
} 

ob_start('output');
fputcsv(....);
于 2014-05-13T12:17:28.150 回答
-1

如果在读取 Macintosh 计算机上或由 Macintosh 计算机创建的文件时 PHP 不能正确识别行尾,启用 auto_detect_line_endings 运行时配置选项可能有助于解决问题。ini_set("auto_detect_line_endings", true);

于 2019-03-26T12:53:53.903 回答