TCPDF 在 mysql 中的选定记录上生成空白页

TCPDF produce blank page on selected records from mysql

我需要帮助。

我正在尝试从 DB 中准备一份 pdf,但结果是空白的。 pdf 格式为 table,带有单独的内联样式。 Table 设计有非常复杂的条件,例如根据客户要求的某些标准进行行和列合并。

这是我在测试中发现的:

  1. 从数据库中提取少量记录 -​​ pdf 显示完美
  2. 从数据库中获取大量记录 -​​ pdf 显示空白(屏幕上没有其他错误,只有编码中设置的带有页眉和页脚的纯白色 pdf)
  3. 如果记录量很大,仅在 HTML 中回显 - 所有记录都以 table 格式完美显示。

我做了什么: 增加时间限制、执行时间、使用 get_ob_contents 和所有 ob 系列以及我在 stackflow 中按照 google 指示找到的大部分解决方案,但我没有找到解决方案。

我将所有 sql 结果存储在一个数组中,因为我必须根据某个字段进行排序,该字段具有另一个 table 的排序顺序(许多左加入 sql).我没有添加到左连接,而是考虑将 array_multisort 与所选字段一起使用。 pdf 是基于 sql 查询生成的,该查询具有多个左连接和 where 子句,使用 html 形式设置。一旦 array_multisort 完成,只有 for 循环被设置为使用 writeHTML()

展开变量以执行 pdf

测试示例:

  1. sql 记录较少的结果(估计:测试期间有 20 条记录)pdf 完美地生成了分页符和页码。

  2. sql 结果有很多记录 (149) pdf 纯白色单页,只有页眉和页脚出现

我似乎无法找到一个解决方案来显示具有 table 格式的大量 sql 数据的 pdf。

有没有更好的方法来完成这个?

顺便说一句,我使用的是 TCPDF 版本 6.2.9,这让我头疼,所以我下载了 6.3.1,结果相同。

    <?php
error_reporting(E_ALL);
ini_set('display_errors',"On");

//require_once('tcpdf_include.php');
$original_mem=ini_get('memory_limit');
ini_set('memory_limit','340M');
session_start();
ob_start();

// Include the main TCPDF library (search for installation path). 
include '../../dbc.php';
include '../../func.php';

function conditional_format($data){
    //function for conditional formatting
    //with table row structure 
return $formatted_data;
}

require_once('tcpdf_include.php');
// Increase max_execution_time. If a large pdf fails, increase it even more.
ini_set('max_execution_time', 180);
// Increase this for old PHP versions (like 5.3.3). If a large pdf fails, increase it even more.
ini_set('pcre.backtrack_limit', 1000000);
    




//below function to set footer align in middl of page
class MYPDF extends TCPDF {
    public function Header() {

        $curdate=date("d/m/Y");
        // get the current page break margin
        $bMargin = $this->getBreakMargin();
        // get current auto-page-break mode
        $auto_page_break = $this->AutoPageBreak;
        // disable auto-page-break
        $this->SetAutoPageBreak(false, 0);
        if($this->page==1){
            //client requested title only on first page
            $this->Cell(0, 9, 'TRADEMARK STATUS REPORT', 'B', false, 'C', 0, '', 0, false, 'M', 'M');
        }
        $this->SetFont('helvetica', 'B', 10);
        $this->SetAutoPageBreak($auto_page_break, $bMargin);
        $this->setPageMark();
    }

    public function Footer() {
        $curdate=date("d/m/Y");
            // Position at 10 mm from bottom
        $this->SetY(-10);
        // Set font
        $this->SetFont('helvetica', 'I', 8);
        // Page number
        $this->Cell(0, 10, 'as at '.$curdate, 'T', false, 'L', 0, '', 0, false, 'T', 'M');
        $this->Cell(0, 10, 'Page '.$this->getAliasNumPage(), 'T', false, 'R', 0, '', 0, false, 'T', 'M');
    
    }
}

//call custom page foooter from function above
$pdf=new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Ryan');
$pdf->SetTitle('Trade Mark Status Report');
$pdf->SetSubject('Trade Mark');
$pdf->SetKeywords('Trade Mark, PDF, example, test, guide');

// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);


// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

// set some language-dependent strings (optional)
if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
    require_once(dirname(__FILE__).'/lang/eng.php');
   $pdf->setLanguageArray($l);
}

// ---------------------------------------------------------

// set font
$pdf->SetFont('freeserif', 'B', 20);

// add a page
$pdf->setHeaderFont(array('', 'B', 14));
$pdf->AddPage('L', 'A4');

$pdf->SetFont('freeserif', '', 8);

$main_sql="SELECT ..... WHERE 
$user_emtered_where_clause";

//echo $main_sql;
// there is no issue with sql when echo

$result=mysqli_query($db,$main_sql);
$tbl="";
if(!$result){
    echo "Error: ".mysqli_error($db);
}else{
    if(mysqli_num_rows($result)>0){
        while($main_rs=mysqli_fetch_array($result)){
            //get record data from DB
            // design tbl header with selected record 
            $tbl = <<<EOF
            
            <table width="950" v-align="top" style="border-collapse: collapse;font-size:13px;table-layout:fixed;" border="0" cellpadding="0" cellspacing="0">
                <thead>
                    <tr>
                        <td width="950" colspan="7" style="padding:3px;text-align:center;background-color:lightgray;border-bottom:1px solid black;"><h2 style="font-weight:bold;line-height:20px;">$ProjectCompany</h2>
                        </td>
                    </tr>
                    <tr>
                        <td width="950"  colspan="7" style="font-size:17px;font-weight:bold;vertical-align:top;"><br>
                            $TMClient
                        </td>                       
                    </tr>
                    <tr>
                        <td width="30" style="text-align:center;border-left:1px solid black;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">No</td>
                        <td width="100" style="text-align:center;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">Filing Country</td>
                        <td width="175" style="text-align:center;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">Applicant/Proprietor</td>
                        <td width="100" style="text-align:center;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">Trademark No</td> 
                        <td width="205" style="text-align:center;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">Trademark</td>
                        <td width="80"  style="text-align:center;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">Status</td>
                        <td width="260" style="text-align:center;border-right: 1px solid black;border-bottom: 1px solid black;border-top:1px solid black;background-color: azure;font-weight:bold;">Remarks</td>                                    
                    </tr>
                </thead>
            <tbody>             
    EOF;
        
        //assign data to array           
      
        $data_array[]=array(all record data here);// assign to array
            
        
    }
    
    //sort array
    foreach ($data_array as $key => $row){
        $sort_country[$key] = $row['sort'];
        //to get the sort order value from array
    }
    // rearrange the array based on the sort order value above
    array_multisort($sort_country, SORT_ASC, $data_array);
    //view array data
     //echo "<pre>";
     //print_r($data_array);
     //echo "</pre>":
     // array data all appear perfect.
    
    if(count($data_array)>0){
        
        $n=1;
        // construct table body data
        foreach($data_array as $item){
            set_time_limit(60);
            
            $no =$n;
            //------------------------ construction of table body -----------------------------------
            
                $class_data= conditional_format($classid); // call conditional format function with variable from $data_array    
                
            $pbreak=$conditional_page_break;
            $tbl_data .= <<<EOD
            $pbreak  

                    <tr nobr="true">
                        <td width="950"  padding="0" style="text-align:left;"><table width="950" style="font-size:13px;table-layout:fixed;border:1px solid red;" border="1" cellpadding="2" cellspacing="0">                                
                                
                                <tr nobr="true">
                                    <td width="30" height="105" style="text-align:center;vertical-align:top;border-top:1px solid black;border-left:1px solid black;border-right: 1px solid black;">$no</td>
                                    <td width="100" height="105" v-align="top" style="text-align:center;vertical-align:top;border-top:1px solid black;border-right: 1px solid black;border-bottom:1px solid black;">$TMCountry</td>
                                    <td width="175" height="105" v-align="top" style="text-align:left;border-top:1px solid black;border-right: 1px solid black;border-bottom:1px solid black;">$TMEffecOwner</td>
                                    <td width="100" height="105" v-align="top" style="vertical-align:top;border-top:1px solid black;text-align:center;border-right: 1px solid black;border-bottom:1px solid black;">$TMApplnNo</td> 
                                    <td width="205" height="105" style="text-align:center;word-wrap: break-word;border-top:1px solid black;border-right: 1px solid black;border-bottom:1px solid black;"><br><br>$logo $imgType</td>
                                    <td width="80" height="105" v-align="top" style="border-top:1px solid black;text-align:center;vertical-align:top;border-right: 1px solid black;border-bottom:1px solid black;">$Status</td>
                                    <td width="260" height="105" v-align="top" style="border-top:1px solid black;vertical-align:top;border-right:1px solid black;border-bottom:1px solid black;">$Remarks</td>
                                </tr>
                            </table>
                        </td>
                    </tr>                                                
                    <tr nobr="true">
                        <td width="950" align="center" style="text-align: center; padding:0px;"><table width="950" v-align="top" style="margin-left: auto;margin-right: auto; font-size:13px;padding:3px;" border="0" cellpadding="0" cellspacing="0" >
                                <tr>
                                    <td width="30" style="border-left:1px solid black;border-right:1px solid black;">&nbsp;&nbsp;</td>
                                    <td width="100" style="border-left:1px solid black;font-weight:bold;background-color:#F3F3F3;">Class: &nbsp;&nbsp;</td>
                                    <td width="820" style="border-right:1px solid black;font-weight:bold;background-color:#F3F3F3;">Specification: &nbsp;&nbsp;</td>
                                </tr>
                                $class_data
                            </table>
                        </td>                                                    
                    </tr> 
                        
                              
        EOD;
            $n++;
            $linecount++;
            }
        
        }else{
            $tbl= "no record";
        }
    }   
    $tbl.=$tbl_data."
                            </tbody> 
                        </table>
                        ";
$tbl_decode=ob_get_contents();
$pdf->SetY(10);
ob_end_clean();
//echo $tbl_decode; //this echo does produce HTML version of entire table
$pdf->writeHTML($tbl_decode, true, false, false, false, ''); // this is where I get blank pdf page
$pdf->Output('Trademark_Status_Report_with_spec.pdf', 'I');

    ini_set('memory_limit',$original_mem);

?>

找到原因了

首先..它的时间限制问题 所以我将时间限制更改为以下

foreach($data_array as $item){
            set_time_limit(400);//this did send out the output

第二期与 sql

中的文本字段相关
htmlentities($value);

现已解决。