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

PHP Spreadsheet生成Excel无法保存及下载问题求助

PHP Spreadsheet导出Excel失败的问题排查与修复

核心问题分析

1. 文件保存时机错误

你在创建完表头后就执行了第一次$Writer->save(),此时单元格样式设置、数据填充都还未完成,导致第一次保存的文件为空或不完整。后续修改不会同步到已保存的文件,第二次save()虽在最后,但整体流程逻辑混乱。

2. 输出内容破坏HTTP头部

循环填充数据时执行的echo $Ecritures;会将数组转为字符串输出到浏览器,导致后续header()无法正常生效(HTTP头部必须在任何输出前发送),最终下载请求失败。

3. 下载逻辑错误

原下载按钮直接指向静态文件路径,但该文件是在处理函数执行时才生成的,点击按钮时文件可能还不存在;同时目录权限不足也会导致无法访问已生成的文件。此外,PHP Spreadsheet支持直接将文件输出到浏览器,无需先保存到服务器。

4. 目录权限隐患

./inc/fin/test/目录需确保服务器进程(如www-data)有写入权限,否则save()方法会因权限不足抛出错误。

修复后的代码实现

处理函数修正

function download() {
    // 开启输出缓冲区,避免意外输出破坏头部
    ob_start();

    $Ecritures = get_ListeEcrituresCegid($_POST['soct'], $_POST['datd'], $_POST['datf']);
    $NomFichier = $_POST['soct'] . date('Y-m-d') . '.xlsx';

    $Classeur = new Spreadsheet();
    $Classeur->getDefaultStyle()->getFont()->setName('Arial Nova');
    $Classeur->getDefaultStyle()->getFont()->setSize(9);
    $Feuille = $Classeur->getActiveSheet();

    // 设置表头
    $Feuille->setCellValue('A1', 'EXERCICE');
    $Feuille->setCellValue('B1', 'JOURNAL');
    $Feuille->setCellValue('C1', 'PIECE');
    $Feuille->setCellValue('D1', 'COMPTE CLIENT');

    // 设置表头样式
    $cellColors = [
        'A1' => 'd4e6f1', 'B1' => 'd4e6f1', 'C1' => 'd4e6f1', 'D1' => 'd4e6f1',
    ];
    foreach ($cellColors as $cell => $color) {
        $Feuille->getStyle($cell)->getFill()->setFillType(Fill::FILL_SOLID);
        $Feuille->getStyle($cell)->getFill()->getStartColor()->setRGB($color);
    }

    // 填充数据
    $rowIndex = 2;
    foreach ($Ecritures as $e) {
        $Feuille->setCellValue('A' . $rowIndex, $e['E_EXERCICE']);
        $Feuille->setCellValue('B' . $rowIndex, $e['E_JOURNAL']);
        $Feuille->setCellValue('C' . $rowIndex, $e['E_DEBIT']);
        $Feuille->setCellValue('D' . $rowIndex, $e['E_COMPTECLI']);
        $rowIndex++;
    }

    // 设置HTTP下载头部
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment; filename="' . $NomFichier . '"');
    header('Cache-Control: max-age=0');

    // 直接输出到浏览器,无需保存到服务器
    $Writer = new Xlsx($Classeur);
    $Writer->save('php://output');

    // 清理缓冲区并终止脚本,避免后续输出干扰
    ob_end_flush();
    exit;
}

下载按钮修正

将静态a标签改为表单提交(确保POST参数能正确传递到处理函数):

<td style='border:1px solid grey; border-top:0; border-bottom:0; border-left:0; border-right:0;' align='center' colspan='1'>
    <form method="post" action="你的处理页面.php">
        <input type="hidden" name="soct" value="<?php echo $_POST['soct']; ?>">
        <input type="hidden" name="datd" value="<?php echo $_POST['datd']; ?>">
        <input type="hidden" name="datf" value="<?php echo $_POST['datf']; ?>">
        <button type="submit" name="action" value="download" style="border:none; background:none; padding:0;">
            <img src='./img/excel.png' height='30' alt='Télécharger' />
        </button>
    </form>
</td>

额外注意事项

  • 确保引入PHP Spreadsheet的样式类,否则样式设置会报错:
    use PhpOffice\PhpSpreadsheet\Style\Fill;
    
  • 若仍需将文件保存到服务器,检查./inc/fin/test/目录权限,设置为755或775(根据服务器配置调整)。
  • 处理函数需在页面最顶部调用,确保没有任何HTML输出在函数执行之前。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:15:02