2016-05-18 3 views
3

ввода PDF документа с комментариемExtract PDF комментарии в HTML

У меня есть PDF-документ с подсветкой и комментариями по блику ("мой комментарий") (downlload).

enter image description here

Желаемая выход

Я хочу, чтобы преобразовать PDF в текст, где комментарий в теги, что-то вроде этого:

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

Вопрос

Может кто-нибудь помочь мне, как реализовать метод:

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

или метод

private boolean isTextAnnotated() 

, чтобы определить, является ли аннотация апп находится в позиции текста? Если возможно, также будет полезно определить текстовую позицию комментария.

JAVA код

Во всяком случае я заблудился о том, как определить, если аннотаций связан с перерабатываемой в настоящее время текст. Я также не знаю, если можно определить точную часть текста.

   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 зависимостей

<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

Я не думаю, что на ваш вопрос есть «идеальный ответ». Аннотации имеют прямоугольник, который вы можете получить, но это не означает, что вся поверхность прямоугольника над текстом. Существует много разных типов аннотаций, см. Http://www.pdfill.com/example/pdf_commenting_new.pdf –

+0

Действительно ли ваш план делает текст жирным? Просто интересно, что именно вы пытаетесь сделать, если есть другой способ сделать это, что будет иметь больше смысла. Если вы просто хотите узнать, подсвечена ли какая-либо часть текста, вы можете обнаружить это, но, как отмечено в предыдущем комментарии, возможно, что выделена только часть текста. – Amber

+0

Кроме того, вас интересуют только аннотации выделения? – Amber

ответ

4

Вы можете получить аннотацию прямоугольник и посмотреть, если он содержит как верхний левый и нижний правый угол каждой позиции текста. Поскольку writeString содержит несколько символов, вы хотите проверить каждый символ отдельно, поскольку аннотация может охватывать только подмножество символов. Аннотации могут также обернуть строки, поэтому вам нужно будет проверить в конце страницы (не в конце каждой строки), если вам нужно закрыть тэг html. Обратите внимание, что прямоугольник, который вы получаете из аннотации, находится в пространстве PDF. Но координаты, которые вы получаете от TextPosition, находятся в пространстве java. Поэтому, когда вы проверяете Rectangle.contains, вам нужно перевести координаты текстовой позиции в пространство PDF.

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); 
    } 
}