PHP強(qiáng)化之10 - CSV文件處理

一砚婆、生成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');
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市镊掖,隨后出現(xiàn)的幾起案子乃戈,更是在濱河造成了極大的恐慌,老刑警劉巖亩进,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件症虑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡归薛,警方通過查閱死者的電腦和手機(jī)谍憔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門匪蝙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人习贫,你說我怎么就攤上這事逛球。” “怎么了苫昌?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵颤绕,是天一觀的道長。 經(jīng)常有香客問我祟身,道長奥务,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任袜硫,我火速辦了婚禮氯葬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘婉陷。我一直安慰自己帚称,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布秽澳。 她就那樣靜靜地躺著闯睹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肝集。 梳的紋絲不亂的頭發(fā)上瞻坝,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天蛛壳,我揣著相機(jī)與錄音杏瞻,去河邊找鬼。 笑死衙荐,一個(gè)胖子當(dāng)著我的面吹牛捞挥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忧吟,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼砌函,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了溜族?” 一聲冷哼從身側(cè)響起讹俊,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煌抒,沒想到半個(gè)月后仍劈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寡壮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年贩疙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了讹弯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡这溅,死狀恐怖组民,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悲靴,我是刑警寧澤臭胜,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站癞尚,受9級(jí)特大地震影響庇楞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜否纬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一吕晌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧临燃,春花似錦睛驳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爪瓜,卻和暖如春蹬跃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铆铆。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蝶缀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人薄货。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓翁都,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谅猾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子柄慰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容