2016-08-13 33 views
2

pdfbox 2.0.2(https://github.com/apache/pdfbox/tree/2.0.2)ユーザーの初心者として、すべてのストロークライン(たとえば、テーブルの列と行の境界線)を取得したいと思います。ページ(PDPage)の次のクラスを作成しました。 package org.apache.pdfbox.rendering;pdfbox 2.0.2> PageDrawer.processPageメソッドを呼び出すと例外が発生する

import java.awt.geom.GeneralPath; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URI; 

import org.apache.commons.io.IOUtils; 
import org.apache.pdfbox.pdmodel.PDDocument; 
import org.apache.pdfbox.pdmodel.PDPage; 
import org.apache.pdfbox.rendering.PDFRenderer; 
import org.apache.pdfbox.rendering.PageDrawer; 
import org.apache.pdfbox.rendering.PageDrawerParameters; 

public class LineCatcher { 
    private PageDrawer pageDrawer; 
    private PDDocument document; 
    private PDFRenderer pdfRenderer; 
    private PDPage page; 

    public LineCatcher(URI pdfSrcURI) throws IllegalArgumentException, 
     MalformedURLException, IOException { 
     this.document = PDDocument.load(IOUtils.toByteArray(pdfSrcURI)); 
     this.pdfRenderer = new PDFRenderer(this.document); 
    } 
    public GeneralPath getLinePath(int pageIndex) throws IOException { 
     this.page = this.document.getPage(pageIndex); 
     PageDrawerParameters parameters = new PageDrawerParameters (this.pdfRenderer, this.page); 
     this.pageDrawer = new PageDrawer(parameters); 
     this.pageDrawer.processPage(this.page); //catches exception here 
     return this.pageDrawer.getLinePath(); 
    } 
} 

私の理解によると、ページの行のパスを取得するためには、ページが最初に処理しなければならないので、私は、私は「ここにキャッチ例外」とマークされた行、のメソッドprocessPageと呼ばれます。予期せず上記の行にNullPointer Excpetions intを捕まえました。例外情報は次のとおりです。

java.lang.NullPointerException 
    at org.apache.pdfbox.rendering.PageDrawer.fillPath(PageDrawer.java:599) 
    at org.apache.pdfbox.contentstream.operator.graphics.FillNonZeroRule.process(FillNonZeroRule.java:36) 
    at org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(PDFStreamEngine.java:815) 
    at org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(PDFStreamEngine.java:472) 
    at org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(PDFStreamEngine.java:446) 
    at org.apache.pdfbox.contentstream.PDFStreamEngine.processPage(PDFStreamEngine.java:149) 
    at org.apache.pdfbox.rendering.LineCatcher.getLinePath(LineCatcher.java:33) 
    at org.apache.pdfbox.rendering.TestLineCatcher.testGetLinePath(TestLineCatcher.java:21) 

ロジックのアドバイスやコードのデバッグに役立つ人はいますか?事前に感謝します

+1

間違っています... getLinePath()は、ページの処理中に現在の行のパスを取得します。各塗りつぶし/ストローク後に空にリセットされます。あなたの考えではなく、ページのすべての行を含むパスです。私は何か良いものを考え出すことができるかどうかを見ます。ストローク演算子をキャッチします。 –

答えて

4

PageDrawerを拡張しても実際には機能しませんでしたので、PDFGraphicsStreamEngineを拡張しました。ここに結果があります。私はPageDrawerで行われていることのいくつかを行います。行を収集するには、strokePath()の形状を評価するか、printlnをインクルードした他のメソッドの点と行を収集します。

public class LineCatcher extends PDFGraphicsStreamEngine 
{ 
    private final GeneralPath linePath = new GeneralPath(); 
    private int clipWindingRule = -1; 

    public LineCatcher(PDPage page) 
    { 
     super(page); 
    } 

    public static void main(String[] args) throws IOException 
    { 
     try (PDDocument document = PDDocument.load(new File("Test.pdf"))) 
     { 
      PDPage page = document.getPage(0); 
      LineCatcher test = new LineCatcher(page); 
      test.processPage(page); 
     } 
    } 

    @Override 
    public void appendRectangle(Point2D p0, Point2D p1, Point2D p2, Point2D p3) throws IOException 
    { 
     System.out.println("appendRectangle"); 
     // to ensure that the path is created in the right direction, we have to create 
     // it by combining single lines instead of creating a simple rectangle 
     linePath.moveTo((float) p0.getX(), (float) p0.getY()); 
     linePath.lineTo((float) p1.getX(), (float) p1.getY()); 
     linePath.lineTo((float) p2.getX(), (float) p2.getY()); 
     linePath.lineTo((float) p3.getX(), (float) p3.getY()); 

     // close the subpath instead of adding the last line so that a possible set line 
     // cap style isn't taken into account at the "beginning" of the rectangle 
     linePath.closePath(); 
    } 

    @Override 
    public void drawImage(PDImage pdi) throws IOException 
    { 
    } 

    @Override 
    public void clip(int windingRule) throws IOException 
    { 
     // the clipping path will not be updated until the succeeding painting operator is called 
     clipWindingRule = windingRule; 

    } 

    @Override 
    public void moveTo(float x, float y) throws IOException 
    { 
     linePath.moveTo(x, y); 
     System.out.println("moveTo"); 
    } 

    @Override 
    public void lineTo(float x, float y) throws IOException 
    { 
     linePath.lineTo(x, y); 
     System.out.println("lineTo"); 
    } 

    @Override 
    public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) throws IOException 
    { 
     linePath.curveTo(x1, y1, x2, y2, x3, y3); 
     System.out.println("curveTo"); 
    } 

    @Override 
    public Point2D getCurrentPoint() throws IOException 
    { 
     return linePath.getCurrentPoint(); 
    } 

    @Override 
    public void closePath() throws IOException 
    { 
     linePath.closePath(); 
    } 

    @Override 
    public void endPath() throws IOException 
    { 
     if (clipWindingRule != -1) 
     { 
      linePath.setWindingRule(clipWindingRule); 
      getGraphicsState().intersectClippingPath(linePath); 
      clipWindingRule = -1; 
     } 
     linePath.reset(); 

    } 

    @Override 
    public void strokePath() throws IOException 
    { 
     // do stuff 
     System.out.println(linePath.getBounds2D()); 

     linePath.reset(); 
    } 

    @Override 
    public void fillPath(int windingRule) throws IOException 
    { 
     linePath.reset(); 
    } 

    @Override 
    public void fillAndStrokePath(int windingRule) throws IOException 
    { 
     linePath.reset(); 
    } 

    @Override 
    public void shadingFill(COSName cosn) throws IOException 
    { 
    } 
} 
+0

大きな助けをいただき、ありがとうございます:) linePathが「最終」になる理由は何ですか? – Rui

+0

これは決して上書きされないため、Netbeansによる推奨です。それは本当に重要ではありません。 –

+0

Ahaa、Listと似ていますか?私が覚えているとおり、リストは最終的に初期化されるべきです。そして、「創造」とは何ですか?それほど重要ではないと思われますが、それについて何かを得る方が良いでしょう。さらに、 'linePath'を返すメソッドが必要でしょうか? – Rui

関連する問題