[英]Export CSV for Excel
I'm writing a CSV file in PHP using fputcsv($file, $data)
.我正在使用
fputcsv($file, $data)
在 PHP 中编写一个 CSV 文件。 It all works, however I can't just open it in Excel but have to import it and specify the encoding and which delimiter to use (in a wizard).一切正常,但是我不能只在 Excel 中打开它,而是必须导入它并指定编码和要使用的分隔符(在向导中)。 I've seen exports from other websites that open correctly just by clicking on them and now would like to know what I should do to my file to achieve that.
我已经看到其他网站的导出,只需单击它们即可正确打开,现在想知道我应该对我的文件做什么才能实现这一目标。
I tried using this library: http://code.google.com/p/parsecsv-for-php/ But I couldn't even get it to run and am not really confident if it would really help me...我尝试使用这个库: http : //code.google.com/p/parsecsv-for-php/但我什至无法让它运行,我也不确定它是否真的能帮助我......
This is how I make Excel readable CSV files from PHP :这就是我从 PHP 制作 Excel 可读 CSV 文件的方法:
For exemple :举个例子 :
$headers = array('Lastname :', 'Firstname :');
$rows = array(
array('Doe', 'John'),
array('Schlüter', 'Rudy'),
array('Alvarez', 'Niño')
);
// Create file and make it writable
$file = fopen('file.csv', 'w');
// Add BOM to fix UTF-8 in Excel
fputs($file, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));
// Headers
// Set ";" as delimiter
fputcsv($file, $headers, ";");
// Rows
// Set ";" as delimiter
foreach ($rows as $row) {
fputcsv($file, $row, ";");
}
// Close file
fclose($file);
// Send file to browser for download
$dest_file = 'file.csv';
$file_size = filesize($dest_file);
header("Content-Type: text/csv; charset=utf-8");
header("Content-disposition: attachment; filename=\"file.csv\"");
header("Content-Length: " . $file_size);
readfile($dest_file);
Works with Excel 2013.适用于 Excel 2013。
this is really a mess.这真是一团糟。 You surely can use the sep=;
你当然可以使用 sep=; or sep=, or sep=\\t or whatever to make Excel aware of a separator used in your CSV.
或 sep= 或 sep=\\t 或任何使 Excel 知道您的 CSV 中使用的分隔符的东西。 Just put this string at the beginning of your CSV contents.
只需将此字符串放在 CSV 内容的开头即可。 Eg:
例如:
fwrite($handle, "sep=,\n");
fputcsv($handle,$yourcsvcontent);
This works smoothly.这工作顺利。 BUT, it doesn't work in combination with a BOM which is required to make Excel aware of UTF-8 in case you need to support special characters or MB respectively.
但是,如果您需要分别支持特殊字符或 MB,它不能与使 Excel 知道 UTF-8 所需的 BOM 结合使用。
In the end to make it bullet-proof you need to read out users locale and set the Separator accordingly, as mentioned above.最后,要使其防弹,您需要读出用户区域设置并相应地设置分隔符,如上所述。 Put a BOM
("\\xEF\\xBB\\xBF")
at the begining of your CSV content, then write the CSV like eg: fputcsv($handle, $fields, $user_locale_seperator);
在 CSV 内容的
("\\xEF\\xBB\\xBF")
放置一个 BOM ("\\xEF\\xBB\\xBF")
,然后像这样编写 CSV: fputcsv($handle, $fields, $user_locale_seperator);
where $user_locale_seperator
is the separtator you retrieved by checking the user's locale.其中
$user_locale_seperator
是您通过检查用户的语言环境检索到的分隔符。 Not comfortable but it works...不舒服,但它有效......
Despite the "C=comma" in CVS, Excel uses your locale native separator.尽管 CVS 中有“C=逗号”,但 Excel 使用您的语言环境本机分隔符。 So supposing
fputcsv
always uses a comma, it won't work, if your locale separator is for example a semicolon.因此,假设
fputcsv
始终使用逗号,如果您的区域设置分隔符是分号,则它将不起作用。
What Google AdSense does, when you click "Export to Excel CSV" , is that it uses Tab as a separator.当您点击“导出到 Excel CSV”时,Google AdSense 的作用是使用Tab作为分隔符。 And that works.
这有效。
To replicate that, set the third parameter ( delimiter
) of fputcsv
to override the default comma.要复制它,请设置
fputcsv
的第三个参数 ( delimiter
) 以覆盖默认逗号。 Eg for Tab use: fputcsv($handle, $fields, "\\t");
例如对于Tab使用:
fputcsv($handle, $fields, "\\t");
Compare the format of the CSV that works for you against the one generated by fputcsv
.将适用于您的 CSV 格式与
fputcsv
生成的格式进行比较。
Consider including example of both in your question.考虑在您的问题中包含两者的示例。 You might get better answers.
你可能会得到更好的答案。
You may have an encoding issue.您可能有编码问题。
Try this post:试试这个帖子:
http://onwebdev.blogspot.com.es/2010/10/php-encoding-of-csv-file-for-excel.html http://onwebdev.blogspot.com.es/2010/10/php-encoding-of-csv-file-for-excel.html
I notice that you need to consider: Content-Type
header BOM (Byte Order Mark) Actual character encoding in the file我注意到你需要考虑:
Content-Type
header BOM (Byte Order Mark) 文件中的实际字符编码
With BOM (works):使用 BOM(作品):
$bom = pack("CCC", 0xEF, 0xBB, 0xBF);
header('Content-Type: text/csv');
header('Content-Length: '.(strlen($csv)+strlen($bom)));
header('Content-Disposition: attachment;filename=my.csv');
echo $bom;
echo $csv;
Without BOM (works but you need to replace “smart quotes” then run utf8_decode
on each value or cell, and it converts some characters, for example FRĒ is converted to FRE')没有 BOM(有效,但您需要替换“智能引号”,然后在每个值或单元格上运行
utf8_decode
,它会转换一些字符,例如 FRĒ 被转换为 FRE')
header('Content-Type: application/csv;charset=utf-8');
header('Content-Length: '.strlen($csv));
header('Content-Disposition: attachment;filename=my.csv');
echo $csv;
If the wrong combination of charset and BOM are used, it just comes out wrong when opening in MS Excel.如果使用了错误的字符集和 BOM 组合,在 MS Excel 中打开时就会出错。
Bonus fact: mb_strlen
tells you the number of characters, strlen
tells you the number of bytes.额外的事实:
mb_strlen
告诉您字符数, strlen
告诉您字节数。 You do NOT want to use mb_strlen
for calculating the Content-Length header.你不希望使用
mb_strlen
计算Content-Length头。
Bonus 2: replace microsoft "smart" characters (em dash, curly quotes, etc):奖励 2:替换微软的“智能”字符(破折号、卷曲引号等):
$map = array(chr(145) => "'"
,chr(146) => "'"
,chr(147) => '"'
,chr(148) => '"'
,chr(149) => '-'
,chr(150) => '-'
,chr(151) => '-'
,chr(152) => '-'
,chr(152) => '-'
,chr(171) => '-'
,chr(187) => '-'
);
// faster that strtr
return str_replace( array_keys($map), $map, $str );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.