spipu / html2pdf

OFFICIAL PROJECT | HTML to PDF converter written in PHP
http://html2pdf.fr/en/default
Open Software License 3.0
1.67k stars 745 forks source link

Cannot modify header information - headers already sent by .... #215

Closed polinevol closed 6 years ago

polinevol commented 7 years ago

Hi, I have this problem and don't know how to fix it Trying to generate a pdf file, I get this error code :

Warning: Cannot modify header information - headers already sent by (output started at C:\laragon\www\schola\reports\tbulletin_pdf.php:89) in C:.......\vendor\tecnickcom\tcpdf\tcpdf.php on line 7630

Fatal error: Uncaught Exception: TCPDF ERROR: Some data has already been output to browser, can't send PDF file in C:...\vendor\tecnickcom\tcpdf\tcpdf.php:2927 Stack trace: #0 C:...\vendor\tecnickcom\tcpdf\tcpdf.php(7632): TCPDF->Error('Some data has a...') #1 C:...\vendor\spipu\html2pdf\src\Html2Pdf.php(506): TCPDF->Output('bulletin.pdf', 'I') #2 C:....\tbulletin_pdf.php(154): Spipu\Html2Pdf\Html2Pdf->output('bulletin.pdf') #3 {main} thrown in C:...\vendor\tecnickcom\tcpdf\tcpdf.php on line 2927

Here is my php file

<?php
require_once dirname(__FILE__).'/vendor/autoload.php';
use Spipu\Html2Pdf\Html2Pdf;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use Spipu\Html2Pdf\Exception\ExceptionFormatter;

$bdd = new PDO('mysql:host=xxxxx;dbname=xxxxxxxx;charset=utf8', 'root', '');
$numbull = -1;
if(isset($_GET['numbulletin']))
{
    $numbull = $_GET['numbulletin'];
}
$sql_infos_eleve = "SELECT xxxxxxxxxxxxxx FROM vue_details_bulletins
    WHERE xxxxxxxxxxxxx'";
$reponse_infos_eleve = $bdd->query($sql_infos_eleve);
$row_infos_eleve = $reponse_infos_eleve->fetch();

$sql_infos_bull = "SELECT * From xxxxxxxxxxxxxxxxxxxx'";
$reponse_infos_bull = $bdd->query($sql_infos_bull);
//$row_infos_bull = $reponse_infos_bull->fetch();

$sql_infos_etab = "SELECT * From xxxxxxxxxxxxx";
$reponse_infos_etab = $bdd->query($sql_infos_etab);
$row_infos_etab = $reponse_infos_etab->fetch();
//ob_start();
?>
<link type="text/css" rel="stylesheet" href="bulletin.css">
<div><a href="javascript:demoFromHTML()" class="btn btn-info" role="button">Exporter en PDF </a></div>
<page>
    <div class="bulletin">
        <div class="page">
                <div id="idetab"><?php echo $row_infos_etab["denomination"];?></div>
                <div id="entete">
                    <div class="boite" id="adresse">
                        <div id="boitepostale"><?php echo $row_infos_etab["adresse"];?></div>
                        <div id="telephones">Fixe : <?php echo $row_infos_etab["telfix1"]; if(!$row_infos_etab["telfix2"]=="") { echo " / ". $row_infos_etab["telfix2"];}?></div>
                        <div id="telephones">Mobile : <?php echo $row_infos_etab["telmob1"]; if(!$row_infos_etab["telmob2"]==""){ echo " / ". $row_infos_etab["telmob2"];}?></div>
                        <div id="email">Site web. :<?php echo $row_infos_etab["siteweb"];?></div>
                        <div id="email">E-mail : <span style="font-weight:bold;"><?php echo $row_infos_etab["email"];?></span></div>
                    </div>
                    <div class="boite" id="logo">LOGO</div>
                    <div class="boite" id="enseignement"><?php echo $row_infos_eleve['annee_scolaire']; ?><br><?php echo$row_infos_eleve['niveau'] ;?></div>
                    <div class="boite" id="niveau"></div>               
                    <div id="numbull">Bulletin N° <span style="font-weight:bold;"><?php echo $row_infos_eleve['numbulletin'] ;?></span>  </div>
                </div>
                <div id="titre">
                 Bulletin de notes du 1er trimestre : Enseignement général
                </div>
            <div id="entete2">
                <div id="entete2left">
                        <div>Année scolaire : <span style="font-weight: bold;"><?php echo $row_infos_eleve['annee_scolaire'] ;?></span></div>
                        <div id="nomeleve"> Nom de l'élève : <span style="font-weight:bold;"><?php echo $row_infos_eleve['nom'].' '.$row_infos_eleve['prenom'];?></span></div>
                        <div id="datenaiss"> Né le : <span style="font-weight: bold;"><?php echo $row_infos_eleve['datenaiss'] ;?></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Matricule : <span style="font-weight: bold;"><?php echo $row_infos_eleve['matricule'] ;?></span></div>
                </div>
                <div id="entete2right">
                    <div id="nomeleve"> Classe de : <span style="font-weight: bold;"><?php echo $row_infos_eleve['classe'] ;?></span></div>
                    <div>Effectif : <span style="font-weight: bold;"><?php echo $row_infos_eleve['effectif'] ;?></span></div>                   
                    <div id="datenaiss"> Redoublant(e) : <span style="font-weight: bold;"><?php echo ($row_infos_eleve['redoublant'] == 'N') ?  'Non' : 'Oui' ;?></span></div>          
                </div>
            </div>
                <table>
                    <tr>
                      <th style="min-width:65mm;font-size:14px;text-align:center;">Matières</th>
                      <th style="max-width:15mm;font-size:14px;text-align:center;">Notes / 20</th>
                      <th style="max-width:10mm;text-align:center;text-align:center;font-size:14px;">Coef.</th>
                      <th style="min-width:1.8mm;text-align:center;font-size:14px;">Notes pondérées</th>
                      <th style="min-width:70mm;text-align:center;font-size:14px;">Observations des professeurs</th>
                    </tr>
                    <?php
                    while ($row_infos_bull = $reponse_infos_bull->fetch())              
                        {
                    ?>
                    <tr>
                      <td style="padding-left:5px;font-size:12px;"><?php echo $row_infos_bull["designation"];?></td>
                      <td style="font-size:12px;text-align:center;"><?php echo $row_infos_bull["moyenne"];?></td>
                      <td style="font-size:12px;text-align:center;"><?php echo $row_infos_bull["coef"];?></td>
                      <td style="font-size:12px;text-align:center;"><?php echo $row_infos_bull["noteponderee"];?></td>
                      <td>
                            <div style="padding-left:5px;font-size:12px;float:left;"><?php echo $row_infos_bull["appreciation"];?></div>
                            <div style="padding-right:5px;font-size:10px; font-style:italic; float:right;"><?php echo $row_infos_bull["npprof"];?></div>                      
                      </td>
                    </tr>                   
                    <?php
                        }
                    ?>
                    <tr> //ligne 89
                      <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">TOTAUX</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td colspan="1" rowspan="5" style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">MOYENNE SUR 20</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">RETRAIT DE POINTS</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">MOYENNE DEFINITIVE</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">Bilan    Technique</td>
                      <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">Bilan    g&eacute;n&eacute;ral</td>
                    </tr>
                    <tr>
                      <td style="padding-left:5px;font-size:12px;">Moyenne de l'&eacute;l&egrave;ve</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td colspan="1" rowspan="4" style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;">Rappel Moyennes</td>
                    </tr>
                    <tr>
                      <td style="padding-left:5px;font-size:12px;">Moyenne de la classe</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td colspan="1" rowspan="3" style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td style="padding-left:5px;font-size:12px;">Meilleure moyenne</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td style="padding-left:5px;font-size:12px;">Plus faible moyenne</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                    </tr>
                    <tr>
                      <td style="padding-left:5px;font-size:12px;">Moyenne annuelle</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                      <td style="padding-left:5px;font-size:12px;">Rang annuel</td>
                      <td style="padding-left:5px;font-size:12px;"></td>
                    </tr>
            </table>                
        </div>
    </div>
</page>
<?php
    try {
        $content = ob_get_clean();
        $html2pdf = new Html2Pdf('P', 'A4', 'fr',true, "UTF-8");
        $html2pdf->setDefaultFont('Arial');
        $html2pdf->writeHTML($content);  //ligne 153
        $html2pdf->output('bulletin.pdf');  
        } 
    catch (Html2PdfException $e) 
        {
    $formatter = new ExceptionFormatter($e);
    echo $formatter->getHtmlMessage();
        }

Can someone help me ?

LittleBigFox commented 7 years ago

Hi!

Don't you need to uncomment ob_start first?

Otherwise, you can put directly the html in a PHP string, instead of using OB...

Regards, LBF

polinevol commented 7 years ago

Ok I've got it uncommented (my ob_start), but still the same error... It says that the output start à ligne 89, just after looping to create my table rows...??? How to put all my html in a PHP string...no idea... Thanks !

polinevol commented 7 years ago

I have a css file for ma page... Where can I add it to be consider during pdf generation ?

LittleBigFox commented 7 years ago

Something like that?

Just put your css file in a string with php and put it in a STYLE tag for use with Html2PDF ...

You can not display the webpage and your PDF in your browser at the same time, but you can save it to your HD and open it by clicking on a link if you want ...

It is not recommended to mix html with PHP neither, OB is clean but it's easier to concatenate string...

require_once dirname(__FILE__).'/vendor/autoload.php';
use Spipu\Html2Pdf\Html2Pdf;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use Spipu\Html2Pdf\Exception\ExceptionFormatter;

$bdd = new PDO('mysql:host=xxxxx;dbname=xxxxxxxx;charset=utf8', 'root', '');
$numbull = -1;
if(isset($_GET['numbulletin']))
{
    $numbull = $_GET['numbulletin'];
}
$sql_infos_eleve = "SELECT xxxxxxxxxxxxxx FROM vue_details_bulletins WHERE xxxxxxxxxxxxx'";
$reponse_infos_eleve = $bdd->query($sql_infos_eleve);
$row_infos_eleve = $reponse_infos_eleve->fetch();

$sql_infos_bull = "SELECT * From xxxxxxxxxxxxxxxxxxxx'";
$reponse_infos_bull = $bdd->query($sql_infos_bull);
//$row_infos_bull = $reponse_infos_bull->fetch();

$sql_infos_etab = "SELECT * From xxxxxxxxxxxxx";
$reponse_infos_etab = $bdd->query($sql_infos_etab);
$row_infos_etab = $reponse_infos_etab->fetch();

// Content
$content  = '<style type="text/css">'.file_get_contents("path/to/bulletin.css").'</style>';
$content .= '<page>';
$content .= '<div class="bulletin">';
$content .= '<div class="page">';
$content .= '<div id="idetab">'.$row_infos_etab["denomination"].'</div>';
$content .= '<div id="entete">';
$content .= '   <div class="boite" id="adresse">';
$content .= '       <div id="boitepostale">'.$row_infos_etab["adresse"].'</div>';

$content .= '       <div id="telephones">Fixe :'.$row_infos_etab["telfix1"];
if(!$row_infos_etab["telfix2"]=="") { $content .= " / ". $row_infos_etab["telfix2"];}

$content .= '   </div>'
$content .= '   <div id="telephones">Mobile :'.$row_infos_etab["telmob1"];
if(!$row_infos_etab["telmob2"]==""){ $content .= " / ". $row_infos_etab["telmob2"];}

$content .= '   </div>';
$content .= '   <div id="email">Site web. :'.$row_infos_etab["siteweb"].'</div>';
$content .= '   <div id="email">E-mail : <span style="font-weight:bold;">'.$row_infos_etab["email"];.'</span></div>';

$content .= '</div>';
$content .= '<div class="boite" id="logo">LOGO</div>';
$content .= '<div class="boite" id="enseignement">'. $row_infos_eleve['annee_scolaire']; .'<br>'.$row_infos_eleve['niveau'] .'</div>';
$content .= '<div class="boite" id="niveau"></div>';
$content .= '<div id="numbull">Bulletin N° <span style="font-weight:bold;">'.$row_infos_eleve['numbulletin'] .'</span>  </div>';
$content .= '</div>';
$content .= '<div id="titre">Bulletin de notes du 1er trimestre : Enseignement général</div>';
$content .= '<div id="entete2">';
$content .= '   <div id="entete2left">';
$content .= '       <div>Année scolaire : <span style="font-weight: bold;">'.$row_infos_eleve['annee_scolaire'].'</span></div>';
$content .= '       <div id="nomeleve"> Nom de l\'élève : <span style="font-weight:bold;">'.$row_infos_eleve['nom'].' '.$row_infos_eleve['prenom'];.'</span></div>';
$content .= '       <div id="datenaiss"> Né le : <span style="font-weight: bold;">'.$row_infos_eleve['datenaiss'].'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Matricule : <span style="font-weight: bold;">'.$row_infos_eleve['matricule'].'</span></div>';
$content .= '   </div>';
$content .= '   <div id="entete2right">';
$content .= '       <div id="nomeleve"> Classe de : <span style="font-weight: bold;">'.$row_infos_eleve['classe'].'</span></div>';
$content .= '           <div>Effectif : <span style="font-weight: bold;">'.$row_infos_eleve['effectif'].'</span></div>';
$content .= '           <div id="datenaiss"> Redoublant(e) : <span style="font-weight: bold;">.'($row_infos_eleve['redoublant'] == 'N'?'Non':'Oui').'</span></div>';
$content .= '       </div>';
$content .= '</div>';
$content .= '
    <table>
        <tr>
          <th style="min-width:65mm;font-size:14px;text-align:center;">Matières</th>
          <th style="max-width:15mm;font-size:14px;text-align:center;">Notes / 20</th>
          <th style="max-width:10mm;text-align:center;text-align:center;font-size:14px;">Coef.</th>
          <th style="min-width:1.8mm;text-align:center;font-size:14px;">Notes pondérées</th>
          <th style="min-width:70mm;text-align:center;font-size:14px;">Observations des professeurs</th>
        </tr>
';
while ($row_infos_bull = $reponse_infos_bull->fetch()) {
    $content .= '
        <tr>
          <td style="padding-left:5px;font-size:12px;">'.$row_infos_bull["designation"].'</td>
          <td style="font-size:12px;text-align:center;">'.$row_infos_bull["moyenne"].'</td>
          <td style="font-size:12px;text-align:center;">'.$row_infos_bull["coef"].'</td>
          <td style="font-size:12px;text-align:center;">'.$row_infos_bull["noteponderee"].'</td>
          <td>
                <div style="padding-left:5px;font-size:12px;float:left;">'.$row_infos_bull["appreciation"].'</div>
                <div style="padding-right:5px;font-size:10px; font-style:italic; float:right;">'.$row_infos_bull["npprof"].'</div>
          </td>
        </tr>
    ';
}
$content .= '
        <tr>
          <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">TOTAUX</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td colspan="1" rowspan="5" style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">MOYENNE SUR 20</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">RETRAIT DE POINTS</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">MOYENNE DEFINITIVE</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">Bilan technique</td>
          <td colspan="2" rowspan="1" style="padding-left:5px;font-size:12px;">Bilan général</td>
        </tr>
        <tr>
          <td style="padding-left:5px;font-size:12px;">Moyenne de l\élève</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td colspan="1" rowspan="4" style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;">Rappel Moyennes</td>
        </tr>
        <tr>
          <td style="padding-left:5px;font-size:12px;">Moyenne de la classe</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td colspan="1" rowspan="3" style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td style="padding-left:5px;font-size:12px;">Meilleure moyenne</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td style="padding-left:5px;font-size:12px;">Plus faible moyenne</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
        </tr>
        <tr>
          <td style="padding-left:5px;font-size:12px;">Moyenne annuelle</td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;"></td>
          <td style="padding-left:5px;font-size:12px;">Rang annuel</td>
          <td style="padding-left:5px;font-size:12px;"></td>
        </tr>
</table>
</div>
</div>
</page>
';

try {
    $html2pdf = new Html2Pdf('P', 'A4', 'fr',true, "UTF-8");
    $html2pdf->setDefaultFont('Arial');
    $html2pdf->writeHTML($content);
    $html2pdf->output('/path/to/save/bulletin.pdf','F');
}
catch (Html2PdfException $e) {
    $formatter = new ExceptionFormatter($e);
    echo $formatter->getHtmlMessage();
}

echo '
    <div><a href="/url/to/pdf/bulletin.pdf" class="btn btn-info" role="button">Exporter en PDF</a></div>
    '.$content.'
';
polinevol commented 7 years ago

Hi, It's ok now. I can get my pdf exported without error ! Thanks a lot ! Another problem. If I use the browser menu "Print"->"Print Preview", my page is well formated according to the css file.... but not in the generated pdf. How to ajust my html content to fit in the pdf ?

LittleBigFox commented 7 years ago

Hum... Try to remove the style tag, to see if something is read in the stylesheet... $content = '<style type="text/css">'.file_get_contents("path/to/bulletin.css").'</style>'; to $content = file_get_contents("path/to/bulletin.css");

if something is write in the PDF, have you got any other css on your website who apply? A main stylesheet? In this case, don't forget to add it in the same way than bulletin.css. If not, some attributes are not supported by Html2PDF at this time. Show us your css to see, if you want.

polinevol commented 7 years ago

Hi, When I remove the css, the pdf is not formatted... It's the only one i use in this page. Here my css file bulletin.txt

LittleBigFox commented 7 years ago

Hum, i think it's because some style are not implemented in Html2pdf: max-width, min-width , @page, @media, box-shadow

The style float work only on image, if i remember...

The simplest way to emulate min/max width is to use relative width on cell. You have to set width for every cell for a clean output. Example:

CSS

td {font-size:12px; }
td.designation {width:40%; padding-left:5px; }
td.moyenne {width:10%; text-align:center;}
td.coef {width:10%; text-align:center;}
td.noteponderee {width:10%; text-align:center;}
td.appreciation {width:30%;}

PHP

<tr>
<td class="designation">'.$row_infos_bull["designation"].'</td>
<td class="moyenne">'.$row_infos_bull["moyenne"].'</td>
<td class="coef">'.$row_infos_bull["coef"].'</td>
<td class="notepondere">'.$row_infos_bull["noteponderee"].'</td>
<td class="appreciation">
    <table style="width:100%;"><tr>
         <td style="width:50%;padding-left:5px;">'.$row_infos_bull["appreciation"].'</td>
         <td style="width:50%;padding-right:5px;font-size:10px; font-style:italic;">'.$row_infos_bull["npprof"].'</td>
    </tr></table>
</td>
</tr>
polinevol commented 7 years ago

Thanks a lot. It's ok now. I put my css directly in html file...and I tried to replace float styles by using a tables...

MarcioQuimbundo commented 6 years ago

error_reporting(0) will not solve the problem, but it will clean the output error

spipu commented 6 years ago

never do this !!!!

When you have a water leak, do you close your eyes, instead of fix it ?!