jueves, 4 de noviembre de 2021

VBA: Extraer texto de PDF a Excel

Por suerte hoy en día existen diferentes formas de extraer el texto de un documento pdf: Power Automate, Power Query (leer algo más), programas de terceros, o incluso el mismo Adobe con su método de exportación...
Si bien, algunos de ellos, nos devuelven un texto algo liado y en muchas ocasiones 'bajarado o mezclado', difícil de trabajar.

Un alternativa más limpia de extraer el texto contenido en un pdf es empleando VBA.
Si bien necesitaremos tener acceso a las librerías de Adobe Acrobat (no Reader!!).

Así pues, lo primero que haremos, dentro del Editor de VBA es ir al menú de Herramientas > Referencias y activar la librería: Adobe Acrobat 10.0 Type Library (o la última versión que tengas).
Hecho esto, en el siguiente paso, añadiremos en un módulo estándar del editor de VBA el siguiente procedimiento:.

Sub ExtarerTexto_PDF()
Dim FilePath As String
FilePath = "F:\excelforo\FacturaEjemploPDF.pdf"

Dim strTextoPDF As String

Dim acPDoc As Acrobat.AcroPDDoc                 'para acceder al pdf
Dim acHiLst As Acrobat.AcroHiliteList           'selección de palabras..
Dim acPage As Acrobat.AcroPDPage                'identificará una página concreta dento del pdf
Dim acGTxt As Acrobat.AcroPDTextSelect          'para trabajar sobre el texto seleccionado

Set acPDoc = New Acrobat.AcroPDDoc
Set acHiLst = New Acrobat.AcroHiliteList

'indicamos el tamaño máximo de caracteres a recuperar
acHiLst.Add 0, 2500

'abrimos el documento pdf
acPDoc.Open FilePath

'NumPags = acPDoc.GetNumPages()         'por si quisieramos recorrer todas las páginas del doc

Set acPage = acPDoc.AcquirePage(0)    'sobre la página 1
'con CreateWordHilite seleccionamos todas las palabras del texto de la página
Set acGTxt = acPage.CreateWordHilite(acHiLst)
'si se ha seleccionado algo, lo cargaremos en nuestra variable strTexto
If Not acGTxt Is Nothing Then
    With acGTxt
        'recorriendo cada palabra...
        For j = 0 To .GetNumText - 1
            strTextoPDF = strTextoPDF & .GetText(j)
        Next j
    End With
End If

'Para trasladarlo a las celdas de nuestra hoja de cálculo
'partimos el texto obtenido por cada salto de línea identificada... (usamos la función SPLIT)
arrTexto = Split(strTextoPDF, vbCrLf)
'finalmente recorremos la matriz obtenida
'y trasladamos cada parte a una celda distinta
For fila = 1 To UBound(arrTexto)
    Hoja4.Range("A1").Offset(fila - 1, 0).Value = arrTexto(fila)
Next fila

'cerramos el documento
acPDoc.Close

'liberamos memoria
Set acPDoc = Nothing
Set acHiLst = Nothing
Set acPage = Nothing
Set acGTxt = Nothing
End Sub


El procedimiento, en general, realiza los siguientes pasos:
- Abre el pdf
- Indicamos sobre qué página (base 0) trabajaremos
- Tomamos el número de caracteres indicado en un paso previo (2500 en mi ejemplo)
- identificamos cada palabra y las recorremos componiendo un texto único
- finalmente separamos por saltos de línea existentes, y
- lo trasladamos a las celdas de nuestra hoja de cálculo.
Por ejemplo, en la siguiente imagen vemos el resultado de tratar el documento pdf de la derecha con nuestra macro.
VBA: Extraer texto de PDF a Excel


Algunos métodos, propiedades, objetos, etc... de la librería de Adobe empleados son:
.Open: muy simple. Abre el pdf en un nueva instancia.
AcroHiliteList.Add: En esencia crea una selección de texto a partir de una lista de caracteres y recuentos de caracteres en una página.
Después de crear nuestra lista destacada, podremos usar:
- PDPage.CreatePageHilite
-o PDPage.CreateWordHilite
dependiendo de si la lista creada se utiliza por caracteres o palabras, con el fin de crear una selección de texto de la lista.
.GetNumPages(): Nos dice el número total de páginas del documento pdf.
.AcquirePage(índice): Trabaja sobre la página concreta indicada del documento pdf.
.CreateWordHilite: Crea una selección de texto a partir de una lista de palabras en una sola página. La selección de texto puede luego configurarse como la selección actual usando AVDoc.SetTextSelection, y la vista se puede configurar para mostrar la selección usando AVDoc.ShowTextSelect.
.GetNumText: Obtiene el número de elementos de texto en una selección de texto. OJO, un 'elemento de texto' no es necesariamente una palabra; un elemento de texto consta de caracteres de la misma fuente, tamaño y estilo.
.GetText: Obtiene el texto del elemento especificado de una selección de texto previa (por ejemplo, la generada con .CreateWordHilite).

Como vemos el resultado obtenido es bastante limpio y fácil de trabajar... si bien se requiere un conocimiento elevado del entorno de Adobe para poder trabajar nuestros pdf's ;-)

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.