Si trabaja con archivos de formato de documento portátil (PDF), es posible que el usuario de su sistema desee extraer todo el texto de un archivo PDF. Por lo tanto, el usuario no tiene que seleccionar todo el texto de un PDF con el mouse y luego hacer algo con él, ya que puede automatizar esta acción con JavaScript en su navegador. Si no desea extraer el texto de un PDF en el navegador con JavaScript porque le importa la experiencia del usuario, es posible que desee hacerlo en el lado del servidor.
En este artículo, aprenderá cómo extraer el texto de un PDF en el lado del servidor con PHP en su proyecto Symfony 3 usando la biblioteca PDF Parser. Aunque existen otras bibliotecas que pueden ayudarlo a extraer el texto como pdf-to-text de @spatie , eso también funciona como un encanto, PDF Parser es una mejor manera de proceder, ya que es muy fácil de instalar, usar y no tiene alguna dependencia de software (si usa la biblioteca de pdf a texto por Spatie, entonces necesitará instalar pdftotext en su máquina ya que la biblioteca es un contenedor para la utilidad).
Empecemos !
1. Instalar PDF Parser
PdfParser es una impresionante biblioteca PHP independiente que proporciona varias herramientas para extraer datos de un archivo PDF. Algunas características del analizador de PDF son:
- Cargar / analizar objetos y encabezados
- Extraer metadatos (autor, descripción, ...)
- Extraer texto de páginas ordenadas
- Soporte de pdf comprimido
- Soporte de codificación de juego de caracteres Roman de MAC OS
- Manejo de codificación hexa y octal en secciones de texto
- Compatible con PSR-0 ( cargador automático )
- Compatible con PSR-1 ( estilo de código )
Incluso puede probar cómo funciona la biblioteca en esta página . La única limitación de este analizador es que no puede manejar documentos protegidos.
La forma preferida de instalar esta biblioteca es a través de Composer. Abra una nueva terminal, cambie al directorio de su proyecto y ejecute el siguiente comando en ella:
composer require smalot/pdfparser
Si no desea instalar nuevas bibliotecas directamente con la terminal en su proyecto, aún puede modificar el composer.json
archivo y agregar la dependencia manualmente:
{
"require": {
"smalot/pdfparser": "*"
}
}
Guarde los cambios y luego ejecútelos composer install
en su terminal. Una vez que finalice la instalación, podrá extraer el texto de un PDF fácilmente.
Si necesita más información sobre la biblioteca PDF Parser, visite el repositorio oficial en Github aquí o su sitio web aquí .
2. Extrayendo el texto
La extracción de texto con PDFParse es bastante fácil, solo necesita crear una instancia de la Smalot\PdfParser\Parser
clase y luego cargar el archivo PDF desde su ruta absoluta o relativa, el archivo analizado debe almacenarse en una variable y luego este objeto le permitirá manejar el PDF por páginas. Puede extraer directamente todo el texto de todo el PDF o por separado por páginas.
Consulte los siguientes ejemplos:
Nota
Como estamos trabajando con Symfony, podemos recuperar la ruta de la /web
carpeta en el proyecto usando $this->get('kernel')->getRootDir() . '/../web'
siempre que estés dentro de un controlador.
Extrae todo el texto de todas las páginas
Puede extraer todo el texto de un PDF utilizando el getText
método disponible en la instancia de PDF:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Importar la clase de analizador de PDF
*/
use Smalot\PdfParser\Parser;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// La ruta relativa o absoluta al archivo PDF
$pdfFilePath = $this->get('kernel')->getRootDir() . '/../web/example.pdf';
// Cree una instancia de PDFParser
$PDFParser = new Parser();
// Cree una instancia del PDF con el método parseFile del analizador
// este método espera como primer argumento la ruta al archivo PDF
$pdf = $PDFParser->parseFile($pdfFilePath);
// Extrae TODO el texto con el método getText
$text = $pdf->getText();
// Envía el texto como respuesta en el controlador.
return new Response($text);
}
}
Repetir cada página del PDF y extraer texto
Si desea manejar por separado cada página del PDF, puede iterar a través de la matriz de páginas que puede recuperar con el método getPages
de la instancia de PDF:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Importar la clase de analizador de PDF
*/
use Smalot\PdfParser\Parser;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// La ruta relativa o absoluta al archivo PDF
$pdfFilePath = $this->get('kernel')->getRootDir() . '/../web/example.pdf';
// Cree una instancia de PDFParser
$PDFParser = new Parser();
// Cree una instancia del PDF con el método parseFile del analizador
// este método espera como primer argumento la ruta al archivo PDF
$pdf = $PDFParser->parseFile($pdfFilePath);
// Recupere todas las páginas del archivo pdf.
$pages = $pdf->getPages();
// Recupere el número de páginas contando la matriz
$totalPages = count($pages);
// Establecer la página actual como la primera (un contador)
$currentPage = 1;
// Cree una variable vacía que almacenará el texto final
$text = "";
// Recorre cada página para extraer el texto
foreach ($pages as $page) {
// Agrega un separador HTML por página, por ejemplo, página 1/14
$text .= "<h3>Page $currentPage/$totalPages</h3> </br>";
// Concatenar el texto
$text .= $page->getText();
// Incrementar el contador de páginas
$currentPage++;
}
// Envía el texto como respuesta en el controlador.
return new Response($text);
}
}
Puede recuperar el texto de una página en formato de matriz (donde cada elemento de la matriz es una nueva línea) utilizando el getTextArray
método en lugar de getText
.
Extraiga el texto de una página específica en el PDF
Aunque no existe un método para acceder directamente a una página por su número, simplemente puede acceder a ella en la matriz de páginas con el getPages
método de la instancia PDF. Esta matriz está ordenada de la misma manera que el PDF (índice 0 igual a la página # 1 del PDF) para que pueda acceder a la página recuperándola de la matriz con el índice.
Tenga en cuenta que debe verificar si el índice (número de página) en la matriz de páginas existe; de ââlo contrario, obtendrá una excepción:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Importar la clase de analizador de PDF
*/
use Smalot\PdfParser\Parser;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// La ruta relativa o absoluta al archivo PDF
$pdfFilePath = $this->get('kernel')->getRootDir() . '/../web/example.pdf';
// Cree una instancia de PDFParser
$PDFParser = new Parser();
// Cree una instancia del PDF con el método parseFile del analizador
// este método espera como primer argumento la ruta al archivo PDF
$pdf = $PDFParser->parseFile($pdfFilePath);
// Obtén todas las páginas del PDF
$pages = $pdf->getPages();
// Extraigamos el texto de la página # 2 del PDF
$customPageNumber = 2;
// Si la página existe, extraiga el texto
// Como cada matriz comienza con 0, agregue +1
if(isset($pages[$customPageNumber + 1])){
// Como cada matriz comienza con 0, agregue +1
$pageNumberTwo = $pdf->getPages()[$customPageNumber + 1];
// Extrae el texto de la página # 2
$text = $pageNumberTwo->getText();
// Envía el texto como respuesta en el controlador.
return new Response($text);
}else{
return new Response("Lo sentimos, la página # $customPageNumber no existe");
}
}
}
Que te diviertas ❤️!
Conviertete en un programador más sociable