Java 从pdf中获取斜体行

Java 从pdf中获取斜体行,java,python,Java,Python,我想从一本有斜体字的pdf书中获取所有行 示例(pdf上的一行是): 这是狗。 我希望输出为包含斜体文本的所有行。在这种情况下,整行将作为输出 我可以使用java或python中的任何解析从pdf中获得它吗?或者在某个地方我会得到这样的行列表。在玩了一番之后,我想到了以下几点: 如前所述,大多数斜体字体都是通过负斜角来识别的 基于此,我通过扩展SimpleTextExtractionStrategy进行了自定义,我将其命名为ItalicTextExtractionStrategy,并相应地覆盖了

我想从一本有斜体字的pdf书中获取所有行

示例(pdf上的一行是):

这是狗。

我希望输出为包含斜体文本的所有行。在这种情况下,整行将作为输出


我可以使用java或python中的任何解析从pdf中获得它吗?或者在某个地方我会得到这样的行列表。

在玩了一番之后,我想到了以下几点:

如前所述,大多数斜体字体都是通过负斜角来识别的

基于此,我通过扩展
SimpleTextExtractionStrategy
进行了自定义,我将其命名为
ItalicTextExtractionStrategy
,并相应地覆盖了该方法:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.DocumentFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TextRenderInfo;

public class ExtractItalicText {

    final static class ItalicTextExtractionStrategy extends SimpleTextExtractionStrategy {
        @Override
        public void renderText(TextRenderInfo arg0) {
            DocumentFont font = arg0.getFont();
            String[][] familyFontNamesArray = font.getFamilyFontName();
            for(String[] familyFontNames : familyFontNamesArray) {
                for(String familyFontName : familyFontNames) {
                    if(familyFontName.toLowerCase().contains("italic")) {
                        float italicAngle = font.getFontDescriptor(BaseFont.ITALICANGLE,
                                0 /* not relevant for ItalicAngle otherwise 1000 is a good value 
                                     source: http://grepcode.com/file/repo1.maven.org/maven2/com.itextpdf/itextpdf/5.4.2/com/itextpdf/text/pdf/DocumentFont.java#DocumentFont */);
                        if(italicAngle < 0) {
                            super.renderText(arg0);
                        }
                        break;
                    }
                }   
            }
        }
    }

    public static void extractItalicText(String pdf) throws IOException {
        PdfReader reader = null;
        PrintWriter out = null;
        PrintWriter outItalic = null;
        long s = System.currentTimeMillis();
        try {
            System.out.println("Processing: " + pdf + " ...");
            // output for original text including italic styled
            out = new PrintWriter(new FileOutputStream("src/main/resources/" + new File(pdf).getName() + ".txt"));
            // output for italic styled text only
            outItalic = new PrintWriter(new FileOutputStream("src/main/resources/" + new File(pdf).getName() + "_italic.txt"));
            reader = new PdfReader(pdf);
            int numberOfPages = reader.getNumberOfPages();
            for(int pageNumber = 1; pageNumber <= numberOfPages; pageNumber++) {
                // extract italic text
                String pageItalicText = PdfTextExtractor.getTextFromPage(reader, pageNumber, new ItalicTextExtractionStrategy());
                if(pageItalicText.trim().length() > 0) {
                    // we have some italic text in the current page, so we get the hole text of the page
                    // to search for the lines where the italic text is located
                    String textFromPage = PdfTextExtractor.getTextFromPage(reader, pageNumber);
                    String[] textLinesFromPage = textFromPage.split("[\r\n]");

                    // punctuation marks etc. are sometime not part of the italic text, so we need to clean the line
                    // map a cleaned line to a raw line
                    Map<String, String> cleanedtextLines = new LinkedHashMap<String, String>(textLinesFromPage.length * 4 / 3 + 1);
                    for(String line : textLinesFromPage) {
                        out.println(line);
                        // clean line from all non-word characters
                        cleanedtextLines.put(line.replaceAll("\\W", ""), line);
                    }
                    // split the italic text into lines
                    String[] italicTextLines = pageItalicText.split("[\r\n]");
                    Set<String> linesContainingItalicText = new HashSet<String>(italicTextLines.length * 4 / 3 + 1);
                    for(String italicText : italicTextLines) {
                        // clean the italic text from non-word characters
                        String cleanedItalicText = italicText.replaceAll("\\W", "");
                        // search for the corresponding line
                        for(Entry<String, String> lineEntry : cleanedtextLines.entrySet()) {                            
                            if((! linesContainingItalicText.contains(lineEntry.getKey())) 
                                    && lineEntry.getKey().contains(cleanedItalicText)) {
                                linesContainingItalicText.add(lineEntry.getKey());
                                // output the raw line
                                outItalic.println(lineEntry.getValue());
                            }
                        }
                    }
                }
                out.println("==== Page " + pageNumber + " =========================================================\n");
                outItalic.println("==== Page " + pageNumber + " =========================================================\n");
            }

        } finally {
            if(out != null) {
                out.close();
            }
            if(outItalic != null) {
                outItalic.close();
            }
            if(reader != null) {
                reader.close(); 
            }
            long e = System.currentTimeMillis();
            System.out.println("done (" + (e-s) + " ms)");
        }
    }

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        for(String arg: args) {
            extractItalicText(arg);
        }
    }
}
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.PrintWriter;
导入java.util.HashSet;
导入java.util.LinkedHashMap;
导入java.util.Map;
导入java.util.Map.Entry;
导入java.util.Set;
导入com.itextpdf.text.pdf.BaseFont;
导入com.itextpdf.text.pdf.DocumentFont;
导入com.itextpdf.text.pdf.PdfReader;
导入com.itextpdf.text.pdf.parser.PdfTextExtractor;
导入com.itextpdf.text.pdf.parser.simpletextractionstrategy;
导入com.itextpdf.text.pdf.parser.TextRenderInfo;
公共类提取斜体文本{
最后一个静态类ItalicTextExtractionStrategy扩展了SimpleTextExtractionStrategy{
@凌驾
公共无效renderText(TextRenderInfo arg0){
DocumentFont=arg0.getFont();
字符串[][]familyFontNamesArray=font.getFamilyFontName();
对于(字符串[]familyFontNames:familyFontNamesArray){
for(字符串familyFontName:familyFontNames){
如果(familyFontName.toLowerCase().包含(“斜体”)){
float italicAngle=font.getFontDescriptor(BaseFont.italicAngle,
0/*与ItalicAngle无关,否则1000是一个好值
资料来源:http://grepcode.com/file/repo1.maven.org/maven2/com.itextpdf/itextpdf/5.4.2/com/itextpdf/text/pdf/DocumentFont.java#DocumentFont */);
如果(斜体<0){
super.renderText(arg0);
}
打破
}
}   
}
}
}
公共静态void extractItalicText(字符串pdf)引发IOException{
PdfReader reader=null;
PrintWriter out=null;
PrintWriter outItalic=null;
长s=System.currentTimeMillis();
试一试{
System.out.println(“处理:+pdf+”);
//输出原始文本,包括斜体样式
out=newprintWriter(新文件输出流(“src/main/resources/”+新文件(pdf).getName()+“.txt”);
//仅输出斜体样式的文本
outItalic=新的PrintWriter(新文件outputstream(“src/main/resources/”+新文件(pdf).getName()+“_italic.txt”);
阅读器=新的pdf阅读器(pdf);
int numberOfPages=reader.getNumberOfPages();
用于(int pageNumber=1;pageNumber 0){
//我们在当前页面中有一些斜体文本,因此我们得到页面的孔文本
//搜索斜体文本所在行的步骤
字符串textFromPage=PdfTextExtractor.getTextFromPage(读取器,页码);
字符串[]textLinesFromPage=textFromPage.split([\r\n]”);
//标点符号等有时不是斜体文本的一部分,因此我们需要清理线条
//将已清理的线映射到原始线
Map cleanedtextLines=新建LinkedHashMap(textLinesFromPage.length*4/3+1);
用于(字符串行:textLinesFromPage){
out.println(行);
//清除所有非单词字符的行
cleanedtextLines.put(line.replaceAll(\\W,“”),line);
}
//将斜体文本分成几行
字符串[]italicTextLines=pageItalicText.split([\r\n]”);
Set linescontaingingitalictext=新哈希集(italicTextLines.length*4/3+1);
用于(字符串斜体文本:斜体文本行){
//清除非单词字符中的斜体文本
字符串cleanedItalicText=italicText.replaceAll(“\\W”和“);
//搜索对应的行
对于(Entry lineEntry:cleanedtextLines.entrySet()){
如果(!linesContainingItalicText.contains(lineEntry.getKey()))
&&lineEntry.getKey()包含(cleanedItalicText)){
linesContainingItalicText.add(lineEntry.getKey());
//输出原始生产线
outItalic.println(lineEntry.getValue());
}
}
}
}
out.println(“===页面”+页码+”=================================================================================================================================\n”);
outItalic.println(“===第页“+页码+”===================================================================================================================================================\n”);
}
}最后{
if(out!=null){
out.close();
}
如果(outItalic!=null){
outItalic.close();
}
if(读卡器!=null){
reader.close();
}
长e=System.currentTimeMillis();
System.out.println(“完成”(+(e-s)+“ms”);
}
}
/**
*@param args
*@抛出异常
*/
公共静态void main(字符串[]参数