Jump to content

Download


Go to solution Solved by John Hebert Trindade,

Recommended Posts

Posted

Boa noite a todos, tenho um projeto em PHP com estrutura MVC que esta trabalhar, estou criando um documento do word através do php, nos browser (Chrome, Edge, firefox, opera) o download é feito naturalmente e o documento é criado. No safari diz que "Não foi possível criar o ficheiro" e o mesmo esta com o tamanho zero.
não sei se estou a colocar a duvida no local certo, e caso não esteja pesso imensa desculpa. mas se alguém conseguir ajudar me agradeço.
Por se tratar de um codigo muito extenso irei colocar apenas a parte que gera o documento, caso seja necessário adiciono o restante.
 

private function generateDocx(array $dados): void
{

    // Define o caminho base dinamicamente
    $basePath = $_SERVER['DOCUMENT_ROOT'] . '/app/adms/assets/';

    while (ob_get_level()) {
        ob_end_clean();
    }

    $nomeArquivo = 'cartaz_' . $this->id . '.docx';
    $pastaTmp = $_SERVER['DOCUMENT_ROOT'] . '/app/adms/assets/tmp/tmpWord/';
    $caminhoCompleto = $pastaTmp . $nomeArquivo;

    $phpWord = new PhpWord();

    // --- PRIMEIRA PÁGINA (MANTIDA ORIGINAL) ---
    $section = $phpWord->addSection([
        'marginLeft' => 720,
        'marginRight' => 720,
        'marginBottom' => 1440
    ]);

    $header = $section->addHeader();
    $moldura = $basePath . 'images/moldura.png';
    if (file_exists($moldura)) {
        $header->addImage($moldura, [
            'width' => 600, 'height' => 840,
            'positioning' => 'absolute',
            'posHorizontalRel' => 'page', 'posVerticalRel' => 'page',
            'wrappingStyle' => 'behind',
        ]);
    }

    $section->addTextBreak(3);
    $caminhoFoto = $basePath . 'images/funerais/' . $dados[0]['processo'] . '/' . $dados[0]['image'];

    if (file_exists($caminhoFoto)) {
        $img = imagecreatefromjpeg($caminhoFoto);
        $origW = imagesx($img);
        $origH = imagesy($img);

        $wFixo = 2448; $hFixo = 3264; $bordaGrossa = 60; $espaco = 20; $bordaFina = 12;
        $totalBorder = $bordaGrossa + $espaco + $bordaFina;
        $canvasW = $wFixo + ($totalBorder * 2);
        $canvasH = $hFixo + ($totalBorder * 2);

        $canvas = imagecreatetruecolor($canvasW, $canvasH);
        $ouroVelho = imagecolorallocate($canvas, 197, 160, 89);
        $fundo = imagecolorallocate($canvas, 255, 255, 255);

        imagefill($canvas, 0, 0, $ouroVelho);
        imagefilledrectangle($canvas, $bordaGrossa, $bordaGrossa, $canvasW - $bordaGrossa - 1, $canvasH - $bordaGrossa - 1, $fundo);
        $inicioFina = $bordaGrossa + $espaco;
        imagefilledrectangle($canvas, $inicioFina, $inicioFina, $canvasW - $inicioFina - 1, $canvasH - $inicioFina - 1, $ouroVelho);
        $offset = $totalBorder;
        imagecopyresampled($canvas, $img, $offset, $offset, 0, 0, $wFixo, $hFixo, $origW, $origH);

        $caminhoTemp = $pastaTmp . 'foto_final_' . $this->id . '.jpg';
        imagejpeg($canvas, $caminhoTemp);
        imagedestroy($canvas);
        imagedestroy($img);

        $section->addImage($caminhoTemp, ['width' => 140, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    }

    $section->addText(($dados[0]['name_genero'] == 'M' ? 'Ex.mo Sr. ' : 'Ex.ma Sra. D. ') . ($dados[0]['name_falecido'] ?? ''), ['name' => 'Baguet Script', 'size' => 14], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);

    $section->addTextBreak(2);
    $fontStyle = ['name' => 'Baguet Script', 'size' => 16];
    $paragraphStyle = ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::BOTH, 'indentation' => ['left' => 850, 'right' => 680], 'spaceAfter' => 200];
    $meses = ["janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"];

    $formatarData = function($dataRaw) use ($meses) {
        if (empty($dataRaw)) return "N/A";
        $d = explode('-', trim($dataRaw));
        return (count($d) == 3) ? (int)$d[2] . " de " . $meses[(int)$d[1]-1] . " de " . $d[0] : "N/A";
    };

    $section->addText('O Velório realizar-se-á na ' . ($dados[0]['name_local_saida'] ?? 'N/A'), $fontStyle, $paragraphStyle);
    $section->addTextBreak(2);
    $section->addText('Celebração dia ' . $formatarData($dados[0]['data_missa'] ?? '') . ' pelas ' . substr($dados[0]['hora_missa'] ?? 'N/A', 0, 5), $fontStyle, $paragraphStyle);
    $section->addTextBreak(2);
    $section->addText('Funeral dia ' . $formatarData($dados[0]['data_funeral'] ?? '') . ' pelas ' . substr($dados[0]['hora_funeral'] ?? 'N/A', 0, 5) . ', sendo ' . ($dados[0]['name_tipo_servico'] ?? 'N/A') . ' no ' . ($dados[0]['name_cemiterio'] ?? 'N/A'), $fontStyle, $paragraphStyle);

    $footer = $section->addFooter();
    $table = $footer->addTable(['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $table->addRow(1350);
    $table->addCell(200);
    $cellQr = $table->addCell(2500);
    $cellQr->addImage($basePath . 'images/qrgoogle.png', ['width' => 50, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $cellQr->addText('Avalia-nos no Google! Sua estrela faz a DIFERENÇA. Obrigado!', ['name' => 'Arial', 'size' => 7], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $table->addCell(550);
    $cellLogo = $table->addCell(2800);
    $cellLogo->addImage($basePath . 'images/logo/logo.png', ['width' => 110, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $table->addCell(2900);
    $table->addRow(300);

    // --- SEGUNDA PÁGINA ---
    $section2 = $phpWord->addSection([
        'breakType' => 'nextPage',
        'marginLeft' => 720,
        'marginRight' => 720,
        'marginBottom' => 1440
    ]);

    $section2->addText('Condolências', ['name' => 'Baguet Script', 'size' => 22, 'color' => 'C5A059', 'bold' => true], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $section2->addText(($dados[0]['name_genero'] == 'M' ? 'Ex.mo Sr. ' : 'Ex.ma Sra. D. ') . ($dados[0]['name_falecido'] ?? ''), ['name' => 'Baguet Script', 'size' => 14], ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $section2->addTextBreak(1);

    $table2 = $section2->addTable(['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $table2->addRow();

    $tStyle = ['name' => 'Baguet Script', 'size' => 14, 'bold' => true];
    $dStyle = ['name' => 'Baguet Script', 'size' => 10.5];

   // Célula 1: Velório
    $c1 = $table2->addCell(3000);
    $c1->addText("Velório", $tStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $dStyle = ['name' => 'Baguet Script', 'size' => 10.5];
    $c1->addText($formatarData($dados[0]['data_velorio'] ?? ''), $dStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $c1->addText(substr($dados[0]['hora_velorio'] ?? '', 0, 5) . " " . ($dados[0]['name_local_saida'] ?? ''), $dStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);

    // Célula 2: Celebração
    $c2 = $table2->addCell(3000);
    $c2->addText("Celebração", $tStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $c2->addText($formatarData($dados[0]['data_missa'] ?? ''), $dStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $c2->addText(substr($dados[0]['hora_missa'] ?? '', 0, 5), $dStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);

    // Célula 3: Funeral
    $c3 = $table2->addCell(3000);
    $c3->addText("Funeral", $tStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $c3->addText($formatarData($dados[0]['data_funeral'] ?? ''), $dStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $c3->addText(substr($dados[0]['hora_funeral'] ?? '', 0, 5) . " " . ($dados[0]['name_cemiterio'] ?? ''), $dStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);

    // --- 5 QUADROS COM ESPAÇAMENTO ---
    $section2->addTextBreak(1);
    $tableQuadros = $section2->addTable(['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $bordaEstilo = ['borderSize' => 6, 'borderColor' => 'C5A059'];
    $semBorda = ['borderStyle' => 'none', 'borderSize' => 0];

    for ($i = 0; $i < 5; $i++) {
        $tableQuadros->addRow(1300); // Quadro maior
        $tableQuadros->addCell(9000, $bordaEstilo);

        // Adiciona linha de espaçamento invisível se não for o último
        if ($i < 4) {
            $tableQuadros->addRow(450); // 0.8cm aproximadamente
            $tableQuadros->addCell(9000, $semBorda);
        }
    }

    // Rodapé da Segunda Página (duas linhas)
    $footer2 = $section2->addFooter();
    $tableF2 = $footer2->addTable(['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $tableF2->addRow();
    $tableF2->addCell(9000)->addImage($basePath . 'images/logo/logo.png', ['width' => 110, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
    $tableF2->addRow();
    $tableF2->addCell(9000);

    $objWriter = IOFactory::createWriter($phpWord, 'Word2007');
    $objWriter->save($caminhoCompleto);

   if (file_exists($caminhoCompleto)) {
        // Limpa qualquer buffer existente e desativa o output buffering para este download
        if (ob_get_level()) ob_end_clean();

        // Cabeçalhos essenciais para forçar o Safari a aceitar o fluxo
        header('Content-Description: File Transfer');
        header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
        header('Content-Disposition: attachment; filename="' . basename($caminhoCompleto) . '"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: no-cache, no-store, must-revalidate');
        header('Pragma: no-cache');
        header('Content-Length: ' . filesize($caminhoCompleto));

        // Envio em pedaços (ideal para evitar timeout ou erro de leitura do macOS)
        $handle = fopen($caminhoCompleto, 'rb');
        while (!feof($handle)) {
            echo fread($handle, 8192);
            flush(); // Força a descarga para o buffer do navegador
        }
        fclose($handle);

        exit;
    }
}

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.