PHP 数组到 CSV

我正在尝试将一系列产品转换成 CSV 文件,但似乎并不打算这样做。CSV 文件是一长行,这是我的代码:

for($i=0;$i<count($prods);$i++) {
$sql = "SELECT * FROM products WHERE id = '".$prods[$i]."'";
$result = $mysqli->query($sql);
$info = $result->fetch_array();
}


$header = '';


for($i=0;$i<count($info);$i++)
{
$row = $info[$i];


$line = '';
for($b=0;$b<count($row);$b++)
{
$value = $row[$b];
if ( ( !isset( $value ) ) || ( $value == "" ) )
{
$value = "\t";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );


if ( $data == "" )
{
$data = "\n(0) Records Found!\n";
}


header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");


array_to_CSV($data);




function array_to_CSV($data)
{
$outstream = fopen("php://output", 'r+');
fputcsv($outstream, $data, ',', '"');
rewind($outstream);
$csv = fgets($outstream);
fclose($outstream);
return $csv;
}

此外,头部不强制下载。我已经复制和粘贴的输出和保存为.csv

剪辑

问题解决:

如果其他人也在寻找同样的东西,找到一个更好的方法:

$num = 0;
$sql = "SELECT id, name, description FROM products";
if($result = $mysqli->query($sql)) {
while($p = $result->fetch_array()) {
$prod[$num]['id']          = $p['id'];
$prod[$num]['name']        = $p['name'];
$prod[$num]['description'] = $p['description'];
$num++;
}
}
$output = fopen("php://output",'w') or die("Can't open php://output");
header("Content-Type:application/csv");
header("Content-Disposition:attachment;filename=pressurecsv.csv");
fputcsv($output, array('id','name','description'));
foreach($prod as $product) {
fputcsv($output, $product);
}
fclose($output) or die("Can't close php://output");
269513 次浏览

不要写出值,考虑使用 fputcsv()

这可以立即解决你的问题。

注释 : 我应该提到的是,这将在您的服务器上创建一个文件,所以您需要在输出文件之前读取该文件的内容,如果您不想保存一个副本,那么您需要在完成后使用 ùnlink‘ the file

尝试使用;

PHP_EOL

终止 CSV 输出中的每个新行。

我假设文本是划界的,但是没有移到下一行?

这是一个 PHP 常量。它将确定您需要的行的正确结尾。

例如,Windows 使用“ r n”。当我的输出没有突破到一个新的行时,我绞尽脑汁想了这个问题。

如何在 PHP 中编写统一的新行?

在我的例子中,我的数组是多维的,可能使用数组作为值。所以我创建了这个递归函数来彻底破坏数组:

function array2csv($array, &$title, &$data) {
foreach($array as $key => $value) {
if(is_array($value)) {
$title .= $key . ",";
$data .= "" . ",";
array2csv($value, $title, $data);
} else {
$title .= $key . ",";
$data .= '"' . $value . '",';
}
}
}

由于数组的各个级别不适合采用平面 CSV 格式,因此我创建了一个空列,其中包含子数组的键,作为下一级数据的描述性“介绍”。输出样本:

agentid     fname           lname      empid    totals  sales   leads   dish    dishnet top200_plus top120  latino  base_packages
G-adriana   ADRIANA EUGENIA PALOMO PAIZ 886                0    19              0         0         0         0      0

您可以很容易地删除“ intro”(描述性)列,但是在我的例子中,每个子数组中都有重复的列标题,即入站 _ lead,因此在下一节之前给了我一个 break/title。删除:

$title .= $key . ",";
$data .= "" . ",";

在 is _ array ()之后,进一步压缩代码并删除额外的列。

因为我既需要标题行也需要数据行,所以我将两个变量传递给函数,在完成对函数的调用后,用 PHP _ EOL 结束这两个变量:

$title .= PHP_EOL;
$data .= PHP_EOL;

是的,我知道我多留了一个逗号,但是为了简洁起见,我没有在这里处理它。

我知道这是旧的,我有一个情况下,我需要的数组关键字包含在 CSV 也,所以我更新了由 Jesse Q 脚本这样做。 我使用一个字符串作为输出,因为内爆不能添加新行(新行是我添加的东西,应该真的在那里)。

请注意,这只适用于单值数组 (key, value)。但可以很容易地更新,以处理多维 (key, array())

function arrayToCsv( array &$fields, $delimiter = ',', $enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');


$output = '';
foreach ( $fields as $key => $field ) {
if ($field === null && $nullToMysqlNull) {
$output = '';
continue;
}


// Enclose fields containing $delimiter, $enclosure or whitespace
if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
$output .= $key;
$output .= $delimiter;
$output .= $enclosure . str_replace($enclosure, $enclosure . $enclosure,     $field) . $enclosure;
$output .= PHP_EOL;
}
else {
$output .= $key;
$output .= $delimiter;
$output .= $field;
$output .= PHP_EOL;
}
}


return  $output ;
}

数组数据被转换成 csv‘ text/csv’格式,这是通过内置的 php 函数 fputcsv 处理逗号、引号等等。.
你看
Https://coderwall.com/p/zvzwwa/array-to-comma-separated-string-in-php
Http://www.php.net/manual/en/function.fputcsv.php

这是一个将数组导出到 csv 字符串的简单解决方案:

function array2csv($data, $delimiter = ',', $enclosure = '"', $escape_char = "\\")
{
$f = fopen('php://memory', 'r+');
foreach ($data as $item) {
fputcsv($f, $item, $delimiter, $enclosure, $escape_char);
}
rewind($f);
return stream_get_contents($f);
}


$list = array (
array('aaa', 'bbb', 'ccc', 'dddd'),
array('123', '456', '789'),
array('"aaa"', '"bbb"')
);
var_dump(array2csv($list));

参考文献

这招对我很管用。

 $f=fopen('php://memory','w');
$header=array("asdf ","asdf","asd","Calasdflee","Start Time","End Time" );
fputcsv($f,$header);
fputcsv($f,$header);
fputcsv($f,$header);
fseek($f,0);
header('content-type:text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '";');
fpassthru($f);```

从数组创建 csv 文件最简单的方法是使用 implode ()函数:

<?php
$arr = array('A','B','C','D');
echo implode(",",$arr);
?>

上述代码的输出结果如下: A B C D

我使用这个简单的函数将每个数组条目创建为 csv:

function arrayToCsv($fields, $delimiter = ",", $enclosure = "\"", $escapeChar = "\"")
{
$fp  = fopen('php://temp', 'r+');
fputcsv($fp, $fields, $delimiter, $enclosure, $escapeChar);
rewind($fp);
$ret = fgets($fp);
fclose($fp);
return $ret;
}

您可以尝试下面的代码使用 Fputcsv从数组导出 csv

ob_start();
$outputCsv = fopen('php://output', 'w');
fputcsv($outputCsv, ['column 1', 'column 2' 'column 3'], ",");
fputcsv($outputCsv, ['','',''], ",");


fputcsv($outputCsv, ['value 1', 'value 2' 'value 3'], ",");
fputcsv($outputCsv, ['value 11', 'value 21' 'value 31'], ",");
fputcsv($outputCsv, ['value 12', 'value 22' 'value 31'], ",");


header('Cache-Control: max-age=0');
header("Expires: 0");
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-type: application/csv');
header('Content-Disposition: attachment;filename="doc_logs.csv"');
header("Content-Transfer-Encoding: binary");
fpassthru($outputCsv);
fclose($outputCsv);