一砚婆、生成CSV文件
1佃迄、主要函數(shù):
fputcsv—將行格式化為 CSV 并寫入文件指針
int fputcsv ( resource $handle , array $fields [, string $delimiter = ',' [, string $enclosure = '"' ]] )
1)函數(shù)說明:
fputcsv() 將一行(用 fields 數(shù)組傳遞)格式化為 CSV 格式并寫入由 handle 指定的文件茶行。
2)參數(shù):
- handle 文件指針必須是有效的沃呢,必須指向由fopen()或fsockopen()成功打開的文件(并還未由fclose()關(guān)閉)断序。
- fields 值的一個(gè)數(shù)組流纹。
- delimiter 可選的delimiter參數(shù)設(shè)定字段分界符(只允許一個(gè)字符)。
- enclosure 可選的enclosure參數(shù)設(shè)定字段字段環(huán)繞符(只允許一個(gè)字符)违诗。
3)返回值:
返回寫入字符串的長度漱凝, 或者在失敗時(shí)返回false。
2较雕、示例code:
//test data
$list = array (
array('name', 'data', 'number', 'price'),
array('iphone X', '2018/3/21', 123 ,8888),
array('imax pro', '2018/3/23',20,12000),
array('Letv', '2018/3/27',99,1100),
);
$fp = fopen('./file.csv', 'w') or die('Can\'t open file.');
// fwrite($fp,chr(0xEF).chr(0xBB).chr(0xBF)); //解決出現(xiàn)中文編碼的問題
foreach ($list as $fields) {
if (fputcsv($fp, $fields) === false) {
die('Can\'t write line.');
}
}
fclose($fp) or die('Can\'t close file.');
如下為生成的CSV文件:
3碉哑、問題:
1)中文編碼問題
//Windows下使用BOM來標(biāo)記文本文件的編碼方式
fwrite($fp,chr(0xEF).chr(0xBB).chr(0xBF));
二挚币、輸出CSV數(shù)據(jù)
要輸出CSV格式的數(shù)據(jù)而不是寫入文件亮蒋,可以使用特殊的輸出流php://output。
要把SCV格式的數(shù)據(jù)放入一個(gè)pb字符串妆毕,而不是輸出或?qū)懼烈粋€(gè)文件慎玖,可以結(jié)合輸出緩沖區(qū)使用,具體代碼如下:
$list = array (
array('name', 'data', 'number', 'price'),
array('iphone X', '2018/3/21', 123 ,8888),
array('imax pro', '2018/3/23',20,12000),
array('Letv', '2018/3/27',99,1100),
);
ob_start();
$fp = fopen('php://output','w') or die('Can\'t open php://output');
foreach ($list as $fields) {
if (fputcsv($fp, $fields) === false) {
die('Can\'t write CSV line.');
}
}
fclose($fp) or die('Can\'t close php://output');
$output = ob_get_contents();
ob_end_clean();
//echo $output;
三笛粘、解析CSV文件
1趁怔、主要函數(shù)
如果CSV數(shù)據(jù)在一個(gè)文件中(或可以通過一個(gè)URL得到),用fopen()打開文件薪前,并使用fgetcsv()讀入數(shù)據(jù)润努。
fgetcsv—從文件指針中讀入一行并解析 CSV 字段。
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = ',' [, string $enclosure = '"' [, string $escape = '\\' ]]]] )
1)函數(shù)說明:
和 fgets() 類似示括,只除了 fgetcsv() 解析讀入的行并找出 CSV 格式的字段然后返回一個(gè)包含這些字段的數(shù)組铺浇。
2)參數(shù):
- handle 一個(gè)由 fopen()、popen() 或 fsockopen() 產(chǎn)生的有效文件指針垛膝。
- length 必須大于 CVS 文件內(nèi)最長的一行鳍侣。在 PHP 5 中該參數(shù)是可選的。如果忽略(在 PHP 5.0.4 以后的版本中設(shè)為 0)該參數(shù)的話吼拥,那么長度就沒有限制倚聚,不過可能會(huì)影響執(zhí)行效率。
- delimiter 設(shè)置字段分界符(只允許一個(gè)字符)凿可。
- enclosure 設(shè)置字段環(huán)繞符(只允許一個(gè)字符)惑折。
- escape 設(shè)置轉(zhuǎn)義字符(只允許一個(gè)字符),默認(rèn)是一個(gè)反斜杠。
3)返回值:返回包含讀取字段的索引數(shù)組惨驶。
2矗积、示例代碼如下:
$fp = fopen('./file.csv','r') or die('Can\'t open file');
print '<table>';
while($csv_line = fgetcsv($fp)) {
print '<tr>';
for($i = 0, $j = count($csv_line); $i < $j; $i++){
print '<td>'.htmlentities($csv_line[$i]).'</td>';//將字符轉(zhuǎn)換為 HTML 轉(zhuǎn)義字符
}
print '</tr>';
}
print '</table>';
fclose($fp) or die('Can\'t close file');
3、注意
默認(rèn)地敞咧,fgetcsv()會(huì)讀入一整行數(shù)據(jù)棘捣。如果平均行長度超過8192字節(jié),還可以明確指定行的長度而不是讓PHP來確定休建,這樣一來乍恐,你的程序可以運(yùn)行得更快。為此要為fgetcsv()提供第二個(gè)參數(shù)测砂,這是比CSV文件中最大行長度更大的一個(gè)值(不要忘記統(tǒng)計(jì)行尾空白符)茵烈。如果傳入長度為0,PHP應(yīng)付采用默認(rèn)行為砌些。
可以向fgetcsv()傳入可選的第三個(gè)參數(shù)呜投,這個(gè)作為分隔符來取代逗號(hào)(,)。不過存璃,使用CSV的目的是為了很容易地交換表格數(shù)據(jù)仑荐,而使用一個(gè)不同的分隔符可能對(duì)此會(huì)有些影響。
不要試圖繞過fgetcsv()纵东,而只想讀入一行再使用explode()按逗號(hào)進(jìn)行解析粘招。CSV比這要復(fù)雜,它可以處理包含特殊符號(hào)的字段值偎球,如字段值中可能包含直接量逗號(hào)洒扎,不能把這些逗號(hào)看作是字段分隔符。使用fgetcsv()可以避免這樣一些微妙的錯(cuò)誤衰絮。
四袍冷、下載CSV文件
結(jié)合使用header()函數(shù)來改變php程序輸出的內(nèi)容類型,并使用fputcsv()函數(shù)完成數(shù)據(jù)格式轉(zhuǎn)化猫牡,從而可以將CSV文件發(fā)送到瀏覽器胡诗。
示例代碼如下:
$list = array (
array('name', 'data', 'number', 'price'),
array('iphone X', '2018/3/21', 123 ,8888),
array('imax pro', '2018/3/23',20,12000),
array('Letv', '2018/3/27',99,1100),
);
$fp = fopen('php://output','w') or die('Can\'t open php://output');
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="save.csv"');
foreach ($list as $fields) {
if (fputcsv($fp, $fields) === false) {
die('Can\'t write CSV line.');
}
}
fclose($fp) or die('Can\'t close php://output');