PDFBox를 사용하여 PDF 파일의 좌표로 텍스트를 추출하려고합니다.PDFBox에서 스트립하는 경우의 텍스트 좌표
인터넷 (stackoverflow 너무)에서 발견 된 몇 가지 방법/정보를 섞어 보았지만 문제는 내가 좌표가 맞지 않습니다. 예를 들어, tex 위에 직사각형을 그릴 때 좌표를 사용하려고하면 rect가 다른 곳에 그려집니다.
이
은TextLine.java
import java.util.List;
import org.apache.pdfbox.text.TextPosition;
/**
*
* @author samue
*/
public class TextLine {
public List<TextPosition> textPositions = null;
public String text = "";
}
myStripper.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author samue
*/
public class myStripper extends PDFTextStripper {
public myStripper() throws IOException
{
}
@Override
protected void startPage(PDPage page) throws IOException
{
startOfLine = true;
super.startPage(page);
}
@Override
protected void writeLineSeparator() throws IOException
{
startOfLine = true;
super.writeLineSeparator();
}
@Override
public String getText(PDDocument doc) throws IOException
{
lines = new ArrayList<TextLine>();
return super.getText(doc);
}
@Override
protected void writeWordSeparator() throws IOException
{
TextLine tmpline = null;
tmpline = lines.get(lines.size() - 1);
tmpline.text += getWordSeparator();
super.writeWordSeparator();
}
@Override
protected void writeString(String text, List<TextPosition> textPositions) throws IOException
{
TextLine tmpline = null;
if (startOfLine) {
tmpline = new TextLine();
tmpline.text = text;
tmpline.textPositions = textPositions;
lines.add(tmpline);
} else {
tmpline = lines.get(lines.size() - 1);
tmpline.text += text;
tmpline.textPositions.addAll(textPositions);
}
if (startOfLine)
{
startOfLine = false;
}
super.writeString(text, textPositions);
}
boolean startOfLine = true;
public ArrayList<TextLine> lines = null;
}
를 (단지 테스트하기 위해 매우 빠른 기록 된 스타일을 판단하지 마십시오) 내 코드입니다
AWT 버튼을 클릭 이벤트
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
try {
File file = new File("C:\\Users\\samue\\Desktop\\mwb_I_201711.pdf");
PDDocument doc = PDDocument.load(file);
myStripper stripper = new myStripper();
stripper.setStartPage(1); // fix it to first page just to test it
stripper.setEndPage(1);
stripper.getText(doc);
TextLine line = stripper.lines.get(1); // the line i want to paint on
float minx = -1;
float maxx = -1;
for (TextPosition pos: line.textPositions)
{
if (pos == null)
continue;
if (minx == -1 || pos.getTextMatrix().getTranslateX() < minx) {
minx = pos.getTextMatrix().getTranslateX();
}
if (maxx == -1 || pos.getTextMatrix().getTranslateX() > maxx) {
maxx = pos.getTextMatrix().getTranslateX();
}
}
TextPosition firstPosition = line.textPositions.get(0);
TextPosition lastPosition = line.textPositions.get(line.textPositions.size() - 1);
float x = minx;
float y = firstPosition.getTextMatrix().getTranslateY();
float w = (maxx - minx) + lastPosition.getWidth();
float h = lastPosition.getHeightDir();
PDPageContentStream contentStream = new PDPageContentStream(doc, doc.getPage(0), PDPageContentStream.AppendMode.APPEND, false);
contentStream.setNonStrokingColor(Color.RED);
contentStream.addRect(x, y, w, h);
contentStream.fill();
contentStream.close();
File fileout = new File("C:\\Users\\samue\\Desktop\\pdfbox.pdf");
doc.save(fileout);
doc.close();
} catch (Exception ex) {
}
}
제안 사항? 내가 도대체 뭘 잘못하고있는 겁니까?
나는 당신의 코드를 이해하지 못했다. PDF에서 y = 0은 맨 위가 아니라 맨 아래임을 유의하십시오. 다음은 텍스트 추출 좌표를 사용하는 방법을 이해하는 데 도움이되는 예제입니다. https://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/ DrawPrintTextLocations.java?view = markup & sortby = date –
'PDPContentStream' 생성자를 다른 부울 인수'resetContext'와 함께 사용하고'true'로 설정해 보았습니까? – mkl
예 저는 0이 맨 아래에 있다는 것을 알고 있습니다. 이것이 getY() 또는 getYDirAdj() 대신 .getTextMatrix(). getTranslateY()를 사용한 이유입니다. 나는 resetContext를 사용해 보았지만 아무 도움도받지 않았다. 이제 그 소스 코드를 살펴볼 것입니다. 업데이트 할 것입니다. 감사합니다. –