PHP中编程实现可下载的CSV文件
在PHP开发中,我们可以通过结合使用header()函数来改变在PHP程序中以fputcsv()函数输出的数据格式的内容类型(content type),可以实现将CSV文件发送给浏览器的功能。浏览器接收到CSV文件后会自动调用电子表格软件(或者其他与特定的客户端系统相关联的CSV文件编辑程序)对其进行处理。下面的PHP例子代码中将SQL SELECT查询的结果格式化为CSV数据,并提供了正确的响应头部,保证了发送给浏览器的数据文件能够得到适当的处理。
<?php
require_once 'DB.php';
// Connect to the database
$db = DB::connect('mysql://david:hax0r@localhost/phpcookbook');
// Retrieve data from the database
$sales_data = $db->getAll('SELECT region, start, end, amount FROM sales');
// Open filehandle for fputcsv()
$output = fopen('php://output','w') or die("Can't open php://output");
$total = 0;
// Tell browser to expect a CSV file
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="sales.csv"');
// Print header row
fputcsv($output,array('Region','Start Date','End Date','Amount'));
// Print each data row and increment $total
foreach ($sales_data as $sales_line) {
fputcsv($output, $sales_line);
$total += $sales_line[3];
}
// Print total row and close file handle
fputcsv($output,array('All Regions','--','--',$total));
fclose($output) or die("Can't close php://output");
?>上面的例子中为了保证浏览器能够正确地处理CSV输出设置了两个响应头部信息。第一个,Content-Type,用于告诉浏览器所输出的不是HTML格式,而是CSV格式。第二个为Content-Disposition,告诉浏览器不要直接显示所输出的CSV格式的数据,而是要尝试载人一个外部程序来处理这些数据。其中的filename属性,为浏览器下载的文件提供了一个默认的文件名。
如果想为同一数据提供不同的查看方式,可以在一个页面中组合使用格式化代码,并通过一个查询字符串变量来决定要生成何种格式。在下面的例子中,格式化查询字符串变量用于控制SQL SELECT查询的结果是作为一个HTML表格还是一个CSV文件返回。
<?php
$db = new PDO('sqlite:/usr/local/data/sales.db');
$query = $db->query('SELECT region, start, end, amount FROM sales', PDO::FETCH_NUM);
$sales_data = $db->fetchAll();
$total = 0;
$column_headers = array('Region','Start Date','End Date','Amount');
// Decide what format to use
$format = $_GET['format'] == 'csv' ? 'csv' : 'html';
// Print format-appropriate beginning
if ($format == 'csv') {
$output = fopen('php://output','w') or die("Can't open php://output");
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="sales.csv"');
fputcsv($output,$column_headers);
} else {
echo '<table><tr><th>';
echo implode('</th><th>', $column_headers);
echo '</th></tr>';
}
foreach ($sales_data as $sales_line) {
// Print format-appropriate line
if ($format == 'csv') {
fputcsv($output, $sales_line);
} else {
echo '<tr><td>' . implode('</td><td>', $sales_line) . '</td></tr>';
}
$total += $sales_line[3];
}
$total_line = array('All Regions','--','--',$total);
// Print format-appropriate footer
if ($format == 'csv') {
fputcsv($output,$total_line);
fclose($output) or die("Can't close php://output");
} else {
echo '<tr><td>' . implode('</td><td>', $total_line) . '</td></tr>';
echo '</table>';
}
?>如果在查询字符串中以format=csv来访问上例中的程序,会得到CSV格式的输出结果。而查询字符串中的任何其他格式的值都会得到HTML格式的输出结果。其中将format设置为CSV或者HTML的逻辑很容易扩展到其他输出格式,如XML等。如果你在很多地方都需要对相同数据提供多种格式的下载,可以将上例中的代码打包成一个函数,使其接受两个参数——第一个是要输出的数据数组,第二个是一个格式说明符,据此二者即可显示正确的结果。
至此,PHP中编程实现可下载的CSV文件就介绍完了。
转载请注明:http://www.itivy.com/php/archive/2012/2/18/php-csv.html
我也来参与讨论
你还可以输入600/600个字符
发表评论
回复 2012-2-19 1:03:39 by tester