tabulapdf / tabula-java

Extract tables from PDF files
MIT License
1.82k stars 424 forks source link

Algunas dudas. #6

Open aosi87 opened 9 years ago

aosi87 commented 9 years ago

Hola, disculpa que los tenga olvidados, sin embargo he estado algo atareado con otros proyectos, en este fin de semana (MARATONICO) me decidí probar la implementan y sinergia con mi proyecto, y note lo siguiente

1.- Como puedo decirle en linea de comando que use como método de extracción la decisión, ya que en el HOW TO, y README, solo aparecen los métodos "Hoja de calculo", y "Basico". (Opciones -r, -n), pero entonces para que tenemos la opción --guess ó -g ya que se utilizaría solo en el caso de seleccionar el método básico.

2.- Otro detalle estoy recibiendo apuntadores nulos al leer este documento PDF y me da estos errores y se ciclan ya que entiende que hay mas paginas en el documento, pero no puede obtenerlas(eso imagino).

nov 10, 2014 5:39:54 AM org.apache.pdfbox.util.PDFStreamEngine processOperator
INFORMACIÓN: unsupported/disabled operation: BDC
nov 10, 2014 5:39:59 AM org.apache.pdfbox.util.PDFStreamEngine processOperator
INFORMACIÓN: unsupported/disabled operation: EMC
nov 10, 2014 5:43:35 AM org.apache.pdfbox.util.PDFStreamEngine processOperator
ADVERTENCIA: java.lang.NullPointerException
java.lang.NullPointerException
    at org.nerdpower.tabula.ObjectExtractor$PointComparator.compare(ObjectExtractor.java:36)
    at org.nerdpower.tabula.ObjectExtractor.strokeOrFillPath(ObjectExtractor.java:249)
    at org.nerdpower.tabula.ObjectExtractor.strokePath(ObjectExtractor.java:270)
    at org.apache.pdfbox.util.operator.pagedrawer.StrokePath.process(StrokePath.java:47)
    at org.apache.pdfbox.util.PDFStreamEngine.processOperator(PDFStreamEngine.java:557)
    at org.apache.pdfbox.util.PDFStreamEngine.processSubStream(PDFStreamEngine.java:268)
    at org.apache.pdfbox.util.PDFStreamEngine.processSubStream(PDFStreamEngine.java:235)
    at org.apache.pdfbox.util.PDFStreamEngine.processStream(PDFStreamEngine.java:215)
    at org.nerdpower.tabula.ObjectExtractor.drawPage(ObjectExtractor.java:149)
    at org.nerdpower.tabula.ObjectExtractor.extractPage(ObjectExtractor.java:108)
    at org.nerdpower.tabula.PageIterator.next(PageIterator.java:29)
    at controller.Tabula.extractTables(Tabula.java:153)
    at controller.Tabula.<init>(Tabula.java:76)
    at controller.Tabula.main(Tabula.java:361)

Lo anterior ocurre en la siguientes lineas de código:

PageIterator pageIterator = pages == null ? oe.extract() : oe.extract(pages);
            Page page;
            List<Table> tables = new ArrayList<Table>();

            **while (pageIterator.hasNext()) {**
                page = pageIterator.next();

                if (area != null) {
                    page = page.getArea(area);
                }

                if (method == ExtractionMethod.DECIDE) {
                    method = spreadsheetExtractor.isTabular(page) ? ExtractionMethod.SPREADSHEET : ExtractionMethod.BASIC;
                }

Como no soy experto, y con este proyecto es la primera vez que sufro con PDFs, no logro entender por que me retorna null si el PDF contiene paginas y datos.

3.- Ya para finalizar, como puedo interceptar la lectura de datos, es decir entiendo que la variable o arreglo de tablas se llena al extraer por pagina.tables.addAll(spreadsheetExtractor.extract(page)); pero al momento de trabajar con la lista de tablas no comprendo la estructura de datos dentro de ella, es decir salio como tabla, como una lista, por fila etc. y pues con la falta de documentación si se me ha complicado un poco seguirte el paso.

De antemano muchas gracias y saludos, espero no importunarte.

Éxito.

jazzido commented 9 years ago

Hola, gracias por tu reporte.

Al parecer, hay un error en ObjectExtractor, en particular en los métodos que analizan los paths (líneas) contenidas en una página. Necesitaría saber en qué página sucede este error, así puedo depurarlo.

Saludos,

M

jazzido commented 9 years ago

Acabo de probar la extracción de una tabla del PDF que adjuntaste usando la aplicación incluída con Tabula. Invocándola de esta manera:

java -jar target/tabula-extractor-0.7.4-SNAPSHOT-jar-with-dependencies.jar -p 11 -a 72.12,96.17,417.47,714.72 "Altman Exclusive Dealer Confidential Price List Jan  2014.pdf"

obtengo el siguiente resultado:

"Item ","Description ","List ","Disc. ","Net ",MAP $
"MF-** ","75 Watt Micro Flood  MR-16 Style w/ Male Edison Connector (4 lbs.) ","$178.00 ","50% ","$89.00 ",$133.50
"MF-220-** ","208-240 Volt version of Micro Flood  (4 lbs.) ","$185.00 ","50% ","$92.50 ",$138.75
"MF-277-** ","277 Volt Version of Micro Flood  (4 lbs.) ","$185.00 ","50% ","$92.50 ",$138.75
"MFY-** ","75 Watt Micro Flood  MR-16 Style for Smart Track (4 lbs.) ","P.O.A ",,"P.O.A ",P.O.A.
"** (Finish Color) ","Add the following code for Housing Color: BK=Black  WH= White  SL= Silver  ",,,,
Available Lamps,,,,,
"90-EYC ","75W, MR-16, 12V, 3050K, 42°, 4000hr. ","$10.00 ","50% ","$5.00 ",$7.50
"90-EYF ","75W, MR-16, 12V, 3050K, 14°, 4000hr. ","$12.00 ","50% ","$6.00 ",$9.00
"MF3-*-** ","25w LED (non dimmable) Micro Flood with 6' cord and molded edison conn. ","$425.00 ","50% ","$212.50 ",$318.75
"MF3-*-**-DMX ","25w LED (DMX dimmable) Micro Flood with molded edison and 5pin DMX tails ","$710.00 ","50% ","$355.00 ",$532.50
...

Luce bastante bien.

aosi87 commented 9 years ago

Bueno, mi error ocurre con el la siguiente linea:

tabula "Altman Exclusive Dealer Confidential Price List Jan  2014.pdf" -n -p all -o "demo.csv"

Así que supondré es verdad en algún momento localiza un problema en la pagina, en este caso parece ser un NULL y termina la ejecución. Imagino que ocurre algo como en ApachePOI, al hacer el parser localiza una linea(path) pero en ella solo se encuentran puros objetos nulos, en esos casos tendríamos que poner algúna política de lectura, algo como Path.RETURN_NULL_AS_BLANK, por esto mismo comentaba, en que momento o clase del proyecto te pones a ver los datos.

Apenas pueda ver en que pagina ocurre el problema te informo. =D.

Saludos y mucho Éxito.

jazzido commented 9 years ago

Encontré que el error sucede en —al menos— las páginas 48, 49 y 66. Cuando tenga un momento voy a ver si puedo agregar condiciones en el ObjectExtractor para considerar estos casos.

Aquí las páginas 48-49 extraídas en un archivo aparte: https://www.dropbox.com/s/y9i7s351j1isjjy/weird_paths.pdf?dl=0

Saludos!

aosi87 commented 9 years ago

Muchas gracias por tu esfuerzo, ahora le hecho un vistazo y practico el uso de tu Debug en el proceso, otra cosa, no se si tengas considerado que hay mas de una tabla por pagina, esto lo pregunto por que me he topado con varios casos de que las tablas están separadas con nombres de tabla antes de sus cabeceras, y si es algo difícil localizarlos con solo espacios vacíos ya que puede dar el caso que en una tabla no tenga mas que una columna o dos cuando mucho. Existe alguna variable o método que me permita retornar o verificar si pertenece a una tabla ese elemento?, de no ser así tenias considerado estos casos? esto lo pregunto para que implemente algo en mi proyecto aparte.

Saludos. =)

jazzido commented 9 years ago

Hola,

De momento, los algoritmos implementados en Tabula actuan sobre una área de manera global. Es decir que es reponsabilidad del programador de identificar el área de la tabla que se desea extraer.

Ese es el propósito del parámetro -a en el ejecutable que viene con Tabula, que a su vez usa el método getArea() de la clase Page. Una vez que tienes un objeto Page, debes extraer la área que necesitas con getArea y pasárselo al ExtractionAlgorithm que quieras usar.

Saludos,

M