2016-05-18 15 views
3

Eingang PDF-Dokument mit KommentarenExtract PDF-Kommentare in HTML

Ich habe ein PDF-Dokument mit Highlight und kommentiert die Highlight ("meinen Kommentar") (downlload).

enter image description here

Wunsch Ausgang

ich die PDF in Text konvertieren möchten, wo Kommentar in Tags ist, so etwas wie dieses:

ONE TWO THREE  
FOUR <b id="my comment">FIVE</b> SIX SEVEN 

Frage

Kann mir jemand helfen, wie Verfahren zu implementieren:

private double getDistance(PDAnnotation ann, TextPosition firstProsition) {...} 

oder der Methode

private boolean isTextAnnotated() 

zu bestimmen, ob die Anmerkung ann an der Position des Textes? Wenn möglich, wäre auch die Textposition des Kommentars schön zu bestimmen.

JAVA-Code

Auf jeden Fall habe ich verloren darüber, wie um zu bestimmen, ob Anmerkung zu dem aktuell bearbeiteten Text bezogen ist. Ich weiß auch nicht, ob es möglich ist, den genauen Teil des Textes zu identifizieren.

   PDFParser parser = new PDFParser(new FileInputStream(file)); 
       parser.parse(); 
       cosDoc = parser.getDocument(); 

       pdfStripper = new PDFTextStripper() 
       { 
        List<PDAnnotation> la; 
        private boolean closeWithEnd; 
        @Override 
        protected void startPage(PDPage page) throws IOException 
        { 
         la = page.getAnnotations(); // init pages 
         startOfLine = true; 
         super.startPage(page); 
        } 

        @Override 
        protected void writeLineSeparator() throws IOException 
        { 
         startOfLine = true; 
         super.writeLineSeparator(); 
         if(closeWithEnd) { 
          writeString(" </b> "); 
         } 
        } 

        @Override 
        protected void writeString(String text, List<TextPosition> textPositions) throws IOException 
        { 
         if (startOfLine) 
         { 
          TextPosition firstProsition = textPositions.get(0); 
          PDAnnotation ann; 
          if((ann = isTextAnnotated(firstProsition, text)) != null) { 
           writeString(" <b id='"+ann.getAnnotationName()+"'> "); 
           closeWithEnd = true; 
          } else { 
           closeWithEnd = false; 
          } 
          startOfLine = false; 
         } 
         super.writeString(text+" ", textPositions); 
        } 
        private PDAnnotation isTextAnnotated(TextPosition firstProsition, String text) { 
         for (PDAnnotation ann : la) { 
          System.out.println(text+" ------------- "+getDistance(ann, firstProsition)); 
         } 
         return null; 
        } 
        private double getDistance(PDAnnotation ann, TextPosition firstProsition) { 
         TODO - how to get distance 
         return 0.0; 
        } 
        boolean startOfLine = true; 
       }; 

       pdDoc = new PDDocument(cosDoc); 
       pdfStripper.setStartPage(0); 
       pdfStripper.setEndPage(pdDoc.getNumberOfPages()); 
       String parsedText = pdfStripper.getText(pdDoc); 

Maven Abhängigkeiten

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>3.8.1</version> 
    <scope>test</scope> 
</dependency> 

<!-- http://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --> 
<dependency> 
    <groupId>org.apache.pdfbox</groupId> 
    <artifactId>pdfbox</artifactId> 
    <version>1.8.10</version> 
</dependency> 

<!-- http://mvnrepository.com/artifact/org.apache.tika/tika-core --> 
<dependency> 
    <groupId>org.apache.tika</groupId> 
    <artifactId>tika-core</artifactId> 
    <version>1.13</version> 
</dependency> 

<!-- http://mvnrepository.com/artifact/commons-io/commons-io --> 
<dependency> 
    <groupId>commons-io</groupId> 
    <artifactId>commons-io</artifactId> 
    <version>2.4</version> 
</dependency> 


<!-- http://mvnrepository.com/artifact/log4j/log4j --> 
<dependency> 
    <groupId>log4j</groupId> 
    <artifactId>log4j</artifactId> 
    <version>1.2.17</version> 
</dependency> 

<dependency> 
    <groupId>info.debatty</groupId> 
    <artifactId>java-string-similarity</artifactId> 
    <version>RELEASE</version> 
</dependency> 

<dependency> 
    <groupId>org.apache.opennlp</groupId> 
    <artifactId>opennlp-tools</artifactId> 
    <version>1.6.0</version> 
</dependency> 

+0

Ich denke nicht, dass es "die perfekte Antwort" auf Ihre Frage gibt. Beschriftungen haben ein Rechteck, das Sie erhalten können. Dies bedeutet jedoch nicht, dass die gesamte Fläche des Rechtecks ​​über dem Text liegt. Es gibt viele verschiedene Arten von Anmerkungen, siehe http://www.pdfill.com/example/pdf_commentment_new.pdf –

+0

Ist Ihr Plan wirklich, den Text fett zu machen? Ich frage mich genau, was Sie zu tun versuchen, falls es einen anderen Weg gibt, der sinnvoller wäre. Wenn Sie nur wissen möchten, ob ein Teil des Textes hervorgehoben ist, können Sie dies erkennen, aber wie im vorherigen Kommentar erwähnt, ist es möglich, dass nur ein Teil des Textes hervorgehoben ist. – Amber

+0

Sind Sie auch nur an Highlight-Annotationen interessiert? – Amber

Antwort

4

Sie können die Anmerkung Rechteck und sehen, ob es enthält sowohl die oberen linke und untere rechte Ecke jeder Textposition. Da writeString mehrere Zeichen enthält, sollten Sie jedes Zeichen einzeln überprüfen, da die Anmerkung möglicherweise nur eine Teilmenge der Zeichen enthält. Die Annotation kann auch Zeilen umbrechen. Daher sollten Sie am Ende der Seite (nicht am Ende jeder Zeile) prüfen, ob Sie Ihr HTML-Tag schließen müssen. Beachten Sie, dass das Rechteck, das Sie von der Anmerkung erhalten, im PDF-Raum ist. Die Koordinaten, die Sie von der TextPosition erhalten, befinden sich jedoch im Java-Bereich. Wenn Sie also Rectangle.contains aktivieren, müssen Sie die Textpositionskoordinaten in den PDF-Raum übersetzen.

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.util.List; 

import org.apache.pdfbox.cos.COSDocument; 
import org.apache.pdfbox.pdfparser.PDFParser; 
import org.apache.pdfbox.pdmodel.PDDocument; 
import org.apache.pdfbox.pdmodel.PDPage; 
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; 
import org.apache.pdfbox.util.PDFTextStripper; 
import org.apache.pdfbox.util.TextPosition; 

public class MyPDFTextStripper extends PDFTextStripper 
{ 
    public MyPDFTextStripper() throws IOException 
    { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 

    PDPage currentPage; 
    List<PDAnnotation> pageAnnotations; 
    private boolean needsEndTag; 
    boolean startOfLine = true; 

    @Override 
    protected void startPage(PDPage page) throws IOException 
    { 
     currentPage = page; 
     pageAnnotations = currentPage.getAnnotations(); 
     super.startPage(page); 
    } 

    @Override 
    protected void writeString(String text, List<TextPosition> textPositions) throws IOException 
    { 
     StringBuilder newText = new StringBuilder(); 
     PDAnnotation currentAnnot = null; 
     for (TextPosition textPosition : textPositions) 
     { 
      PDAnnotation annotation = getAnnotation(textPosition); 
      if (annotation != null) 
      { 
       if (currentAnnot == null) 
       { 
        // if the currentAnnot is null, start a new annotation 
        newText.append("<b id='" + annotation.getAnnotationName() + "'>"); 
       } 
       else if (!currentAnnot.getAnnotationName().equals(annotation.getAnnotationName())) 
       { 
        // if the current Annot is different, end it and start a new 
        // one 
        newText.append("</b><b id='" + annotation.getAnnotationName() + "'>"); 
       } 
       // remember this in case the annotation wraps lines 
       needsEndTag = true; 
       currentAnnot = annotation; 
      } 
      else if (currentAnnot != null) 
      { 
       // if no new annotation is associated with the text, but there used to be, close the tag 
       newText.append("</b>"); 
       currentAnnot = null; 
       needsEndTag = false; 
      } 
      newText.append(textPosition.getCharacter()); 
     } 
     super.writeString(newText.toString(), textPositions); 
    } 

    private PDAnnotation getAnnotation(TextPosition textPosition) 
    { 
     float textX1 = textPosition.getX(); 
     // Translate the y coordinate to PDF Space 
     float textY1 = currentPage.findMediaBox().getHeight() - textPosition.getY(); 
     float textX2 = textX1 + textPosition.getWidth(); 
     float textY2 = textY1 + textPosition.getHeight(); 

     for (PDAnnotation annotation : pageAnnotations) 
     { 
      if (annotation.getRectangle().contains(textX1, textY1) && annotation.getRectangle().contains(textX2, textY2)) 
      { 
       return annotation; 
      } 
     } 
     return null; 
    } 

    @Override 
    public String getPageEnd() 
    { 
     // if the annotation wraps lines and extends to the end of the document, need to add the end tag 
     if (needsEndTag) 
     { 
      return "</b>" + super.getPageEnd(); 
     } 
     return super.getPageEnd(); 
    } 

    public static void main(String[] args) throws Exception 
    { 
     File file = new File(args[0]); 
     PDFParser parser = new PDFParser(new FileInputStream(file)); 
     parser.parse(); 
     COSDocument cosDoc = parser.getDocument(); 

     MyPDFTextStripper pdfStripper = new MyPDFTextStripper(); 

     PDDocument pdDoc = new PDDocument(cosDoc); 
     pdfStripper.setStartPage(0); 
     pdfStripper.setEndPage(pdDoc.getNumberOfPages()); 
     String parsedText = pdfStripper.getText(pdDoc); 
     System.out.println(parsedText); 
    } 
}