You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP无需下载读取在线Excel及cURL下载xlsx异常解决方案咨询

问题解决方案

一、修复cURL下载文件损坏的问题

你当前代码的核心错误如下:

  • 错误使用CURLOPT_HEADER参数:该参数接收布尔值,用于控制是否将响应头写入输出流,自定义请求头需要使用CURLOPT_HTTPHEADER参数。
  • 手动添加了HTTP/2伪头::authority、:method、:path、:scheme这类冒号开头的头是cURL发起HTTP/2请求时自动生成的,手动添加会导致请求格式错误。
  • 未开启自动解压缩:你设置了accept-encoding支持压缩格式,但没有配置cURL自动解码,返回的压缩内容直接保存会导致文件损坏。
  • 固定写死Cookie:代码中的__cf_bm是Cloudflare的反爬Cookie,有效期仅有几分钟,固定写死很快就会失效,请求会被拦截。

修正后的cURL下载代码如下:

function dfCurl($url, $saveToFile = true, $savePath = '../'){
    $ch = curl_init($url);
    
    // 先请求一次referer页面获取最新Cookie,避免反爬拦截
    curl_setopt($ch, CURLOPT_URL, 'https://www.idx.co.id/perusahaan-tercatat/laporan-keuangan-dan-tahunan/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_COOKIEJAR, tmpfile()); // 临时存储Cookie
    curl_exec($ch);

    // 再请求目标文件
    curl_setopt($ch, CURLOPT_URL, $url);
    $headers = [
        'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'accept-language: en-AU,en;q=0.9,id-ID;q=0.8,id;q=0.7,zh-CN;q=0.6,zh;q=0.5,ja-JP;q=0.4,ja;q=0.3,en-GB;q=0.2,en-US;q=0.1',
        'cache-control: no-cache',
        'pragma: no-cache',
        'referer: https://www.idx.co.id/perusahaan-tercatat/laporan-keuangan-dan-tahunan/',
        'sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"',
        'sec-ch-ua-mobile: ?1',
        'sec-ch-ua-platform: "Android"',
        'sec-fetch-dest: document',
        'sec-fetch-mode: navigate',
        'sec-fetch-site: same-origin',
        'sec-fetch-user: ?1',
        'upgrade-insecure-requests: 1',
        'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Mobile Safari/537.36'
    ];
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_ENCODING, ''); // 自动解码所有支持的压缩格式
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    if($saveToFile){
        $fileName = basename($url);
        $saveFilePath = $savePath . $fileName;
        $fp = fopen($saveFilePath, 'wb');
        curl_setopt($ch, CURLOPT_FILE, $fp);
        $result = curl_exec($ch);
        fclose($fp);
    }else{
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
    }

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $httpCode == 200 ? $result : false;
}

二、无需下载到本地直接读取Excel内容

使用PHPSpreadsheet可以直接读取内存中的Excel内容,无需写入本地磁盘,实现方案如下:

  1. 用cURL获取到Excel文件的二进制内容
  2. 将内容写入内存流,直接传给PHPSpreadsheet加载
  3. 读取指定工作表的全量数据

示例代码:

require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;

public function readRemoteExcel() {
    $url = 'https://www.idx.co.id/Portals/0/StaticData/ListedCompanies/Corporate_Actions/New_Info_JSX/Jenis_Informasi/01_Laporan_Keuangan/02_Soft_Copy_Laporan_Keuangan//Laporan%20Keuangan%20Tahun%202021/TW1/AALI/FinancialStatement-2021-I-AALI.xlsx';
    // 获取文件二进制内容,不保存到本地
    $fileContent = dfCurl($url, false);
    if(!$fileContent){
        die('文件获取失败');
    }

    // 从内存流加载Excel
    $spreadsheet = IOFactory::load('data://application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' . base64_encode($fileContent));
    // 读取第一个工作表
    $worksheet = $spreadsheet->getActiveSheet();
    // 获取全量行列数据
    $data = $worksheet->toArray();

    // 后续处理$data即可
    print_r($data);
}

注:如果目标站点反爬策略升级,普通cURL请求被拦截,可以使用Guzzle配合中间件,或者使用无头浏览器获取文件内容。

内容的提问来源于stack exchange,提问作者Dennis Liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:09:00