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