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

Laravel foreach构建PDF内容 生产环境返回空白页问题

生产环境PDF生成空白页问题排查

问题场景

通过存储过程向PDF模板传递数据,使用foreach循环遍历返回的JSON数据构建PDF内部内容项,本地环境运行正常,可生成包含完整内容的PDF文件;部署到远程生产服务器后,生成的PDF为空白页。当前本地与生产环境的控制器代码、模板代码完全一致,存储过程返回的数据内容也完全一致。

控制器PHP代码

public function generarFichaPago(Request $request)
{
    $datosPDF = DB::select('exec SP_GenerarPDF @Op = ?, @matricula = ?, @ciclo = ?, @mes = ?', ['fichaPago', $request->matricula, $request->ciclo, $request->mes]);
    $pdf = PDF::loadView('Oficios.FichaPagoInsc', compact('datosPDF'))->setPaper('a4');
    $path = public_path('pdf/');
    $fileName =  time().'.'. 'pdf' ;
    $pdf->save($path . '/' . $fileName);
    $pdf = public_path('pdf/'.$fileName);
    return response()->download($pdf);
}

前端Ajax调用代码

function generarReferencia(mes) {
var ciclo = document.getElementById("ciclo").value;
var matricula = document.getElementById("matricula").value;
console.log(ciclo,matricula,mes);

$.ajax({ 
    type: 'GET', 
    url: '/pdf/fichaPago', 
    data: {
        "matricula": matricula,
        "ciclo": ciclo,
        "mes": mes,
    },
    xhrFields: { 
        responseType: 'blob' 
    }, 
    success: function(response){ 
        var blob = new Blob([response]); 
        var link = document.createElement('a'); 
        link.href = window.URL.createObjectURL(blob); 
        link.download = "Sample.pdf"; 
        link.click(); 
    }, 
    error: function(blob){ 
        console.log(blob); 
    } 
});

Blade PDF模板代码

<div class="container">
    @foreach ($datosPDF as $dato)
    <div id="n1" class="cell">
        {{-- <img src="{{ asset('images/logo_bbva.jpg') }}" width="105" height="105"> --}}
        Num. CIE: XXXXXXXXXXX
    </div>
    <div id="n2" class="cell">
        <ul style="list-style-type:none;">
            <li>Alumno: <strong>{{$dato->MATRICULA}} {{$dato->NOMBRE_P}}</strong></li>
            <li>Ciclo Escolar: <strong>{{$dato->CICLO}}</strong></li>
            <li>Nivel: <strong>{{$dato->SECCION}}</strong></li>
            <li>Grado: <strong>{{$dato->GRADO}}°</strong></li>
        </ul>
        <div id="leyenda">
            <strong style="color: blue">Pago Inscripción Ciclo {{$dato->CICLO}}</strong>
        </div>
    </div>
    <div id="n3" class="cell">
        <br>
        <ul style="list-style-type:none;">
            <li>Referencia: <strong>1234567890</strong></li>
            <li>Vigencia Al: <strong>{{$dato->FECHA_LIM}}</strong></li>
            <li>Importe: <strong>{{$dato->IMP_PAG}}</strong></li>
        </ul>
    </div>
    <div id="n4" class="cell">
        <p>___________ FIRMA</p>
    </div>
    @endforeach
</div>

排查方向与修复方案

  • 目录权限问题:优先检查生产环境public/pdf/目录的写入权限,权限不足时会生成空文件,给目录配置可写权限即可:执行chmod -R 755 项目实际路径/public/pdf后重试。
  • PHP依赖扩展缺失:确认生产环境PHP安装了PDF生成库必需的dom、gd、mbstring扩展,缺失任意一个都会导致渲染中断输出空白。执行php -m查看已安装扩展,缺失的扩展安装完成后重启php-fpm服务即可。
  • 返回字段名大小写不匹配:本地和生产环境的SQL Server驱动配置可能存在差异,部分驱动默认返回全小写字段名,和模板中写的大写属性(比如$dato->MATRICULA)不匹配,会导致foreach循环读不到变量、无内容输出。在控制器中把$datosPDF写入日志,确认实际返回的对象属性名,和模板中的写法对齐即可。
  • 输出缓冲区污染:如果项目代码在PDF输出前提前输出了BOM头、空行或者报错内容,会破坏PDF文件结构导致打开空白。在调用PDF::loadView前加一句ob_end_clean()清空所有提前输出的内容,再执行PDF生成逻辑即可。
  • 字体/特殊字符兼容问题:生产环境如果没有安装模板用到的字体,或者特殊字符(比如模板中的°符号、西语重音字符)无法被现有字体识别,也会导致内容渲染失败。可以先把模板里的特殊字符替换成普通英文字符测试,能正常生成的话,把对应字体文件放到PDF库的字体目录下加载即可。
  • 前端响应接收问题:先跳过Ajax,直接在浏览器访问控制器对应的路由,看能否直接下载正常的PDF。如果直接访问能拿到正常文件,说明是前端Ajax请求的响应被额外内容污染,检查生产环境是否有全局中间件给响应追加了调试内容、或者接口返回的报错信息混入了blob数据。

内容的提问来源于stack exchange,提问作者Claudio César Pérez Velasco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:42:25