首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 文件下載強制添加 BOM 頭解決 CSV/Excel 亂碼問題

     編輯:PHP 相關知識

在中文環境下導出 CSV/Excel 文件時,若無 BOM(Byte Order Mark)頭,Excel 會默認按系統編碼(如 GBK)解讀,導致 UTF-8 內容顯示亂碼。本文詳細說明 BOM 原理與 PHP 添加方案。

什麼是 BOM 頭?

BOM(Byte Order Mark)是文件開頭的 3 個隱藏字節:EF BB BF(十六進制),對應 UTF-8 編碼標記。Windows 記事本另存為 UTF-8 時會自動添加。系統識別到 BOM 即判定文件為 UTF-8 編碼。

核心解決方案

<?php
// 文件名
$filename = "file.csv";

// 設置下載 Header
header('Expires: ' . gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + 10) . ' GMT');
header('Cache-Control: max-age=10');
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename={$filename}");

// 關鍵:輸出內容前先發送 BOM 頭
$out = "\xEF\xBB\xBF"; // UTF-8 BOM

// 若有提示信息放第一行
if (!empty($extra['notice'])) {
    $out .= "{$extra['notice']}\r\n";
}

// 輸出數據行(示例:$table 為二維數組)
foreach ($table as $row) {
    $out .= implode(",", $row) . "\r\n";
}

// 直接輸出
echo $out;
?>

完整下載腳本示例(含緩存控制)

<?php
$file = '/path/to/export.csv';

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . urlencode(basename($file)));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));

ob_clean();
flush();

// 發送 BOM + 文件內容
echo "\xEF\xBB\xBF";
readfile($file);
exit;
?>

關鍵點總結

  1. BOM 必須在最前面輸出,任何空白字符、HTML、echo 都會導致 BOM 失效
  2. 使用雙引號十六進制轉義:"\xEF\xBB\xBF" 或 chr(239).chr(187).chr(191)
  3. Content-Type 建議:text/csv; charset=utf-8 比 application/vnd.ms-excel 更標準
  4. 中文文件名:必須用 urlencode() 編碼,否則 IE/Edge 下載亂碼
  5. 大文件優化:避免變量拼接全量內存,改用 readfile() 或分塊輸出

適用場景對比

場景是否需要 BOM說明
Excel 打開 CSV✅ 必須Excel 默認不識別無 BOM 的 UTF-8
文本編輯器打開❌ 可選現代編輯器自動檢測編碼
程序解析導入❌ 建議無多數解析庫不處理 BOM,反而干擾
數據庫 LOAD DATA❌ 禁止會導入 BOM 字符造成髒數據

掌握 BOM 添加技巧,能徹底解決「導出文件在 Excel 打開亂碼」這一經典痛點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved