FPDF table 单元格边距和圆角
FPDF table cells margin and rounded corners
我正在使用 tables 创建 PDF 报告文件。
我还需要在每个 table 单元格和每个单元格的圆角之间留出边距。像这样:http://joxi.net/L21XyyLh8aRnLm
有什么办法吗?
This script from fpdf.org可以绘制圆角矩形。让我们扩展它以添加一个 $cellspacing
变量:
<?php
require('rounded_rect.php');
class Bohdan_PDF extends PDF {
var $cellspacing = 1;
function SetCellspacing($cellspacing) {
$this->cellspacing = $cellspacing;
}
接下来,让我们添加一个输出单元格的方法,在其周围绘制一个圆角矩形,并添加单元格间距。它应该接受与 Cell
相同的参数,除了 $border
.
function RoundedBorderCell($w, $h=0, $txt='', $ln=0, $align='',
$fill=false, $link='') {
$this->RoundedRect($this->getX() + $this->cellspacing / 2,
$this->getY() + $this->cellspacing / 2,
$w - $this->cellspacing, $h, 1, 'DF');
$this->Cell($w, $h + $this->cellspacing, $txt, $ln, 0, $align,
$fill, $link);
}
以下方法负责输出 table。
function BohdanTable($header, $data, $widths, $aligns) {
$this->SetLineWidth(0.15);
$rowHeight = $this->FontSizePt - 2;
$this->SetFillColor(255, 255, 0);
for ($i = 0, $j = sizeof($header); $i < $j; $i++) {
$this->RoundedBorderCell($widths[$i], $rowHeight,
$header[$i], 0, $aligns[$i]);
}
$this->Ln();
foreach ($data as $rowId => $row) {
$this->SetFillColor($rowId % 2 == 1 ? 240 : 255);
for ($i = 0, $j = sizeof($row); $i < $j; $i++) {
$this->RoundedBorderCell($widths[$i], $rowHeight,
$row[$i], 0, $aligns[$i]);
}
$this->Ln();
}
}
}
用法示例:
$pdf = new Bohdan_PDF();
$pdf->AddPage();
$pdf->SetFont("Arial", "", 9);
$pdf->BohdanTable(array_fill(0, 4, "Building Name"),
array(
array("Administration Building", "46,314", "1,471,818", "4%"),
array("Alumni House", "4,939", "1,471,818", "400%"),
array("Alumni House Garage", "347", "1,471,818", "34%"),
array("Alumni House Garden House", "165", "1,471,818", "16%")
),
array(105, 26, 26, 26),
array('L', 'R', 'R', 'R'));
$pdf->Output();
示例输出:
更新
这修复了评论中描述的分页问题。此代码检查当前页面上是否还有足够的 space 来添加下一行,如果没有,则将该行放在新页面上。
function RoundedBorderCell($w, $h=0, $txt='', $ln=0, $align='',
$fill=false, $link='') {
$spaceLeft = ($this->h - $this->getY() - $this->bMargin);
$cellHeight = $h + $this->cellspacing;
if ($spaceLeft < $cellHeight) {
$this->AddPage();
}
$this->RoundedRect($this->getX() + $this->cellspacing / 2,
$this->getY() + $this->cellspacing / 2,
$w - $this->cellspacing, $h, 1, 'DF');
$this->Cell($w, $cellHeight, $txt, $ln, 0, $align, $fill, $link);
}
这移植到Python 3.
感谢 Christophe Prugnaud 和 Maxime Delorme 和 Matthias Wiehl 的原始代码。
from fpdf import FPDF
import math
class ROUND_PDF(FPDF):
def rounded_cell(self, w, h=0, txt='', border=0, ln=0, align='', fill=False, link='', radius = 1, corners = (1,2,3,4), cellspacing = 1):
style = 'S'
if fill and border:
style = 'FD'
elif fill:
style = 'F'
self.rounded_rect(self.get_x() + (cellspacing / 2.0),
self.get_y() + (cellspacing / 2.0),
w - cellspacing, h, radius, corners, style)
self.cell(w, h + cellspacing, txt, 0, ln, align, False, link)
def rounded_rect(self, x, y, w, h, r, corners = (1,2,3,4), style = ''):
k = self.k
hp = self.h
if style == 'F':
op = 'f'
elif style=='FD' or style == 'DF':
op='B'
else:
op='S'
my_arc = 4/3 * (math.sqrt(2) - 1)
self._out('%.2F %.2F m' % ((x+r)*k,(hp-y)*k ))
xc = x+w-r
yc = y+r
self._out('%.2F %.2F l' % (xc*k,(hp-y)*k ))
if 2 not in corners:
self._out('%.2F %.2F l' % ((x+w)*k,(hp-y)*k ))
else:
self._arc(xc + r*my_arc, yc - r, xc + r, yc - r*my_arc, xc + r, yc)
xc = x+w-r
yc = y+h-r
self._out('%.2F %.2F l' % ((x+w)*k,(hp-yc)*k))
if 3 not in corners:
self._out('%.2F %.2F l' % ((x+w)*k,(hp-(y+h))*k))
else:
self._arc(xc + r, yc + r*my_arc, xc + r*my_arc, yc + r, xc, yc + r)
xc = x+r
yc = y+h-r
self._out('%.2F %.2F l' % (xc*k,(hp-(y+h))*k))
if 4 not in corners:
self._out('%.2F %.2F l' % ((x)*k,(hp-(y+h))*k))
else:
self._arc(xc - r*my_arc, yc + r, xc - r, yc + r*my_arc, xc - r, yc)
xc = x+r
yc = y+r
self._out('%.2F %.2F l' % ((x)*k,(hp-yc)*k ))
if 1 not in corners:
self._out('%.2F %.2F l' % ((x)*k,(hp-y)*k ))
self._out('%.2F %.2F l' % ((x+r)*k,(hp-y)*k ))
else:
self._arc(xc - r, yc - r*my_arc, xc - r*my_arc, yc - r, xc, yc - r)
self._out(op)
def _arc(self, x1, y1, x2, y2, x3, y3):
h = self.h
self._out('%.2F %.2F %.2F %.2F %.2F %.2F c ' % (x1*self.k, (h-y1)*self.k,x2*self.k, (h-y2)*self.k, x3*self.k, (h-y3)*self.k))
我正在使用 tables 创建 PDF 报告文件。
我还需要在每个 table 单元格和每个单元格的圆角之间留出边距。像这样:http://joxi.net/L21XyyLh8aRnLm
有什么办法吗?
This script from fpdf.org可以绘制圆角矩形。让我们扩展它以添加一个 $cellspacing
变量:
<?php
require('rounded_rect.php');
class Bohdan_PDF extends PDF {
var $cellspacing = 1;
function SetCellspacing($cellspacing) {
$this->cellspacing = $cellspacing;
}
接下来,让我们添加一个输出单元格的方法,在其周围绘制一个圆角矩形,并添加单元格间距。它应该接受与 Cell
相同的参数,除了 $border
.
function RoundedBorderCell($w, $h=0, $txt='', $ln=0, $align='',
$fill=false, $link='') {
$this->RoundedRect($this->getX() + $this->cellspacing / 2,
$this->getY() + $this->cellspacing / 2,
$w - $this->cellspacing, $h, 1, 'DF');
$this->Cell($w, $h + $this->cellspacing, $txt, $ln, 0, $align,
$fill, $link);
}
以下方法负责输出 table。
function BohdanTable($header, $data, $widths, $aligns) {
$this->SetLineWidth(0.15);
$rowHeight = $this->FontSizePt - 2;
$this->SetFillColor(255, 255, 0);
for ($i = 0, $j = sizeof($header); $i < $j; $i++) {
$this->RoundedBorderCell($widths[$i], $rowHeight,
$header[$i], 0, $aligns[$i]);
}
$this->Ln();
foreach ($data as $rowId => $row) {
$this->SetFillColor($rowId % 2 == 1 ? 240 : 255);
for ($i = 0, $j = sizeof($row); $i < $j; $i++) {
$this->RoundedBorderCell($widths[$i], $rowHeight,
$row[$i], 0, $aligns[$i]);
}
$this->Ln();
}
}
}
用法示例:
$pdf = new Bohdan_PDF();
$pdf->AddPage();
$pdf->SetFont("Arial", "", 9);
$pdf->BohdanTable(array_fill(0, 4, "Building Name"),
array(
array("Administration Building", "46,314", "1,471,818", "4%"),
array("Alumni House", "4,939", "1,471,818", "400%"),
array("Alumni House Garage", "347", "1,471,818", "34%"),
array("Alumni House Garden House", "165", "1,471,818", "16%")
),
array(105, 26, 26, 26),
array('L', 'R', 'R', 'R'));
$pdf->Output();
示例输出:
更新
这修复了评论中描述的分页问题。此代码检查当前页面上是否还有足够的 space 来添加下一行,如果没有,则将该行放在新页面上。
function RoundedBorderCell($w, $h=0, $txt='', $ln=0, $align='',
$fill=false, $link='') {
$spaceLeft = ($this->h - $this->getY() - $this->bMargin);
$cellHeight = $h + $this->cellspacing;
if ($spaceLeft < $cellHeight) {
$this->AddPage();
}
$this->RoundedRect($this->getX() + $this->cellspacing / 2,
$this->getY() + $this->cellspacing / 2,
$w - $this->cellspacing, $h, 1, 'DF');
$this->Cell($w, $cellHeight, $txt, $ln, 0, $align, $fill, $link);
}
这移植到Python 3.
感谢 Christophe Prugnaud 和 Maxime Delorme 和 Matthias Wiehl 的原始代码。
from fpdf import FPDF
import math
class ROUND_PDF(FPDF):
def rounded_cell(self, w, h=0, txt='', border=0, ln=0, align='', fill=False, link='', radius = 1, corners = (1,2,3,4), cellspacing = 1):
style = 'S'
if fill and border:
style = 'FD'
elif fill:
style = 'F'
self.rounded_rect(self.get_x() + (cellspacing / 2.0),
self.get_y() + (cellspacing / 2.0),
w - cellspacing, h, radius, corners, style)
self.cell(w, h + cellspacing, txt, 0, ln, align, False, link)
def rounded_rect(self, x, y, w, h, r, corners = (1,2,3,4), style = ''):
k = self.k
hp = self.h
if style == 'F':
op = 'f'
elif style=='FD' or style == 'DF':
op='B'
else:
op='S'
my_arc = 4/3 * (math.sqrt(2) - 1)
self._out('%.2F %.2F m' % ((x+r)*k,(hp-y)*k ))
xc = x+w-r
yc = y+r
self._out('%.2F %.2F l' % (xc*k,(hp-y)*k ))
if 2 not in corners:
self._out('%.2F %.2F l' % ((x+w)*k,(hp-y)*k ))
else:
self._arc(xc + r*my_arc, yc - r, xc + r, yc - r*my_arc, xc + r, yc)
xc = x+w-r
yc = y+h-r
self._out('%.2F %.2F l' % ((x+w)*k,(hp-yc)*k))
if 3 not in corners:
self._out('%.2F %.2F l' % ((x+w)*k,(hp-(y+h))*k))
else:
self._arc(xc + r, yc + r*my_arc, xc + r*my_arc, yc + r, xc, yc + r)
xc = x+r
yc = y+h-r
self._out('%.2F %.2F l' % (xc*k,(hp-(y+h))*k))
if 4 not in corners:
self._out('%.2F %.2F l' % ((x)*k,(hp-(y+h))*k))
else:
self._arc(xc - r*my_arc, yc + r, xc - r, yc + r*my_arc, xc - r, yc)
xc = x+r
yc = y+r
self._out('%.2F %.2F l' % ((x)*k,(hp-yc)*k ))
if 1 not in corners:
self._out('%.2F %.2F l' % ((x)*k,(hp-y)*k ))
self._out('%.2F %.2F l' % ((x+r)*k,(hp-y)*k ))
else:
self._arc(xc - r, yc - r*my_arc, xc - r*my_arc, yc - r, xc, yc - r)
self._out(op)
def _arc(self, x1, y1, x2, y2, x3, y3):
h = self.h
self._out('%.2F %.2F %.2F %.2F %.2F %.2F c ' % (x1*self.k, (h-y1)*self.k,x2*self.k, (h-y2)*self.k, x3*self.k, (h-y3)*self.k))