perlucas/fpdftablewrapper

FPDF包装器,降低在PDF中创建表格的复杂性

dev-master 2020-04-30 23:43 UTC

This package is auto-updated.

Last update: 2024-09-29 05:36:19 UTC


README

FPDFTableWrapper 是知名 FPDF 类的扩展,它引入了用于轻松、敏捷地进行表格打印的方法和实用工具。在使用 FPDF 进行 PDF 开发时,此扩展将非常有用。如果您文档中的表格难以使用常规 FPDF 方法构建,那么此扩展就是您需要的,可以让表格设计和打印变得简单。

基本用法

FPDFTableWrapperFPDF 类的扩展。您可以使用传统的 FPDF 方法来打印和布局您的文档。包装器仅在打印面向表格的结构(即:基本表格、嵌套表格等)时必须使用。让我们看一个基本示例

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->openRow();
		$pdf->printCell("Primer valor");
		$pdf->printCell("Segundo valor");
		$pdf->printCell("Tercer valor");
	$pdf->closeRow();
$pdf->closeTable();

$pdf->output();

我们通过使用默认构造函数(它使用在 FPDF() 中定义的默认参数)创建了一个包装器的新实例。然后我们添加了一个新页面,选择了一种字体,并打印了一个换行符。接下来是什么?表格定义。openTable 方法让我们打开一个将在 PDF 中打印的新表格。openTable 必须使用 3 个参数调用

  1. 一个表示表格中每列宽度的百分比 float 数组。
  2. 一个表示表格中每列文本对齐方式的字符串数组。它必须是 "C" 表示居中,"L" 表示左或 "R" 表示右。
  3. 可选地,您可以使用第三个参数来指定表格的标题。此参数必须是每列标题的数组。

一旦我们打开了表格,我们必须通过表格行来指示表格内容。使用 openRow 方法可以用来表示表格中新行的开始,而使用 closeRow 方法可以表示行的结束。您可以将 openclose 方法视为在制作基于 HTML 的表格时使用的 <table></table><tr></tr><td></td> 标签。

使用 printCell 我们可以将新单元格引入行中。请注意,我们可以在行中引入的单元格数量必须与同一父表格中的每行的单元格数量相同。

请注意,每个 open 方法都必须有相应的 close 方法。生成的 PDF 文档如下:image-20200407162656090

请注意,标题标题始终居中。

我们刚刚创建了我们第一个表格。我们将使用此声明性方式使用包装器打印使用 FPDF 的表格。如果您回顾一下代码,您会注意到我们指示了表格的布局、每列的宽度、行数以及每行的内容。这种声明性语法使表格的最终结构更容易理解。

我们可以多次使用 openRow 方法来添加更多行

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->openRow();
		$pdf->printCell("Primer valor");
		$pdf->printCell("Segundo valor");
		$pdf->printCell("Tercer valor");
	$pdf->closeRow();
    $pdf->openRow();
        $pdf->printCell("Primer valor 2");
        $pdf->printCell("Segundo valor 2");
        $pdf->printCell("Tercer valor 2");
    $pdf->closeRow();
	$pdf->openRow();
		$pdf->printCell("Primer valor 3");
		$pdf->printCell("Segundo valor 3");
		$pdf->printCell("Tercer valor 3");
	$pdf->closeRow();
$pdf->closeTable();

$pdf->output();

image-20200407163106254

如果我们知道一行中的单元格仅包含纯文本,那么我们可以使用简写方式向表格中添加新行。我们正在寻找的是printRow方法。(是的,我知道你在想什么,这是正确的:printCell是打开、打印、关闭行中单元格的简写方法)

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["Primer valor","Segundo valor","Tercer valor"]);
	$pdf->printRow(["Primer valor 2","Segundo valor 2","Tercer valor 2"]);
	$pdf->printRow(["Primer valor 3","Segundo valor 3","Tercer valor 3"]);
$pdf->closeTable();

$pdf->output();

printRow接收一个数组,其中包含每个单元格中的文本。

嵌套表格

我们定义嵌套表格为充当另一个父表格单元格的表格。这种含义表明我们需要在单元格内打开一个新表格,以支持嵌套表格的包装器。

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["Primer valor","Segundo valor","Tercer valor"]);
	$pdf->printRow(["Primer valor 2","Segundo valor 2","Tercer valor 2"]);
	
	// use  open row for access each cell
	$pdf->openRow();
		$pdf->printCell("Primer valor 3");
		$pdf->printCell("Segundo valor 3");
		
		// open a new cell
		$pdf->openCell();
			$pdf->openTable(
                [40, 40, 20],
                "R", // short way of doing ["R", "R", "R"]
                ['col1', 'col2', 'col3']
            );
				$pdf->printRow(['A', 'B', 'C']);
				$pdf->printRow(['D', 'E', 'F']);
			$pdf->closeTable(); // close the nested table
		$pdf->closeCell(); // close cell
	$pdf->closeRow();

$pdf->closeTable(); // close parent table
$pdf->output();

生成的PDF是

image-20200407171321864

甚至可以添加另一个嵌套层

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["Primer valor","Segundo valor","Tercer valor"]);
	$pdf->printRow(["Primer valor 2","Segundo valor 2","Tercer valor 2"]);
	$pdf->openRow();
		$pdf->printCell("Primer valor 3");
		$pdf->printCell("Segundo valor 3");
		$pdf->openCell();
			$pdf->openTable(
                [40, 40, 20],
                "R", // todas las columnas a la derecha
                ['col1', 'col2', 'col3']
            );
				$pdf->printRow(['A', 'B', 'C']);
				$pdf->openRow();
					$pdf->printCell('D');
					$pdf->printCell('E');
					$pdf->openCell();
						$pdf->openTable([50, 50], ['R', 'L'], ['F1', 'F2']);
							$pdf->printRow(["f11", "f22"]);
							$pdf->printRow(["f33", "f44"]);
						$pdf->closeTable();
					$pdf->closeCell();
				$pdf->closeRow();
			$pdf->closeTable();
		$pdf->closeCell();
	$pdf->closeRow();
$pdf->closeTable();
$pdf->output();

image-20200407180529739

表格合并和单元格分割

openTable的第三个参数指示表格每列的标题。这是一个可选参数。我们可以省略它以创建新的表格分区。这允许我们在单元格中进行划分

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["Primer valor","Segundo valor","Tercer valor"]);
	$pdf->printRow(["Primer valor 2","Segundo valor 2","Tercer valor 2"]);
	$pdf->openRow();
		$pdf->printCell("Primer valor 3");
		$pdf->printCell("Segundo valor 3");		
		$pdf->openCell();
			$pdf->openTable([40, 40, 20],"R"); // no header
				$pdf->printRow(['A', 'B', 'C']);
				$pdf->printRow(['D', 'E', 'F']);
			$pdf->closeTable();
		$pdf->closeCell();
	$pdf->closeRow();
$pdf->closeTable();
$pdf->output();

我们得到以下PDF

image-20200408084636831

我们可以使用此功能构建的一些示例

image-20200408085354110

image-20200408111423568

image-20200408114049159

表格样式

FPDFTableWrapper使用一种机制,允许我们根据我们的自定义要求定义表格的视觉样式。我们可以自定义表格中特定行、列或特定单元格的视觉样式。当我们谈论样式时,我们指的是字体大小、字体粗细、填充颜色以及其他我们可以使用传统FPDF方法设置的打印配置。

单元格高度

setCellHeight方法让我们可以修改表格中每个单元格的高度,使用与默认值5不同的值。setCellHeight方法改变表格中所有行的行高

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->setCellHeight(15); // change cell height
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["A","B","C"]);
	$pdf->printRow(["D","E","F"]);
	$pdf->printRow(["G","H","I"]);
$pdf->closeTable();

$pdf->output();

image-20200408114716203

行样式

setRowStyle方法可以用来将样式回调关联到表格中的行。第一个参数必须指示行的索引。0值表示表格的第一行或如果有,则是标题。第二个参数必须是一个回调,该回调使用包装器来配置该行中值的打印样式。回调将在打印值之前应用于该行的每个单元格

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->setRowStyle(2, function ($pdf) {
       $pdf->setFont('Times', 'U', 10) ;
    }); // applies on the row 2

	$pdf->printRow(["A","B","C"]);
	$pdf->printRow(["D","E","F"]);
	$pdf->printRow(["G","H","I"]);

	$pdf->setRowStyle(0, function ($pdf) {
    	$pdf->setFillColor(50, 50, 0);
    }); // applies on the header

$pdf->closeTable();

$pdf->output();

image-20200408115530966

在默认情况下,在打印特定单元格之前,包装器会执行setTableBodyStyle方法以准备表格正常行的打印配置,以及setTableHeaderStyle方法以准备标题的打印样式。您可以为包装器扩展并定义自己的行和标题样式。

列样式

与行样式类似,我们有setColumnStyle方法来为表格中的每个特定列附加回调。0列将是第一列。这些样式应用于属于该列编号的所有单元格,但不包括标题单元格(包装器理解标题单元格样式是在0行回调或setTableHeaderStyle方法中定义的)

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["A","B","C"]);
	$pdf->printRow(["D","E","F"]);
	$pdf->printRow(["G","H","I"]);

	$pdf->setColumnStyle(1, function ($pdf) {
    	$pdf->setFontSize(15);
        // applies to the column 1
    });

	$pdf->setColumnStyle(2, function($pdf) {
       $pdf->setFont('Times', 'I', 20);
       $pdf->setFillColor(250, 155, 135);
    }); // applies to the column 2

$pdf->closeTable();

$pdf->output();

image-20200408120544339

单元格样式

最后,我们可以定义一个影响表格中特定单元格的回调。setCellStyle方法提供了一种声明特定单元格样式的途径。第一个参数必须指示行,第二个是列,第三个是回调

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["A","B","C"]);
	$pdf->printRow(["D","E","F"]);
	$pdf->printRow(["G","H","I"]);

	$pdf->setCellStyle(2, 1, function($pdf) {
       $pdf->setFont('Times', 'I', 20);
       $pdf->setFillColor(250, 155, 135);
    });

	$pdf->setCellStyle(3, 0, function($pdf) {
       $pdf->setFont('Times', 'U', 20);
       $pdf->setFillColor(250, 250, 135);
    });

$pdf->closeTable();

$pdf->output();

image-20200408121012874

嵌套表格中的样式

显然,我们可以在嵌套表格中使用回调方法。您可以将回调方法放在任何位置,但请记住,在使用它们时,请使用openTablecloseTable调用。该方法将影响包含它的特定表格的行/列/单元格

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->cell(20, 8, 'Nueva tabla');
$pdf->ln();
$pdf->openTable(
    [30, 30, 40], 
    ['L', 'L', 'R'], 
    ['Titulo 1', 'Titulo 2', 'Titulo 3']
);
	$pdf->printRow(["Primer valor","Segundo valor","Tercer valor"]);
	$pdf->printRow(["Primer valor 2","Segundo valor 2","Tercer valor 2"]);
	$pdf->openRow();
		$pdf->printCell("Primer valor 3");
		$pdf->printCell("Segundo valor 3");		
		$pdf->openCell();
			$pdf->openTable([40, 40, 20],"R");

				$pdf->printRow(['A', 'B', 'C']);
				$pdf->printRow(['D', 'E', 'F']);
				$pdf->printRow(['G', 'H', 'I']);
				
				$pdf->setColumnStyle(0, function($pdf) {
                    $pdf->setFillColor(250, 250, 135);
                });
				$pdf->setCellStyle(1, 2, function($pdf) {
                    $pdf->setFillColor(250, 155, 135);
                });
                   
			$pdf->closeTable();
		$pdf->closeCell();
	$pdf->closeRow();
$pdf->closeTable();
$pdf->output();

image-20200408123243207

样式的优先级

如果特定单元格受其行定义的回调影响,另一个应用于其列,第三个定义在特定单元格上,那么确定要应用哪个回调的优先级顺序是

  1. 首先,包装器将搜索为该特定单元格定义的回调。如果找到,则将应用它而不是其他回调。
  2. 如果没有为该单元格定义回调,则包装器将寻找为包含该单元格的行定义的回调。如果找到,则将使用它而不是其他回调。
  3. 如果没有为该单元格定义行回调,则包装器将尝试找到为该单元格定义的列回调。

包装器始终在执行特定样式回调之前,对行执行 setTableBodyStylesetTableHeaderStyle

其他方法

包装器上定义的 addStyle 方法允许我们使用别名定义包含打印配置的回调。我们可以稍后使用 useStyle 方法执行该回调。

<?php

use FPDFWrapper\Core\FPDFTableWrapper as Wrapper;

include '../vendor/autoload.php';

$pdf = new Wrapper();
$pdf->addPage();
$pdf->setFont('Arial', 'B', 9);
$pdf->addPage();
$pdf->addStyle('titleStyle', function($pdf) {
    $pdf->setFont('Arial', 'B', 15);
});
// ...later
$pdf->useStyle('titleStyle');
$pdf->cell(30, 'This is a title');

其他资源

您可以通过访问示例文件夹来激发您如何使用此工具的想法。