Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introdução

A Classe ReportPdfNative foi criada com o objetivo de abstrair a crição de relatórios em formato PDF de forma nativa, dispensando o uso de alguns filtros obrigatórios e permitindo que uma quantidade maior de dados seja renderizada, de maneira separada, dentro de um único documento PDF.

Objetivo e Vantagens

Relatórios criados de forma nativa dispensam a necessidade de uma conversão, todo relatório é construído utilizando apenas linguagem PHP e gerando um arquivo de extensão .PDF como produto final. O desenvolvimento do template é simples e objetivo, sendo necessário apenas configurar as células que irão compor as seções do documento (Cabeçalho, Rodapé e Conteúdo principal). O grande diferencial está na passibilidade de configurar cabeçalhos e rodapés dinâmicos para cada página gerada pelos dados do conteúdo principal.

Criar e Configurar Relatório

A criação do relatório dar-se à partir da instâcia de um objeto da classe ReportPdfNative, através de seu método createPdfNative(). A passagem da configuração do relatório dar-se pelo uso do método configGlobal().

/**
 * Cria objeto ReportPdfNative para construção de relatório em formato PDF.
 */
public static function createPdfNative(): self
/**
 * Define as configurações gerais do documento PDF a ser gerado.
 *
 * @param array	$configGlobal		Dados de configuração gerais do documento.
 *
 * $configGlobal = [
 * 		'title' => ?string = 'título do documento',
 * 		'file_name' => ?string = 'nome do arquivo',
 * 		'style' => [
 *       'title' => [
 *         'font_family' => ?string, nome da família da fonte
 *         'font_style' => ?string, estilo da fonte, 'B', 'I' ou 'U'
 *         'font_size' => ?int, tamanho da fonte
 *         'color' => ?string, cor do texto, em Hexadecimal
 *         'fill' => ?string, cor de preenchimento da célula, em Hexadecimal
 *       ],
 *       'subtitle' => [
 *         'font_family' => ?string, nome da família da fonte
 *         'font_style' => ?string, estilo da fonte, 'B', 'I' ou 'U'
 *         'font_size' => ?int, tamanho da fonte
 *         'color' => ?string, cor do texto, em Hexadecimal
 *         'fill' => ?string, cor de preenchimento da célula, em Hexadecimal
 *       ],
 *       'text' => [
 *         'font_family' => ?string, nome da família da fonte
 *         'font_style' => ?string, estilo da fonte, 'B', 'I' ou 'U'
 *         'font_size' => ?int, tamanho da fonte
 *         'color' => ?string, cor do texto, em Hexadecimal
 *         'fill' => ?string, cor de preenchimento da célula, em Hexadecimal
 *       ],
 *       'array' => [
 *         'font_family' => ?string, nome da família da fonte
 *         'font_style' => ?string, estilo da fonte, 'B', 'I' ou 'U'
 *         'font_size' => ?int, tamanho da fonte
 *         'color' => ?string, cor do texto, em Hexadecimal
 *         'fill' => ?string, cor de preenchimento da célula, em Hexadecimal
 *       ],
 *     ],
 *		'defaultCellHeight'=> ?int = 'altura padrão das células'
 * ];
 */
public function globalSettings(array $configGlobal): void
/**
* Sinaliza o final da configuração de um relatório pdf nativo.
*
* Obs: Quando usado em um loop, sinalizará o fim de relatório e início do próximo.
*/
public function end(): void

Manipulação de Dados

Os dados no relatório são inseridos através do conceito de células. As células são construídas de forma simples, onde deve-se informar sua largura, seu conteúdo, tipo do conteúdo que está sendo passado e seu alinhamento horizontal dentro da célula.

Existem métodos específicos para inserir células nos distintos elementos do documento; por elementos distintos entende-se o cabeçalho (header), o rodapé (footer), e o conteúdo principal (body).

/**
 * Insere uma célula no elemento cabeçalho (header) do arquivo PDF.
 *
 * @param int          $w           Largura da célula em "mm"
 * @param array|string $content     Valor do conteúdo a ser inserido.
 * @param string       $typeContent Identifica o tipo do conteúdo passado à célula
 * @param string       $hAlign      Alinhamento horizontal do texto. 'AlignH::CENTER', 'AlignH::LEFT', 'AlignH::RIGHT'
 * @param string       $vAlign      Alinhamento vertical do texto. 'AlignV::TOP', 'AlignV::CENTER', 'AlignV::BOTTOM'
 */
public function headerCell(int $w, array|string $content, $typeContent, string $hAlign, string $vAlign): self
/**
 * Insere uma célula no elemento rodapé (footer) do arquivo PDF.
 *
 * @param int          $w           Largura da célula em "mm"
 * @param array|string $content     Valor do conteúdo a ser inserido.
 * @param string       $typeContent Identifica o tipo do conteúdo passado à célula
 * @param string       $hAlign      Alinhamento horizontal do texto. 'AlignH::CENTER', 'AlignH::LEFT', 'AlignH::RIGHT'
 * @param string       $vAlign      Alinhamento vertical do texto. 'AlignV::TOP', 'AlignV::CENTER', 'AlignV::BOTTOM'
 */
public function footerCell(int $w, array|string $content, string $typeContent, string $hAlign, string $vAlign): self
/**
 * Insere uma célula no conteúdo principal do arquivo PDF.
 *
 * @param int          $w           largura da célula em "mm"
 * @param array|string $content     conteúdo a ser inserido na célula
 * @param string       $typeContent identifica o tipo do conteúdo para sinalizar qual formatação será aplicada a célula
 * @param string       $hAlign      Alinhamento horizontal do texto. 'AlignH::CENTER', 'AlignH::LEFT', 'AlignH::RIGHT'.
 * @param string       $vAlign      Alinhamento vertical do texto. 'AlignV::TOP', 'AlignV::CENTER', 'AlignV::BOTTOM'.
 */
public function bodyCell(int $w, array|string $content, string $typeContent, string $hAlign, string $vAlign): self

<!> Para preencher os parâmetros que identificam o tipo do conteúdo ($typeContent) e o alinhamento ($align) de uma célula, deve-se utilizar constantes previamente definidas. Ver Referências > Constantes.

<!> Para o parâmetro que define a largura ($w), admite-se um documento do tipo folha A4 com largura máxima de 190mm. Utilize esse valor como referência durante o cálculo do somatório das larguras da células configuradas para criação de uma nova linha.

Formatação de Dados

Durante a montagem do relatório alguns métodos podem ser utilizados para facilitar a manipulação das células, personalização e formatação correta do documento.

 /**
 * Modifica a altura da próxima célula a ser criada.
 *
 * @param int $h Altura da próxima célula a ser criada.
 */
 public function cellHeight(int $h = null): self
/**
 * Finaliza a configuração de uma linha, definindo a linha seguinte do template como local de inserção da próxima célula.
 */
public function nextLine(): self
/**
 * Insere uma quebra de linha do documento, construindo um espaço vazio com a altura desejada.
 *
 * @param int|void	$h		Altura da quebra em "mm". 
 *												Quando vazio/null, o valor será definido pela altura padrão da célula ($configGlobal['defaultCellHeight']).
 */
public function jumpLine(int $h = null): self
/**
 * Insere ao final de cada página, no elemento rodapé (footer), o título do documento informado nas configurações gerais,
 * e, um contador de páginas informando a 'página atual/total de páginas' do relatório, que pode ser desabilitado.
 *
 * @param bool $hasNumbPage    Indica se o contador de páginas deve ser exibido ou não. Possue 'true' como valor default.
 * @param bool $hasTitlePage   Indica se o título do documento deve ser exibido ou não. Possue 'true' como valor default.
 */
public function footerInfo(bool $hasNumbPage = true, bool $hasTitlePage = true): self
/**
 * Ignora a quebra automática do conteúdo quando este ultrapassa a largura da célula.
 */
public function ignoreTextBreak(): self
/**
 * Altera o tamanho da fonte do texto.
 *
 * @param int    $size      Tamanho da fonte.
 */
public function fontSize(int $size): self
/**
 * Altera o estilo do texto
 * Valores possívels: B = BOLD, I = ITALIC, U = UNDERLINE.
 *
 * @param string $style     Estilo do texto.
 */
public function fontStyle(string $style): self
/**
* Altera a cor do texto.
*
* @param string $color cor do texto, valor em hexadecimal
*/
public function textColor(string $color): self
/**
* Altera a cor de preenchimento da célula.
*
* @param string $color cor de preenchimento da célula, valor em hexadecimal
*/
public function fillColor(string $color): self
/**
 * Permite que uma linha contenha um conjuto de células, ou, 'sub-linhas'.
 * Funciona de forma semelhante a um 'rowspan'.
 *
 * @param int $numbSplit número de divisões, ou, sub-linhas a serem inseridas
 */
public function rowSplit(int $numbSplit): self
/**
 * Indica a quebra de linha dentro 'rowSplit', ou, o fim de uma 'sub-linha'.
 */
public function split(): self
/**
* Encerra as configuraçõs do template para um relatório. 
* Utilizar após definir todas as células dos elementos do documento (Header, Footer e Body).
*/
public function end()

<!> Sempre utilize o método 'cellHeight()' antes de criar uma célula do tipo 'IMG_BLOB', de maneira a garantir a altura e a largura da imagem renderizada.

<!> O método 'footerInfo()' deve ser, obrigatoriamente, inserido após todas as células do elemento rodapé (Footer) serem configuradas, pois, ele indica o fim da configuração do elemento rodapé.

<!> Ao usar o método 'rowSplit()', o valor passado no parâmetro $numbSplit deve ser igual ao número de vezes em que o método 'split()' aparece no template, de forma a indicar corretamente o fim do split criado.

Referências

Constantes

/** 
 * Para definir o tipo do conteúdo, use: 
 */
 Format::TEXT				# Célula contendo uma string configurada em $configGlobal['style']['text'] e que não possui cor de preenchimento padrão. 
 Format::TITLE 			# Célula contendo uma string configurada em $configGlobal['style']['title']
 Format::SUBTITLE		# Célula contendo uma string configurada em $configGlobal['style']['subtitle']
 Format::ARRAY			 # Célula contendo um Array de dados configurada em $configGlobal['style']['array'], onde cada item do array ocupará 'uma linha' dentro de uma mesma célula.
 Format::IMG_BLOB		# Célula que recebe uma string contendo o binário de uma imagem, aceitará binários que estão ou não em base64.
 Format::LOGO				# Célula que recebe uma string contendo o nome do arquivo de imagem da logo da empresa armazenado no diretório da aplicação.
/**
 * Para definir o alimento horizontal, use:
 */
 AlignH::CENTER			# Alinhar ao centro.
 AlignH::LEFT				# Alinhar a borda esquerda.
 AlignH::RIGHT			# Alinhar a borda direita.
/**
 * Para definir o alimento vertical, use:
 */
 AlignV::CENTER			# Alinhar ao centro.
 AlignV::TOP				# Alinhar a borda superior.
 AlignV::BOTTOM			# Alinhar a borda inferior.

<!> A lista completa com o nome das imagem de logo das empresas disponíveis no diretório da aplicação, em caso de uso do Format::LOGO, encontra-se nesta documentação em Referências > Logo Empresas.

<!> O parâmetro referente ao alinhamento não se aplica ao conteúdo do tipo imagem, neste caso, é possível apenas não passar este parâmetro.

<!> Para passar os dados para dentro do array das céluldas do tipo ARRAY, é necessário criar uma variável do tipo vetor associativo (array chave/valor), com as keys ‘value' e ‘style’, sendo a primeira obrigatória contendo a string/variável a ser renderizada, e, a segunda key será opcional e irá conter a personalização do conteúdo em questão, passando as configs conforme o padrão 'style' da $configGeral['style']['...'].

Logo Empresas

Lista dos nomes dos arquivos das logos das empresas disponíveis diretamente no diretório do NFS_CORE para utilizar nas células do tipo 'LOGO'.

  • agro_baggio.png :: Agro Baggio John Deere
  • bracos.png :: Braços Construções e Instalações de Gás
  • camargocorrea.png :: Construtora Camargo Corrêa
  • camargocorreainfra.png :: Camargo Corrêa Infra
  • case.png :: Case IH Agriculture
  • comgev.png :: Consórcio COMGEV
  • comid.png :: Comid John Deere
  • concremat.jpg :: Concremat Soluções Integradas de Engenharia
  • concremat.png :: Concremat Manutenção
  • eldorado.png :: Eldorado Brasil
  • enasa.png :: Enesa
  • energas.png :: Energás
  • fibria.png :: Fibria
  • fibria.jpg :: Fibria
  • gas_natural_fenosa.gif :: Gas Natural Fenosa
  • gbec.png :: Grupo Transtusa GBEC
  • ge.png :: GE Brasil
  • grupo_agis_branco.jpg :: Grupo AGIS
  • grupoagis.png :: Grupo AGIS
  • invepar.png :: Invepar Rodovias
  • jalles.png :: Jalles Machado
  • jd.png :: John Deere
  • jm.png :: Construtora JM Ltda
  • john_deere64.png :: John Deere
  • lavoro.png :: Lavoro John Deere
  • meridional.png :: Meridional John Deere
  • new_holland.png :: New Holland Agriculture
  • nip.png :: NIPBR Nipcable
  • novatec.png :: Novatec
  • portonovo.png :: Concessionária Porto Novo
  • primavera.jpg :: Primavera John Deere
  • real_guindaste.png :: Real Guindastes e Equipamentos
  • real.png :: Real Guindastes e Equipamentos
  • santa_fe.png :: Usina Santa Fé
  • santa_fe64.png :: Usina Santa Fé
  • socicam.jpg :: Socicam
  • suzano.png :: Suzano Papel e Celulose
  • tamoios.png :: Tamoios
  • via040.png :: VIA040

Dicas e Conceitos Importantes

Agumas DICAS e CONCEITOS para facilitar o processo de montagem do template que dará origem ao relatório pdf.

<!> Na construção do template é possível utilizar todas as funções PHP nativas. Faça uso de estruturas condicionais e de laços de repetição para manipular seus dados conforme necessário.

<!> Utilize do encadeamento de métodos. Crie as células de uma única linha em uma única chamada, facilitando a organização do código. Lembre-se de utilizar o método nextLine() para informar o fim daquela linha.

<!> A ordem de configuração é importante. É essencial que seja definido primeiro os elementos HEADER (cabeçalho) e FOOTER (rodapé), pois eles delimitam o espaço máximo disponível para renderizar corretamente o BODY (conteúdo principal).

<!> Os relatórios nativos são renderizados em papel A4 297x210mm, devido aos 10mm de margem configurado por padrão, tem-se 190mm de máxima largura (ou soma de larguras, em caso de diversas células) para uma única linha.

<!> A quebra de páginas ocorre de forma automática com base no tamanho do conteúdo da próxima linha. Sempre será inserido um cabeçalho de um rodapé para cada página criada.

<!> Utilize das funções isset() e empty() para validação de dados sempre que possível. Evite passagem de valores NULL ou VAZIOS para o CORE, isso pode afetar o desempenho e a formatação do seu documento PDF.

Casos de Uso

Criação, Preenchimento e Formatação - Exemplo Detalhado

Abaixo a construção de um relatório pdf baseado em um template real (Brasfels-dev.h -> EFL=[1-1-6] -> "relatorio_inspecao").

/* CONFIG SECTION */
$pdfNative = ReportPdfNative::createPdfNative();
$pdfNative->globalSettings([
	'title' => 'Inspeção / Suportes',
	'file_name' => $templateData['report_name'],
	'style' => [
		'title' => [
			'font_family' => 'Arial',
			'font_style' => 'B',
			'font_size' => 8,
			'color' => '#000000',
			'fill' => '#cccccc'
		],
		'subtitle' => [
			'font_family' => 'Arial',
			'font_style' => 'B',
			'font_size' => 7,
			'color' => '#000000',
			'fill' => '#f2f2f2'
		],
		'text' => [
			'font_family' => 'Arial',
			'font_style' => '',
			'font_size' => 7,
			'color' => '#000000',
			'fill' => '#ffffff'
		],
		'array' => [
			'font_family' => 'Arial',
			'font_style' => '',
			'font_size' => 7,
			'color' => '#000000',
			'fill' => '#ffffff'
		],
	],
	'defaultCellHeight'=> 5
]);
			
foreach($templateData['dados_check'] as $check) {
	$dados_suporte_rec = $templateData['dados_eng_suporte'][$check['SEQ_DB']][0] ?? null;
	/* HEADER SECTION */
	$pdfNative->cellHeight(20)->headerCell(70, $templateData['images']['logo']['image_base64'], Format::IMG_BLOB)
		->fontSize(12)->fontStyle('B')->headerCell(120, $check['CHECK_QUESTIONARIO'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->headerCell(10, 'Nº', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->headerCell(40, $check['NUMERO_RELATORIO'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->headerCell(20, 'OBRA/ SITE:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->headerCell(40, $check['OBRA'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->headerCell(20, 'DATA/ DATE:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->headerCell(60, $check['INI_DH'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();		
	$pdfNative->headerCell(30, 'CLIENTE/ COMPANY:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->headerCell(60, $check['CLIENTE'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->headerCell(40, 'PROJETO/ PROJECT:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->headerCell(60, $check['PROJETO'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	
	/* FOOTER SECTION */
	$pdfNative->footerCell(190, 'ASSINATURA/ SIGNATURE', Format::TITLE, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->footerCell(50, 'INSPETOR/ INSPECTOR', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->footerCell(50, 'SUPERVISOR/ SUPERVISOR', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->footerCell(50, 'CLASSIFICADORA/ THIRD PART', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->footerCell(40, 'CLIENTE/ CLIENT', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->footerCell(50, 'Data: '.$check['DATA_INSPECAO'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->footerCell(50, 'Data: '.$check['DATA_APROVACAO'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->footerCell(50, 'Data: '.$check['DATA_APROVACAO_FABRICANTE'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->footerCell(40, 'Data: '.$check['DATA_APROVACAO_CLIENTE'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	
	$preencheu_usuario_aprovacao = 'NA';
	if(isset($check['USUARIO_APROVACAO']) && !empty($check['USUARIO_APROVACAO'])){
		$preencheu_usuario_aprovacao = '';
	}
	$preencheu_usuario_aprovacao_fabricante = 'NA';
	if(isset($check['USUARIO_APROVACAO_FABRICANTE']) && !empty($check['USUARIO_APROVACAO_FABRICANTE'])){
		$preencheu_usuario_aprovacao_fabricante = '';
	}
	$preencheu_usuario_aprovacao_cliente = 'NA';
	if(isset($check['USUARIO_APROVACAO_CLIENTE']) && !empty($check['USUARIO_APROVACAO_CLIENTE'])){
		$preencheu_usuario_aprovacao_cliente = '';
	}
	
	$pdfNative->cellHeight(20)->footerCell(50, $check['ASSINATURA_INSPETOR'], Format::IMG_BLOB)
		->footerCell(50, $preencheu_usuario_aprovacao, Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->footerCell(50, $preencheu_usuario_aprovacao_fabricante, Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->footerCell(40, $preencheu_usuario_aprovacao_cliente, Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	
	$array1 = [];
		if (isset($check['EFETIVO_FUNCIONARIO'])) {
			$data = [
				'value' => $check['EFETIVO_FUNCIONARIO']
			];
			array_push($array1, $value);
		}
		if (isset($check['EFETIVO_FUNCAO'])) {
			$data = [ 
				'value'=> $check['EFETIVO_FUNCAO']
			];
			array_push($array1, $value);
		}
		if (isset($check['CERTIFICACAO_INSPETOR'])) {
			$data = [ 
				'value'=> 'Certificações (SNCC, IS): '.$check['CERTIFICACAO_INSPETOR']
			];
			array_push($array1, $value);
		}
		if (isset($check['CRACHA_FUNCIONARIO'])) {
			$data = [ 
				'value'=> 'Matrícula: '.$check['CRACHA_FUNCIONARIO']
			];
			array_push($array1, $value);
		}
		$data = [ 
			'value'=> 'Estaleiro BrasFELS Ltda.'
		];
		array_push($array1, $value);
	
	$array2 = [];
		if (isset($check['NOME'])) {
			$data = [ 
				'value'=> $check['NOME']
			];
			array_push($array2, $data);
		}
		if (isset($check['CARGO'])) {
			$data = [ 
				'value'=> $check['CARGO']
			];
			array_push($array2, $data);
		}
		if (isset($check['USUARIO_APROVACAO'])) {
			$data = [ 
				'value'=> $check['USUARIO_APROVACAO']
			];
			array_push($array2, $data);
		}
		if (isset($check['MATRICULA'])) {
			$data = [ 
				'value'=> 'Matrícula: '.$check['MATRICULA']
			];
			array_push($array2, $data);
		}	
		if(isset($check['USUARIO_APROVACAO']) && !empty($check['USUARIO_APROVACAO'])){
			$data = [ 
				'value'=> 'Estaleiro BrasFELS Ltda.'
			];
			array_push($array2, $data);
			
			$data = [ 
				'value'=> 'Aprovado eletronicamente'
			];
			array_push($array2, $data);
		}
	
	$array3 = [];
		if (isset($check['NOME_FABRICANTE'])) {
			$data = [ 
				'value'=> $check['NOME_FABRICANTE']
			];
			array_push($array3, $data);
		}
		if (isset($check['CARGO_FABRICANTE'])) {
			$data = [ 
				'value'=> $check['CARGO_FABRICANTE']
			];
			array_push($array3, $data);
		}
		if (isset($check['USUARIO_APROVACAO_FABRICANTE'])) {
			$data = [ 
				'value'=> $check['USUARIO_APROVACAO_FABRICANTE']
			];
			array_push($array3, $data);
		}
		if(isset($check['MATRICULA_FABRICANTE'])){
			$data = [ 
				'value'=> 'Matrícula: '.$check['MATRICULA_FABRICANTE']
			];
			array_push($array3, $data);
		}
		if(isset($check['USUARIO_APROVACAO_FABRICANTE']) && !empty($check['USUARIO_APROVACAO_FABRICANTE'])){
			$data = [ 
				'value'=> 'Estaleiro BrasFELS Ltda.'
			];
			array_push($array3, $data);
			
			$data = [ 
				'value'=> 'Aprovado eletronicamente'
			];
			array_push($array3, $data);
		}

	$array4 = [];
		if (isset($check['NOME_CLIENTE'])) {
			$data = [ 
				'value'=> $check['NOME_CLIENTE']
			];
			array_push($array4, $data);
		}
		if (isset($check['CARGO_CLIENTE'])) {
			$data = [ 
				'value'=> $check['CARGO_CLIENTE']
			];
			array_push($array4, $data);
		}
		if (isset($check['USUARIO_APROVACAO_CLIENTE'])) {
			$data = [ 
				'value'=> $check['USUARIO_APROVACAO_CLIENTE']
			];
			array_push($array4, $data);
		}
		if(isset($check['MATRICULA_CLIENTE'])){
			$data = [ 
				'value'=> 'Matrícula: '.$check['MATRICULA_CLIENTE']
			];
			array_push($array4, $data);
		}
		if(isset($check['USUARIO_APROVACAO_CLIENTE']) && !empty($check['USUARIO_APROVACAO_CLIENTE'])){
			$data = [ 
				'value'=> 'Estaleiro BrasFELS Ltda.'
			];
			array_push($array4, $data);
			
			$data = [ 
				'value'=> 'Aprovado eletronicamente'
			];
			array_push($array4, $data);
		}
	
	$pdfNative->footerCell(50, $array1, Format::ARRAY, AlignH::CENTER, AlignV::CENTER)
		->footerCell(50, $array2, Format::ARRAY, AlignH::CENTER, AlignV::CENTER)
		->footerCell(50, $array3, Format::ARRAY, AlignH::CENTER, AlignV::CENTER)
		->footerCell(40, $array4, Format::ARRAY, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	
	$pdfNative->footerInfo(true,false);
	
	/* BODY SECTION */
	$pdfNative->bodyCell(20, 'Nº MÓDULO/ MODULE', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, 'Nº PAINEL/ PANEL', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, 'DISCIPLINA/ DISCIPLINE', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(30, 'TIPO/ TYPE', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, 'LOCAL/ LOCAL', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, 'Requer Inspeção Oficial?', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->nextLine();

	$pdfNative->bodyCell(20, $dados_suporte_rec["MODULO"], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, '---', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, $dados_suporte_rec["DISCIPLINA"], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(30, 'Montagem', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, $dados_suporte_rec["LOCAL_NOME"], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, '', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
		
	$desenho_desc = $dados_suporte_rec["DESENHO"] ?? '';
	$rev_desc = !empty($dados_suporte_rec["REV"]) ? ' / ' .$dados_suporte_rec["REV"] : '';
	
	$desenho_rev = $desenho_desc.$rev_desc;	
	$pdfNative->bodyCell(190, 'Nº DESENHO:/ DRAWING:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
	->nextLine();
	$pdfNative->bodyCell(190, $desenho_rev, Format::TEXT, AlignH::LEFT, AlignV::CENTER)
	->nextLine();
	
	$pdfNative->bodyCell(20, 'CV./ FR.', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, 'até CV', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(20, 'EL', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, 'até EL', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(20, 'LONG:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, 'até LONG:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(20, 'BOMBORDO (PORT)', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(75, 'BORESTE (STBD)', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, 'VANTE (FWD)', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(35, 'RÉ (AFT)', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, 'CENTRO (CENTER)', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(20, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(75, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(20, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(35, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->bodyCell(40, '-', Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();	
				
	$tipo_produto_desc = !empty($dados_suporte_rec["TIPO_PRODUTO"]) ? 'SUPORTE PARA ' .$dados_suporte_rec["TIPO_PRODUTO"] : '';
	$pdfNative->bodyCell(190, 'DESCRIÇÃO DA SOLICITAÇÃO:/ DESCRIPTION OF THE REQUEST:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->nextLine();	
	$pdfNative->bodyCell(190, $tipo_produto_desc, Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	
	$qtde_total = '';
	$peso_total = '';
	foreach($templateData['dados_eng_suporte'] as $eng_suporte) {
		if ($eng_suporte['CHECK_APT_SEQ_DB'] == $check['SEQ_DB']) {
			$qtde_total = $qtde_total + $eng_suporte['QTDE_1'];
			$peso_total = $peso_total + $eng_suporte['PESO_UNIT_1'];
		}
	}
	if ($qtde_total != '') {
		$qtde_total = $qtde_total.' Un';
	}
	if ($peso_total != '') {
		$peso_total = $peso_total.' Kg';
	}
	$pdfNative->bodyCell(40, 'QTDE. TOTAL:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(150, $qtde_total, Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(40, 'PESO TOTAL:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(150, $peso_total, Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(190, 'EM ANEXO/ ATTACHED.', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(40, 'SINETE RAÍZ: ROOT SIGNET:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(150, '-', Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(40, 'SINETE ENCH/ ACAB: FINISH SIGNET:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(150, $check['NUMERO_SINETE'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(40, 'EQUIPAMENTOS INSPEÇÕES:', Format::SUBTITLE, AlignH::LEFT, AlignV::CENTER)
		->bodyCell(150, '-', Format::TEXT, AlignH::LEFT, AlignV::CENTER)
		->nextLine();
		
	
	$pdfNative->jumpLine();	
	
	if ( isset($templateData['dados_check_grupo'][$check['SEQ_DB_DEVICE']]) ) {
		foreach($templateData['dados_check_grupo'][$check['SEQ_DB_DEVICE']] as $grupo) {
			$pdfNative->bodyCell(190, $grupo["DESCRICAO"], Format::TITLE, AlignH::CENTER, AlignV::CENTER)
				->nextLine();

			$pdfNative->bodyCell(50, 'QUESTOES/ QUESTIONS', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
				->bodyCell(30, 'RESPOSTA/ ANSWER', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
				->bodyCell(50, 'OBSERVAÇÃO/ OBSERVATION', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
				->bodyCell(60, 'FOTO/ PHOTO', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
				->nextLine();

			foreach($templateData['dados_check_resposta'][$grupo['CHAVE']] as $resposta) {
				$h = isset($resposta['FOTO']) ? 100 : null;
				$pdfNative->bodyCell(50, $resposta['CHECK_QUESTAO'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
					->bodyCell(30, $resposta['CHECK_TIPO_RESPOSTA'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
					->bodyCell(50, $resposta['OBSERVACAO'], Format::TEXT, AlignH::LEFT, AlignV::CENTER)
					->cellHeight($h)->bodyCell(60, $resposta['FOTO'], Format::IMG_BLOB)
					->nextLine();
			}
		}
		$pdfNative->jumpLine();
	}
	
	$pdfNative->bodyCell(190, 'OBSERVAÇÃO/ OBSERVATION', Format::TITLE, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	$pdfNative->bodyCell(190, $check["OBSERVACAO"], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
		->nextLine();
	
	if ( isset($check["MOTIVO_REPROVACAO"]) && !empty($check["MOTIVO_REPROVACAO"])) {
		$pdfNative->bodyCell(190, $check["MOTIVO_REPROVACAO"], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
			->nextLine();
	}

	if ( isset($templateData['dados_eng_suporte'][$check['SEQ_DB']]) ) {
		$pdfNative->jumpLine();
		$pdfNative->bodyCell(190, 'ANEXO/ ATTACHED', Format::TITLE, AlignH::CENTER, AlignV::CENTER)
			->nextLine();
			
		$pdfNative->bodyCell(30, 'TAG', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
			->bodyCell(40, 'Material', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)		
			->bodyCell(30, 'Tipo de Produto', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)		
			->bodyCell(30, 'Elev. Projeto', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
			->bodyCell(30, 'Qtde. Unit.', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
			->bodyCell(30, 'Peso Unit.', Format::SUBTITLE, AlignH::CENTER, AlignV::CENTER)
			->nextLine();
		
		foreach($templateData['dados_eng_suporte'][$check['SEQ_DB']] as $anexo) {
		
			$pdfNative->bodyCell(30, $anexo['TAG'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)			
				->bodyCell(40, $anexo['MATERIAL'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
				->bodyCell(30, $anexo['TIPO_PRODUTO'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)		
				->bodyCell(30, $anexo['ELEV_PROJETO'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
				->bodyCell(30, $anexo['QTDE_1'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
				->bodyCell(30, $anexo['PESO_UNIT_1'], Format::TEXT, AlignH::CENTER, AlignV::CENTER)
				->nextLine();
		}
	}
	/*END SECTION*/
	$pdfNative->end();
}

<!> Atentar-se as colunas 'TEMPLATE', onde o relaório deve ser descrito por completo seguindo a ordem de preenchimento conforme exposto nesse guia, e, a coluna 'EXPORT_OPTION' a qual deve explicitar o formato de exportação como "pdfNative".