Dompdf doesn’t appear to work when trying to stream a pdf

hi

dompdf doesn’t appear to work when trying to stream a pdf on the fly. the pdf file content is not correct.

trying to create a pdf to display/download (calling from dashboard for testing), code is in userfn.php

function _getSampleReport($campaignid) {
   $dompdf = new \Dompdf\Dompdf();

   $options = $dompdf->getOptions();    
   $options->set("isRemoteEnabled", true);    
   $options->set('defaultFont', 'Courier');
   $dompdf->setOptions($options);
   $dompdf->setPaper('A4', 'portrait');

   $ht = "hello world";
   $dompdf->loadHtml($ht);

   $dompdf->render();    
   $dompdf->stream("mypdf.pdf", array("Attachment" => true));
}

creates a document file with this content:

<!DOCTYPE html>
<html lang="en-US" data-bs-theme="light">
<head>
<title>DocuManage</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/css/select2.min.css?v=25.11.1">
<link rel="stylesheet" href="/css/select2-bootstrap5.min.css?v=25.11.1">
<link rel="stylesheet" href="/plugins/fontawesome-free/css/all.min.css?v=25.11.1">
<link rel="stylesheet" href="/adminlte3/css/adminlte.css?v=25.11.1">
<link rel="stylesheet" href="/css/docuManage.css?v=25.11.1">
<script data-pace-options='{"ajax":{"trackMethods":["GET","POST"],"ignoreURLs":["\/session?"]},"eventLag":false}' src="/js/pace.js?v=25.11.1"></script><!-- Single quotes for data-pace-options -->
<script src="/js/ewcore.js?v=25.11.1"></script>
<script>
var $rowindex$ = null;
Object.assign(ew, {"DEBUG":false,"SESSION_TIMEOUT_COUNTDOWN":120,"SESSION_KEEP_ALIVE_INTERVAL":0,"API_FILE_TOKEN_NAME":"filetoken","API_URL":"api\/","API_ACTION_NAME":"action","API_OBJECT_NAME":"table","API_LIST_ACTION":"list","API_VIEW_ACTION":"view","API_ADD_ACTION":"add","API_EDIT_ACTION":"edit","API_DELETE_ACTION":"delete","A

anyone able to create a pdf using the ->stream method?

saving the content to a file first for example using the output method:
$output = $dompdf->output();
file_put_contents(“mypdf.pdf”, $output);

renders the pdf correctly…

thanks,
JS

It depends on how you called your _getSampleReport(), make sure you call exit after calling it.

simple for testing I put at the end of my dashboard.php file as:

dashboard.php

<?php
    _getCampaignReport(5562);
    exit(0);
?>

in userfn.php:

function _getCampaignReport($campaignid) {

   $fileName = "./html/csr.html";
   $html = @file_get_contents($fileName);

   $dompdf = new \Dompdf\Dompdf();
   $options = $dompdf->getOptions();    

   $dompdf->setOptions($options);
   $dompdf->setPaper('A4', 'portrait');

   $dompdf->loadHtml($html);
   $dompdf->render();    
   
   $dompdf->stream("test.pdf", array("Attachment" => true));
}

where:
csr.html is a simple html formatted file. (some variables get replaced – code removed for clarity)
the same csr.html pdf’s fine when saved to disk using dompdf.

not sure what’s going astray.

Make sure the folder is allowed by the “chroot” option, see Resource Reference Requirements.

made some progress.
so looks like the problem is with prior html content being injected into the html content cause the file corruption.

added:

ob_clean();

before:

   $dompdf->loadHtml($html);
   $dompdf->setPaper('A4', 'portrait');
   $dompdf->render();    
   $dompdf->stream("campaign-summary.$campaignid.pdf", array("Attachment" => true));
   exit(0);

and the pdf file is streamed correctly!

but now putting the call where it has to go doesn’t fire the pdf creation..

report is in an options menu item.

calls this routine in userfn.js:

function ConfirmCampaignReport(sTitle, sDescription, sCampaignId) {   // confirmation 
    loadjs.ready("head", function() {                                       
       $.get(ew.getApiUrl("getCampaignReport") + '/' + sCampaignId)
    });          
}

which calls this in userfn.php

    $app->get('/getCampaignReport[/{params:.*}]', function ($request, $response, $args) {
        $fields = @explode('/', $args['params']);
        $result = _getCampaignReport($fields[0]);   
        $response = $response->write($result);
        return $response; // Return Psr\Http\Message\ResponseInterface object    
    }); 

which finally calls, this to generate the pdf:

function _getCampaignReport($campaignid) {
   $templateid = 0;
   $employeeid = 0;
   $documentid = _getCampaignInfo("campaign_program", $campaignid);
   $owner = CurrentUserID();
   $fileName = "./html/csr.html";
   $html = @file_get_contents($fileName);
   if($html == false) {
        return ("An error occurred attempting to generate the Campaign Summary Report. Template Corrupted.");
   }
   $html = ReplaceGenericTemplateVariables($html, $campaignid, $templateid, $employeeid, $owner, $documentid);
  
   $dompdf = new \Dompdf\Dompdf();
   $options = $dompdf->getOptions();    
   $options->set("isRemoteEnabled", true);    
   $options->set('isHtml5ParserEnabled', true);
   $options->set('defaultFont', 'Arial');
   $dompdf->setOptions($options);

   ob_end_clean();
   $dompdf->loadHtml($html);
   $dompdf->setPaper('A4', 'portrait');

   $dompdf->render();    
   $dompdf->stream("campaign-summary.$campaignid.pdf", array("Attachment" => true));
   exit(0);
}

it is executing to the very end, but nothing is streamed. no console errors…

but running the query from the network postings in the browser..

http://localhost/api/getCampaignReport/5562, the report is rendered…

You have already outputted as stream, so there is no $result, and you route action’s response is empty. You should use output() instead.

thanks, we did that as well with no success. I’ll have to find another solution for this.

output() method IS the solution. You may post your update code for discussion.