我正在使用FPDF来呈现html内容中的表格。
因此,当我想渲染表格时,我得到了这个link来渲染表格。问题是我在html中一个接一个地有两个表,我不能将它分开,因为内容来自 <?php
//Based on HTML2PDF by Clément Lavoillotte
require('fpdf/fpdf.php');
require('htmlparser.inc.php');
class PDF_HTML_Table extends FPDF
{
var $B;
var $I;
var $U;
var $HREF;
function PDF($orientation='P', $unit='mm', $format='A4')
{
//Call parent constructor
$this->FPDF($orientation,$unit,$format);
//Initialization
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
}
function WriteHTML2($html)
{
//HTML parser
$html=str_replace("\n",' ',$html);
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
foreach($a as $i=>$e)
{
if($i%2==0)
{
//Text
if($this->HREF)
$this->PutLink($this->HREF,$e);
else
$this->Write(5,$e);
}
else
{
//Tag
if($e[0]=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extract attributes
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach($a2 as $v)
{
if(preg_match('/([^=]*)=["\']?([^"\']*)/',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
}
$this->OpenTag($tag,$attr);
}
}
}
}
function OpenTag($tag, $attr)
{
//Opening tag
if($tag=='B' || $tag=='I' || $tag=='U')
$this->SetStyle($tag,true);
if($tag=='A')
$this->HREF=$attr['HREF'];
if($tag=='BR')
$this->Ln(5);
if($tag=='P')
$this->Ln(10);
}
function CloseTag($tag)
{
//Closing tag
if($tag=='B' || $tag=='I' || $tag=='U')
$this->SetStyle($tag,false);
if($tag=='A')
$this->HREF='';
if($tag=='P')
$this->Ln(10);
}
function SetStyle($tag, $enable)
{
//Modify style and select corresponding font
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array('B','I','U') as $s)
if($this->$s>0)
$style.=$s;
$this->SetFont('',$style);
}
function PutLink($URL, $txt)
{
//Put a hyperlink
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
function WriteTable($data, $w)
{
$this->SetLineWidth(.3);
$this->SetFillColor(255,255,255);
$this->SetTextColor(0);
$this->SetFont('');
foreach($data as $row)
{
$nb=0;
for($i=0;$i<count($row);$i++)
$nb=max($nb,$this->NbLines($w[$i],trim($row[$i])));
$h=5*$nb;
$this->CheckPageBreak($h);
for($i=0;$i<count($row);$i++)
{
$x=$this->GetX();
$y=$this->GetY();
$this->Rect($x,$y,$w[$i],$h);
$this->MultiCell($w[$i],5,trim($row[$i]),0,'C');
//Put the position to the right of the cell
$this->SetXY($x+$w[$i],$y);
}
$this->Ln($h);
}
}
function NbLines($w, $txt)
{
//Computes the number of lines a MultiCell of width w will take
$cw=&$this->CurrentFont['cw'];
if($w==0)
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
$s=str_replace("\r",'',$txt);
$nb=strlen($s);
if($nb>0 && $s[$nb-1]=="\n")
$nb--;
$sep=-1;
$i=0;
$j=0;
$l=0;
$nl=1;
while($i<$nb)
{
$c=$s[$i];
if($c=="\n")
{
$i++;
$sep=-1;
$j=$i;
$l=0;
$nl++;
continue;
}
if($c==' ')
$sep=$i;
$l+=$cw[$c];
if($l>$wmax)
{
if($sep==-1)
{
if($i==$j)
$i++;
}
else
$i=$sep+1;
$sep=-1;
$j=$i;
$l=0;
$nl++;
}
else
$i++;
}
return $nl;
}
function CheckPageBreak($h)
{
//If the height h would cause an overflow, add a new page immediately
if($this->GetY()+$h>$this->PageBreakTrigger)
$this->AddPage($this->CurOrientation);
}
function ReplaceHTML($html)
{
$html = str_replace( '<li>', "\n<br> - " , $html );
$html = str_replace( '<LI>', "\n - " , $html );
$html = str_replace( '</ul>', "\n\n" , $html );
$html = str_replace( '<strong>', "<b>" , $html );
$html = str_replace( '</strong>', "</b>" , $html );
$html = str_replace( ' ', "\n" , $html );
$html = str_replace( ' ', " " , $html );
$html = str_replace( '"', "\"" , $html );
$html = str_replace( ''', "'" , $html );
return $html;
}
function ParseTable($Table)
{
$_var='';
$htmlText = $Table;
$parser = new HtmlParser ($htmlText);
while ($parser->parse())
{
if(strtolower($parser->iNodeName)=='table')
{
if($parser->iNodeType == NODE_TYPE_ENDELEMENT)
$_var .='/::';
else
$_var .='::';
}
if(strtolower($parser->iNodeName)=='tr')
{
if($parser->iNodeType == NODE_TYPE_ENDELEMENT)
$_var .='!-:'; //opening row
else
$_var .=':-!'; //closing row
}
if(strtolower($parser->iNodeName)=='td' && $parser->iNodeType == NODE_TYPE_ENDELEMENT)
{
$_var .='#,#';
}
if ($parser->iNodeName=='Text' && isset($parser->iNodeValue))
{
$_var .= $parser->iNodeValue;
}
}
$elems = explode(':-!',str_replace('/','',str_replace('::','',str_replace('!-:','',$_var)))); //opening row
foreach($elems as $key=>$value)
{
if(trim($value)!='')
{
$elems2 = explode('#,#',$value);
array_pop($elems2);
$data[] = $elems2;
}
}
return $data;
}
function WriteHTML($html)
{
$html = $this->ReplaceHTML($html);
//Search for a table
$start = strpos(strtolower($html),'<table');
$end = strpos(strtolower($html),'</table');
if($start!==false && $end!==false)
{
$this->WriteHTML2(substr($html,0,$start).'<BR>');
$tableVar = substr($html,$start,$end-$start);
$tableData = $this->ParseTable($tableVar);
for($i=1;$i<=count($tableData[0]);$i++)
{
if($this->CurOrientation=='L')
$w[] = abs(120/(count($tableData[0])-1))+24;
else
$w[] = abs(120/(count($tableData[0])-1))+5;
}
$this->WriteTable($tableData,$w);
$this->WriteHTML2(substr($html,$end+8,strlen($html)-1).'<BR>');
}
else
{
$this->WriteHTML2($html);
}
}
}
编辑器。这里的第一张表工作正常。但对于第二张表,它根本不起作用。我检查了所有标记,一切看起来都不错。
html_table.php就像这样
<?php
require('html_table.php');
$pdf = new PDF_HTML_Table();
$pdf->AddPage();
$pdf->SetFont('Arial','',12);
$html='<table border="1">
<tr>
<td width="200" height="30">cell 1</td><td width="200" height="30" bgcolor="#D0D0FF">cell 2</td>
</tr>
<tr>
<td width="200" height="30">cell 3</td><td width="200" height="30">cell 4</td>
</tr>
</table>
<br>
<br>
<table border="1">
<tr>
<td width="200" height="30">cell 5</td><td width="200" height="30" bgcolor="#D0D0FF">cell 6</td>
</tr>
<tr>
<td width="200" height="30">cell 7</td><td width="200" height="30">cell 8</td>
</tr>
</table>
';
$pdf->WriteHTML($html);
$pdf->Output();
?>
并且index.php就像这样
public function getStartOfQuarter()
{
return date(sprintf('Y-%s-01', floor((date('n') - 1) / 3) * 3 + 1));
}
public function getEndOfQuarter()
{
return date(sprintf('Y-%s-t', floor((date('n') + 2) / 3) * 3));
}
有人能告诉我如何解决这个问题吗?任何帮助和建议都会非常明显。感谢
答案 0 :(得分:1)
如果您使用HTML代码为使用FPDF库生成的PDF文档构建表,那么请查看FPDF easyTable项目https://github.com/fpdf-easytable/fpdf-easytable
$table=new easyTable($pdf, 3, 'border:1;');
// first row
$table->easyCell('Text 1', 'valign:T');
$table->easyCell('Text 2', 'bgcolor:#b3ccff;');
$table->easyCell('Text 3');
$table->printRow();
//second row
$table->rowStyle('min-height:20; align:{C}');
$table->easyCell('Text 4', 'colspan:3');
$table->printRow();
$table->endTable(4);
答案 1 :(得分:0)
前几天我遇到了这个问题,并提出了以下解决方案:
在FPDF类中,添加一个函数findAll()
。这将用于查找HTML中的<table
和</table
的所有实例以进行转换:
function findAll($needle, $haystack)
{
// initialize the return value array
$rv = array();
// set up a temp variable to make things simple
$temp = 0;
// successively find each instance of needle in haystack
while($temp < strlen($haystack))
{
$temp = strpos($haystack,$needle, $temp);
if($temp !== false)
{
$rv[] = $temp;
$temp++;
}
else
{
// nothing to find
return $rv;
}
}
return $rv;
}
将WriteHTML()
函数修改为a)使用findAll()
查找所有表实例,b)替换每个实例(保持任何非表格格式不变)。此修改基本上将您的HTML“块”分为“表格”和“非表格”,并相应地格式化HTML:
function WriteHTML($html)
{
$w = array();
// search for a table
$starts = $this->findAll('<table',strtolower($html));
$ends = $this->findAll('</table',strtolower($html));
if(count($starts) > 0 && count($ends) > 0)
{
$positions[0] = 'doc-start';
foreach($starts as $key => $start)
{
$end = $ends[$key];
$positions[$start] = 'table-start';
$positions[$end] = 'table-end';
}
$endPos = strlen($html)-1;
$positions[$endPos] = 'doc-end';
$lastKnownPos = 0;
for($q=1;$q<=$endPos;$q++)
{
if(isset($positions[$q]))
{
$curPos = $positions[$q];
if($curPos == 'table-start')
{
$this->WriteHTML2(substr($html,$lastKnownPos,$q-$lastKnownPos).'<BR>');
$lastKnownPos = $q;
}
else if($curPos == 'table-end')
{
$tableVar = substr($html,$lastKnownPos,$q-$lastKnownPos+8);
$tableData = $this->ParseTable($tableVar);
for($i=0;$i<count($tableData[0]);$i++)
{
if($this->CurOrientation=='L')
{
$w[$i] = abs(277/(count($tableData[0])));
}
else
{
$w[$i] = abs(190/(count($tableData[0])));
}
}
$this->WriteTable($tableData,$w);
$lastKnownPos = $q+8;
}
else if($curPos == 'doc-end')
{
$this->WriteHTML2(substr($html,$lastKnownPos,$q-$lastKnownPos).'<BR>');
$lastKnownPos = $q;
}
}
}
}
else
{
// if there is no table, just write the HTML as normal
$this->WriteHTML2($html);
}
}