@Grapes(
@Grab(group='org.apache.pdfbox', module='pdfbox', version='2.0.8')
)
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.text.*
import java.awt.Rectangle
03 November 2017
En ete script vamos a tratar las siguientes capacidades de Groovy:
Incluir dependencias externas, en concreto PdfBox de Apache
Realizar bucles anidados de una forma sencilla
Generar mapas (key/value) al vuelo
Mediante este script y usando la librería PdfBox de Apache, dividiremos las páginas de un Pdf en áreas de tal forma que hagamos un "barrido" en cada una de ellas y podamos extraer el texto que se encuentre en las regiones. Al ir haciendo el "barrido" podremos identificar cada línea leída con una posición dentro de la página
Para la lectura del Pdf utilizaremos esta vez las librerías de Apache, PdfBox
@Grapes(
@Grab(group='org.apache.pdfbox', module='pdfbox', version='2.0.8')
)
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.text.*
import java.awt.Rectangle
margenright = 10 //(1)
PDDocument document = PDDocument.load(new URL(args[0]).bytes)
def pages = [:]
document.documentCatalog.pages.eachWithIndex { page , pageIndex->
def paragraphs = [:]
PDFTextStripperByArea stripper = new PDFTextStripperByArea(sortByPosition:true)
(0..42).each { //(2)
stripper.addRegion("$it", new Rectangle( margenright, it * 20, 1500, 20)); //(3)
}
stripper.extractRegions(page)
stripper.regions.eachWithIndex{ r, index->
def str = stripper.getTextForRegion(r)
if (str.trim().length() > 0)
paragraphs["$index"] = str.trim() //(4)
}
pages["$pageIndex"] = paragraphs //(5)
}
println pages
Puedes "jugar" a definir el margen derecho para afinar cuanto texto tomar desde la derecha.
Definimos 42 regiones de 20 pixeles, suficientes para un A4
Definimos un área de 1500x20 suficientes para leer el ancho de un A4
Para cada region que encuentra con texto la añadimos dinámicamente a un mapa creado para la página
Para cada página añadimos las áreas encontradas en un mapa creado para todo el documento.
@jmiguel en un afán minimalista nos comenta que el código anterior cumple su función en una sóla línea:
println new PDFTextStripper().getText(PDDocument.load(new URL(args[0]).bytes))//(1)
<1>Si el primer argumento es una ruta local a un PDF, comienzalo con file://
//tag::dependencies[]
@Grapes(
@Grab(group='org.apache.pdfbox', module='pdfbox', version='2.0.8')
)
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.text.*
import java.awt.Rectangle
//end::dependencies[]
//tag::sourceCode[]
margenright = 10 //(1)
PDDocument document = PDDocument.load(new URL(args[0]).bytes)
def pages = [:]
document.documentCatalog.pages.eachWithIndex { page , pageIndex->
def paragraphs = [:]
PDFTextStripperByArea stripper = new PDFTextStripperByArea(sortByPosition:true)
(0..42).each { //(2)
stripper.addRegion("$it", new Rectangle( margenright, it * 20, 1500, 20)); //(3)
}
stripper.extractRegions(page)
stripper.regions.eachWithIndex{ r, index->
def str = stripper.getTextForRegion(r)
if (str.trim().length() > 0)
paragraphs["$index"] = str.trim() //(4)
}
pages["$pageIndex"] = paragraphs //(5)
}
println pages
//end::sourceCode[]