Java 与PDFBox文档内容对象中的PDF段落关联的文本

Java 与PDFBox文档内容对象中的PDF段落关联的文本,java,pdf,pdfbox,Java,Pdf,Pdfbox,我试图获取与在PDF文件的内容树中导航的段落相关联的文本。我使用的是PDFBox,无法找到段落与其包含的文本之间的链接(请参见下面的代码): public类ReadPdf{ 公共静态void main(字符串[]args)引发IOException{ MyBufferedWriter out=新建MyBufferedWriter(新建文件写入程序( “C:/Users/wip.txt”); RandomAccessFile raf=新的RandomAccessFile(新文件( “C:/User

我试图获取与在PDF文件的内容树中导航的段落相关联的文本。我使用的是PDFBox,无法找到段落与其包含的文本之间的链接(请参见下面的代码):

public类ReadPdf{
公共静态void main(字符串[]args)引发IOException{
MyBufferedWriter out=新建MyBufferedWriter(新建文件写入程序(
“C:/Users/wip.txt”);
RandomAccessFile raf=新的RandomAccessFile(新文件(
“C:/Users/mypdf.pdf”),“r”);
PDFParser解析器=新的PDFParser(raf);
parser.parse();
COSDocument cosDoc=parser.getDocument();
out.write(cosDoc.getXrefTable().toString());
out.write(cosDoc.getObjects().toString());
PDDocument document=parser.getPDDocument()
document.getClass();
COSParser COSParser=新的COSParser(raf);
PDStructureTreeRoot treeRoot=document.getDocumentCatalog().getStructureTreeRoot();
for(对象kid:treeRoot.getKids()){
对于(对象kid2:((pdstructurelement)kid.getKids()){
pdstructurelement kid2c=(pdstructurelement)kid2;
if(kid2c.getStandardStructureType()=“P”){
for(对象kid3:kid2c.getKids()){
if(PDStructureElement的kid3实例){
pdstructurelement kid3c=(pdstructurelement)kid3;
}
否则{
对于(Entryentry:kid2c.getCOSObject().entrySet()){
//打印段落中的所有关键字
System.out.println(entry.getKey().toString());
System.out.println(entry.getValue().toString());}
}}}}}}}
当我打印内容时,我会得到以下键:

  • /P:对父项的引用
  • /A:该段的格式
  • /K:该段在本节中的位置
  • /C:段落名称(!=文本)
  • /Pg:参考页面
示例输出:

COSName{K}

余弦{2}

COSName{Pg}

余对象{12,0}

COSName{C}

COSName{Normal}

COSName{A}

余对象{434,0}

COSName{S}

COSName{Normal}

COSName{p}

COSObject{421,0}

现在,这些都没有指向段落中的实际文本。 我知道当我用acrobat打开文档时,可以通过解析获得关系(见下图):

我找到了一种方法,通过解析页面中的内容流来实现这一点。 浏览PDF规范第10.6.3章时,每个文本流的编号(位于\P\MCID下)与可在COSObject中找到的标记属性(PDFBox中的PDStructureElement)之间存在链接

1) 要获取文本和MCID,请执行以下操作:

PDPage pdPage;
Iterator<PDStream> inputStream = pdPage.getContentStreams();
while (inputStream.hasNext()) {
try {
PDFStreamParser parser2 = new PDFStreamParser((PDStream)inputStream.next());
parser2.parse();
List<Object> tokens = parser2.getTokens();
for (int j = 0; j < tokens.size(); j++){
tokenString = (tokenString + tokens.get(j).toString()}
// here comes the parsing of the string. Chapter 5 specifies what each of the operators Tj (actual text), Tm, BDC, BT, ET, EMC mean, MCID
PDPage-PDPage;
迭代器inputStream=pdPage.getContentStreams();
while(inputStream.hasNext()){
试一试{
PDFStreamParser parser2=新的PDFStreamParser((PDStream)inputStream.next());
parser2.parse();
List tokens=parser2.getTokens();
对于(int j=0;j
  • 然后获取与MCID匹配的标记及其属性:

    PDStructureElement PDStructureElement;
    pDStructureElement.getCOSObject().getInt(COSName.K)

  • 应该可以。在没有标记的文档中(document.getDocumentCatalog().getStructureTreeRoot()没有子项),无法执行此匹配,但仍可以使用步骤1读取文本。

    您需要1)获取PDFDebugger,以便查看结构和内容流2)阅读PDF规范。若要获得特定帮助(不是我,这仍然是未探索的领域之一),请链接到您的PDF。
    PDPage pdPage;
    Iterator<PDStream> inputStream = pdPage.getContentStreams();
    while (inputStream.hasNext()) {
    try {
    PDFStreamParser parser2 = new PDFStreamParser((PDStream)inputStream.next());
    parser2.parse();
    List<Object> tokens = parser2.getTokens();
    for (int j = 0; j < tokens.size(); j++){
    tokenString = (tokenString + tokens.get(j).toString()}
    // here comes the parsing of the string. Chapter 5 specifies what each of the operators Tj (actual text), Tm, BDC, BT, ET, EMC mean, MCID