PHP導出Excel、CSV

字號+ 編輯: 种花家 修訂: 科学鼠辈 來源: 利志分享 2023-09-11 我要說兩句(0)

PHP導出大量數據應該使用ob_flush(),flush()來強制卸載舊的緩存。而其中CSV較各類Excel版本的好處就是在於沒有限制, 可以用CSV做導入導出的業務。

要點一:

對於導出大量數據不能使用Excel,會導致輸出數據不全。

Excel2003限制爲65536行就Excel2007限制爲1048576行

對於CSV目前對數據量沒有限制,所以大量數據導出選用。


要點二:

PHP處理大數據導出時,要強行刷出緩存在服務器和WEB瀏覽器中的緩存,避免爆内存。

使用的函數:ob_flush()  flush()同時使用才會奏效。


生成EXCEL的三張方法:

  1. excel:[\t \n]

  2. csv: [, \n]

  3. csv: [fputcsv] PHP函數

1.導出EXCEL:

主要使用聲明頭文档、輸出格式使用[\t \n]

//導出Excel:單元格'\t'分隔,換行\n
header("Content-type:application/vnd.ms-excel");
header("Content-Disposition:filename=excel.xls");
echo "A1\t B1\t C1\n";
echo "A2\t B2\t C2\n";
echo "A3\t B3\t c3\n";

2.導出CSV

主要使用聲明頭文档、輸出格式使用[ , \n]

//導出CSV:單元格','分隔,換行\n
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename=csv.csv');
header('Cache-Control: max-age=0');
echo "A1, B1, C1\n";
echo "A2, B2, C2\n";
echo "A3, B3, c3\n";

3.導出大量數據:

百萬以上的實現如下(注意不要一次獲取mysql大量數據,可以去ID再去生成CSV,在循環去庫中拿數據)fputcsv

set_time_limit(0);
error_reporting(0);
// 輸出Excel文档頭,可把user.csv換成你要的文档名
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="user.csv"');
header('Cache-Control: max-age=0');
$fp = fopen('/tmp/export/data.csv', 'a');
$head = array('UID', 'EMAIL', '注冊時間', '第一次登陸時間');
foreach ($head as $i => $v) {
    // CSV的Excel支持GBK編碼,一定要轉換,否則亂碼
    $head[$i] = iconv('utf-8', 'gbk', $v);
}
fputcsv($fp, $head);
$result = array(.................................);
foreach($resutl as $val){
    ob_flush();
    flush();
     // 從數據庫中獲取數據,爲了節省内存,不要把數據一次性讀到内存,從句柄中一行一行讀即可
    $sql = "SELECT uid,email,regdate,lastlogintime FROM reg_members WHERE email in ($val) ORDER BY uid ASC, regdate ASC";
    $query = $db_reg_read -> query($sql);
    while ($res = $db_reg_read -> fetch_array($query)) {
        $email = strtolower($res['email']);
        $list[] = $res;
    }
    //對數據進行整理
    //輸入到CSV中
    foreach($list as $key => $val){
        $row[0] = iconv('utf-8', 'gbk', $val['uid']);
        $row[1] = iconv('utf-8', 'gbk', $val['email']);
        $row[2] = iconv('utf-8', 'gbk', $val['regdate']);
        $row[3] = iconv('utf-8', 'gbk', $val['lastlogintime']);
        fputcsv($fp, $row);
    }
}

PHP導入導出csv文档的案例

以下列舉一些實際項目中的代碼來說明csv的導入導出:

導入Excel

/**
 * 導入目標數據
 * @param  string  $tmp_filename  臨時文档地址
 */
public function importTargetData()
{
    ignore_user_abort();
    @ini_set('max_execution_time', '300');
    try {
        $fileName   = $this->checkCsvFile();
        $common     = new Common();
        $totalLines = $common->getFileLineNumber($fileName);
        if ($totalLines < 2) {
            throw new \Exception('文档是空的');
        }
        if ($totalLines >= 10000) {
            throw new \Exception('行數太多,不能接受');
        }
        // 清理中間庫
        MmAchievementShop::onWriteConnection()->whereIn('availability', [0, 1, 2, 3])->delete();
        // 步長
        $num = 150;
        // 行數
        $s = 2;
        for ($i = 2; $i <= $totalLines; $i += $num) {
            // 完善字段
            $data    = [];
            $csvData = $common->getCsvLines($fileName, $i, $i + $num - 1);
            // 處理數據
            foreach ($csvData as $line => $v) {
                // 處理字段進行操作
                if (empty($v[0]) || empty($v[1]) || empty($v[2]) || empty($v[3])) {
                    if (empty($v[0]) && empty($v[1]) && empty($v[2]) && empty($v[3])) {
                        // 完全就是個空行
                        continue;
                    } else {
                        throw new \Exception('存在殘缺表數據[' . $s . ']');
                    }
                }
            }
            unset($csvData);
            $s++;
        }
        return true;
    } catch (\Exception $e) {
        return $e->getMessage();
    }
}

導出Excel

一個下載csv文档模板的程序例子


public function makeCsvTemplate()
{
    @ini_set('memory_limit', '400M');
    @ini_set('max_execution_time', '0');
    $filename = '目標與完成度' . date('YmdHis') . '.csv';
    header("Content-type:text/csv");
    header("Content-Disposition:attachment;filename=" . $filename);
    header('Cache-Control: max-age=0');
    $fp = fopen('php://output', 'a');
    // csv的列名
    $i          = 0;
    $contentArr = [];
    $headerList = Config('c2bData.targetColumnName');
    foreach ($headerList as $v) {
        $v = str_replace(array(
            "\r\n",
            "\r",
            "\n",
        ), '', $v);
        $contentArr[$i] = iconv('utf-8', 'gbk//IGNORE', $v);
        $i++;
    }
    fputcsv($fp, $contentArr);
    $contentList = [];
    // 查詢對象
    $contentList[] = $this->formatExportStr('全國');
    // 月份
    $contentList[] = $this->formatExportStr('2017#01');
    // 線索轉化率目標值
    $contentList[] = $this->formatExportStr('0.10%');
    // 門店-單車利潤目標值
    $contentList[] = $this->formatExportStr('2000');
    fputcsv($fp, $contentList);
    $currentDate = date('Ym', time());
    $sampleList = BiC2bTarget::whereIn('query_type', [2, 3, 4])
        ->where('date_month', $currentDate)
        ->orderBy('query_type', 'asc')
        ->lists('object_name')->toArray();
    $countOfList = count($sampleList);
    for ($i = 0; $i < $countOfList; ++$i) {
        $contentList = [];
        // 查詢對象
        $contentList[] = $this->formatExportStr($sampleList[$i]);
        // 月份
        $contentList[] = '';
        // 線索轉化率目標值
        $contentList[] = '';
        // 門店-單車利潤目標值
        $contentList[] = '';
        fputcsv($fp, $contentList);
    }
}

導出的例子

/**
 * 導出
 * 鬼知道數據庫裡都是什麽格式的數據,爲了防止導出亂碼,一律使用了formatExportStr進行轉碼
 */
public function exportAchievementData($request)
{
    @ini_set('memory_limit', '400M');
    @ini_set('max_execution_time', '0');
    $filename = '目標與完成度' . date('YmdHis') . '.csv';
    header("Content-type:text/csv");
    header("Content-Disposition:attachment;filename=" . $filename);
    header('Cache-Control: max-age=0');
    $fp = fopen('php://output', 'a');
    // csv的列名
    $i          = 0;
    $contentArr = [];
    $headerList = Config('c2bData.exportAchiList');
    foreach ($headerList as $v) {
        $v = str_replace(array(
            "\r\n",
            "\r",
            "\n",
        ), '', $v);
        $contentArr[$i] = iconv('utf-8', 'gbk//IGNORE', $v);
        $i++;
    }
    fputcsv($fp, $contentArr);
    unset($contentArr, $headerList);
    $objArr = $this->getDataBySearcher($request);
    foreach ($objArr as $v) {
        $contentList = [];
        // 查詢對象
        $contentList[]   = $this->formatExportStr($v['object_name']);
        $v['date_month'] = $this->formatMonthData((string) $v['date_month']);
        // 月份
        $contentList[] = $this->formatExportStr($v['date_month']);
        // 線索轉化率目標值
        $contentList[] = $this->formatExportStr($v['target_clue']);
        // 線索實際值
        $contentList[] = $this->formatExportStr($v['actual_clue']);
        // 線索完成度
        $contentList[] = $this->formatExportStr($v['complete_clue']);
        // 門店-單車利潤目標值
        $contentList[] = $this->formatExportStr($v['target_profit']);
        // 門店實際值
        $contentList[] = $this->formatExportStr($v['actual_profit']);
        // 門店完成度
        $contentList[] = $this->formatExportStr($v['complete_profit']);
        // 線索量(條)
        $contentList[] = $this->formatExportStr($v['clue']);
        // 計劃收購量
        $contentList[] = $this->formatExportStr($v['target_buy']);
        // 實際收購量
        $contentList[] = $this->formatExportStr($v['buy']);
        // 收購差異(台)
        $contentList[] = $this->formatExportStr($v['diff_buy']);
        fputcsv($fp, $contentList);
    }
}

過濾並轉碼的例子

/**
 * 過濾並轉碼導出至csv的數據
 * @param  string $str
 * @return string $str
 */
public function formatExportStr($str)
{
    if (!empty($str)) {
        $str = iconv('utf-8', 'gbk//IGNORE', str_replace(array(
            "\r\n",
            "\r",
            "\n",
        ), '', $str));
    }
    return $str;
}
閲完此文,您的感想如何?
  • 有用

    2

  • 沒用

    1

  • 開心

    1

  • 憤怒

    1

  • 可憐

    1

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • PHP的換行符是什麽

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯繫商家解決

我要說說
網上賓友點評