java解析pdf獲取pdf中內(nèi)容信息
今日項(xiàng)目中需要將pdf中的數(shù)據(jù)獲取到進(jìn)行校驗(yàn)數(shù)據(jù),于是前往百度翻來(lái)覆去找到以下幾種辦法,做個(gè)筆記,方便日后查詢(xún)。
廢話不多說(shuō),我要直接上代碼裝逼了
第一種 使用開(kāi)源組織提供的開(kāi)源框架 pdfbox
api ; https://pdfbox.apache.org/
特點(diǎn):免費(fèi),功能強(qiáng)大,解析中文或許會(huì)存在亂碼,格式有點(diǎn)亂,沒(méi)有國(guó)產(chǎn)解析的那么美化。
想要按行讀?。?/p>
PDFTextStripper stripper = new PDFTextStripper();
stripper .setSortByPosition(sort); //sort設(shè)置為true 則按照行進(jìn)行讀取,默認(rèn)是false
可以按照指定的模板,對(duì)pdf進(jìn)行修改添加刪除等操作,總之操作很騷,很強(qiáng)大。
1 pdfbox 需要帶入依賴(lài)
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/jempbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>jempbox</artifactId>
<version>1.8.16</version>
</dependency>
2 代碼
/**
* 功能 PDF讀寫(xiě)類(lèi)
* @CreateTime 2011-4-14 下午02:44:11
*/
public class PDFUtil {
// public static final String CHARACTOR_FONT_CH_FILE = "SIMFANG.TTF"; //仿宋常規(guī)
public static final String CHARACTOR_FONT_CH_FILE = "SIMHEI.TTF"; //黑體常規(guī)
public static final Rectangle PAGE_SIZE = PageSize.A4;
public static final float MARGIN_LEFT = 50;
public static final float MARGIN_RIGHT = 50;
public static final float MARGIN_TOP = 50;
public static final float MARGIN_BOTTOM = 50;
public static final float SPACING = 20;
private Document document = null;
/**
* 功能:創(chuàng)建導(dǎo)出數(shù)據(jù)的目標(biāo)文檔
* @param fileName 存儲(chǔ)文件的臨時(shí)路徑
* @return
*/
public void createDocument(String fileName) {
File file = new File(fileName);
FileOutputStream out = null;
document = new Document(PAGE_SIZE, MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM);
try {
out = new FileOutputStream(file);
// PdfWriter writer =
PdfWriter.getInstance(document, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
// 打開(kāi)文檔準(zhǔn)備寫(xiě)入內(nèi)容
document.open();
}
/**
* 將章節(jié)寫(xiě)入到指定的PDF文檔中
* @param chapter
* @return
*/
public void writeChapterToDoc(Chapter chapter) {
try {
if(document != null) {
if(!document.isOpen()) document.open();
document.add(chapter);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 功能 創(chuàng)建PDF文檔中的章節(jié)
* @param title 章節(jié)標(biāo)題
* @param chapterNum 章節(jié)序列號(hào)
* @param alignment 0表示align=left,1表示align=center
* @param numberDepth 章節(jié)是否帶序號(hào) 設(shè)值=1 表示帶序號(hào) 1.章節(jié)一;1.1小節(jié)一...,設(shè)值=0表示不帶序號(hào)
* @param font 字體格式
* @return Chapter章節(jié)
*/
public static Chapter createChapter(String title, int chapterNum, int alignment, int numberDepth, Font font) {
Paragraph chapterTitle = new Paragraph(title, font);
chapterTitle.setAlignment(alignment);
Chapter chapter = new Chapter(chapterTitle, chapterNum);
chapter.setNumberDepth(numberDepth);
return chapter;
}
/**
* 功能:創(chuàng)建某指定章節(jié)下的小節(jié)
* @param chapter 指定章節(jié)
* @param title 小節(jié)標(biāo)題
* @param font 字體格式
* @param numberDepth 小節(jié)是否帶序號(hào) 設(shè)值=1 表示帶序號(hào) 1.章節(jié)一;1.1小節(jié)一...,設(shè)值=0表示不帶序號(hào)
* @return section在指定章節(jié)后追加小節(jié)
*/
public static Section createSection(Chapter chapter, String title, Font font, int numberDepth) {
Section section = null;
if(chapter != null) {
Paragraph sectionTitle = new Paragraph(title, font);
sectionTitle.setSpacingBefore(SPACING);
section = chapter.addSection(sectionTitle);
section.setNumberDepth(numberDepth);
}
return section;
}
/**
* 功能:向PDF文檔中添加的內(nèi)容
* @param text 內(nèi)容
* @param font 內(nèi)容對(duì)應(yīng)的字體
* @return phrase 指定字體格式的內(nèi)容
*/
public static Phrase createPhrase(String text,Font font) {
Phrase phrase = new Paragraph(text,font);
return phrase;
}
/**
* 功能:創(chuàng)建列表
* @param numbered 設(shè)置為 true 表明想創(chuàng)建一個(gè)進(jìn)行編號(hào)的列表
* @param lettered 設(shè)置為true表示列表采用字母進(jìn)行編號(hào),為false則用數(shù)字進(jìn)行編號(hào)
* @param symbolIndent
* @return list
*/
public static List createList(boolean numbered, boolean lettered, float symbolIndent) {
List list = new List(numbered, lettered, symbolIndent);
return list;
}
/**
* 功能:創(chuàng)建列表中的項(xiàng)
* @param content 列表項(xiàng)中的內(nèi)容
* @param font 字體格式
* @return listItem
*/
public static ListItem createListItem(String content, Font font) {
ListItem listItem = new ListItem(content, font);
return listItem;
}
/**
* 功能:創(chuàng)造字體格式
* @param fontname
* @param size 字體大小
* @param style 字體風(fēng)格
* @param color 字體顏色
* @return Font
*/
public static Font createFont(String fontname, float size, int style, BaseColor color) {
Font font = FontFactory.getFont(fontname, size, style, color);
return font;
}
/**
* 功能: 返回支持中文的字體---仿宋
* @param size 字體大小
* @param style 字體風(fēng)格
* @param color 字體 顏色
* @return 字體格式
*/
public static Font createCHineseFont(float size, int style, BaseColor color) {
BaseFont bfChinese = null;
try {
bfChinese = BaseFont.createFont(CHARACTOR_FONT_CH_FILE,BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return new Font(bfChinese, size, style, color);
}
/**
* 最后關(guān)閉PDF文檔
*/
public void closeDocument() {
if(document != null) {
document.close();
}
}
/**
* 讀PDF文件,使用了pdfbox開(kāi)源項(xiàng)目
* @param fileName
*/
public static void readPDF(String fileName) {
File file = new File(fileName);
FileInputStream in = null;
try {
in = new FileInputStream(fileName);
// 新建一個(gè)PDF解析器對(duì)象
PDFParser parser = new PDFParser(new RandomAccessFile(file,"rw"));
// 對(duì)PDF文件進(jìn)行解析
parser.parse();
// 獲取解析后得到的PDF文檔對(duì)象
PDDocument pdfdocument = parser.getPDDocument();
// 新建一個(gè)PDF文本剝離器
PDFTextStripper stripper = new PDFTextStripper();
// 從PDF文檔對(duì)象中剝離文本
String result = stripper.getText(pdfdocument);
FileWriter fileWriter = new FileWriter(new File("pdf.txt"));
fileWriter.write(result);
fileWriter.flush();
fileWriter.close();
System.out.println("PDF文件的文本內(nèi)容如下:");
System.out.println(result);
} catch (Exception e) {
System.out.println("讀取PDF文件" + file.getAbsolutePath() + "生失敗!" + e);
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
}
}
}
}
/**
* 測(cè)試pdf文件的創(chuàng)建
* @param args
*/
public static void main(String[] args) {
String fileName = "C:\Users\tizzy\Desktop\測(cè)試.pdf"; //這里先手動(dòng)把絕對(duì)路徑的文件夾給補(bǔ)上。
PDFUtil pdfUtil = new PDFUtil();
pdfUtil.writeChapterToDoc(chapter);
pdfUtil.closeDocument();
}
}
解析后的內(nèi)容格式
合 計(jì)
備
注
xxxxxxxxxxx普通發(fā)票
價(jià)稅合計(jì)(大寫(xiě)) (小寫(xiě))
貨物或應(yīng)稅勞務(wù)、服務(wù)名稱(chēng) 規(guī)格型號(hào) 單位 數(shù) 量 單 價(jià) 金 額 稅率 稅 額
購(gòu)
買(mǎi)
方
銷(xiāo)
售
方
收 款 人: 復(fù) 核: 開(kāi) 票 人: 銷(xiāo) 售 方:(章)
密
碼
區(qū)
機(jī)器編號(hào):
名 稱(chēng):
納稅人識(shí)別號(hào):
地 址、
開(kāi)戶行及賬號(hào):
名 稱(chēng):
納稅人識(shí)別號(hào):
地 址、
開(kāi)戶行及賬號(hào):
發(fā)票代碼:
發(fā)票號(hào)碼:
開(kāi)票日期:
校 驗(yàn) 碼:
電 話:
電 話:
¥1.00 ¥0.06
*xxxxxxxxxxx 1 1 1.00 6% 0.06
499111xxx80
壹圓零陸分
收款人 復(fù)核人 開(kāi)票人
0 3 < < 7 9 2 9 > 5 8 4 3 > 2 3 1xxxx / 3 5 0 > 3 5 8 1
> 7 6 3 8 > 1 - x + 1x 5 4 6 * 1 + 7xxx 8 < / 0 3 + 9
7 > < < 7 9 2 9 > 5 xxxx 4 3 > 2 3 1 2 > * + * - + 1 / 9 9
2 2 xx + 4 - < 4 2 9 0 1 - + 0 - 1 9xxxx5 / + 0 0 < 8 > 7
test
xxxx
9150000xxxxA
重慶市xxxxxxxx號(hào)、7號(hào)xxxxx-xxxxx
招商銀行1xxxxxxxxxx0
15xxxxxx1666
544xxxxx880
2019年04月10日
151xxx1 89xx13 56xx5 85xx80
¥1.06
第二種 使用國(guó)產(chǎn)的框架 Spire.PDF
包含兩種版本
1 免費(fèi)版
https://www.e-iceblue.cn/Downloads/Free-Spire-PDF-JAVA.html
友情提示: 免費(fèi)版有 10 頁(yè)的頁(yè)數(shù)輸出限制,在輸出結(jié)果文檔時(shí)只能輸出前10頁(yè)。將 PDF 文檔轉(zhuǎn)換為圖片、Word、HTML、XPS等格式時(shí),僅支持轉(zhuǎn)換前 10 頁(yè)。如超出限制,可升級(jí)到商業(yè)版,我們僅對(duì)免費(fèi)版進(jìn)行不定期維護(hù)。
2 商業(yè)版本
https://www.e-iceblue.cn/Introduce/Spire-PDF-JAVA.html
api
http://e-iceblue.cn/licensing/install-spirepdf-for-java-from-maven-repository.html
特點(diǎn):商業(yè)版本收費(fèi),免費(fèi)版本有限制,可供開(kāi)發(fā)人員調(diào)試,解析格式友好,解析結(jié)果是按照行顯示,對(duì)pdf 圖形 ,水印 ,文本, 條形碼等添加增刪改操作,總之個(gè)人感覺(jué)比pdfbox順手,但就是收費(fèi)啊,誰(shuí)讓咱公司沒(méi)錢(qián)呢。
主要功能
只需 Free Spire.PDF for Java,無(wú)需 Adobe Acrobat
Free Spire.PDF for Java 是一款完全獨(dú)立的 PDF 類(lèi)庫(kù)。它的運(yùn)行環(huán)境無(wú)需安裝 Adobe Acrobat 或其他任何第三方組件。
多樣化的PDF文檔操作功能
Free Spire.PDF for Java 支持畫(huà)文本、圖片、表格、條形碼、形狀到 PDF,提取文本和圖片,創(chuàng)建、填充和刪除 PDF 表單,添加文本/圖片水印到 PDF,添加、更新和刪除 PDF 書(shū)簽,操作超鏈接、附件和注釋?zhuān)约疤砑訄D片/文本印章到 PDF 等。
文檔信息設(shè)置
Free Spire.PDF for Java 支持設(shè)置 PDF 文檔信息,例如文檔屬性設(shè)置,偏好設(shè)置(頁(yè)面方向,頁(yè)面大小,縮放比例等)。
高質(zhì)量的文檔轉(zhuǎn)換功能
Free Spire.PDF for Java 支持將 PDF 文檔高質(zhì)量地轉(zhuǎn)換為 Word、HTML、XPS、圖片、SVG 和 PDF/A 格式,以及將 XPS 文檔高質(zhì)量地轉(zhuǎn)換為 PDF 格式。
文檔安全性設(shè)置
Free Spire.PDF for Java 支持給 PDF 文檔添加和驗(yàn)證數(shù)字簽名,加密和解密 PDF 文檔,修改 PDF 文檔的安全權(quán)限,以及檢測(cè)簽名后的 PDF 文檔是否被修改。
易于集成
開(kāi)發(fā)人員可以輕易地將 Free Spire.PDF for Java 集成到 Java(J2SE和J2EE)應(yīng)用程序中。
api 更多功能如下圖
1 倉(cāng)庫(kù)地址 和 依賴(lài)
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf.free</artifactId>
<version>2.2.2</version>
</dependency>
<
2 代碼
//創(chuàng)建PdfDocument實(shí)例
PdfDocument doc = new PdfDocument();
//加載PDF文件
doc.loadFromFile("C:\\Users\\tizzy\\Desktop\\測(cè)試.pdf");
//創(chuàng)建StringBuilder實(shí)例
StringBuilder sb = new StringBuilder();
PdfPageBase page;
//遍歷PDF頁(yè)面,獲取每個(gè)頁(yè)面的文本并添加到StringBuilder對(duì)象
for(int i= 0;i<doc.getPages().getCount();i++){
page = doc.getPages().get(i);
sb.append(page.extractText(true));
}
FileWriter writer;
try {
//將StringBuilder對(duì)象中的文本寫(xiě)入到文本文件
writer = new FileWriter("ExtractText.txt");
writer.write(sb.toString());
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
doc.close();
解析后格式內(nèi)容如圖
第三種 使用iTika 進(jìn)行解析pdf
api : https://tika.apache.org/
對(duì)中文支持不是很友好,解析的格式和pdfbox類(lèi)似
1依賴(lài)
<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-core -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.20</version>
</dependency>
2 代碼
public static String getPdfFileText(String fileName) throws IOException {
PdfReader reader = new PdfReader(fileName);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
StringBuffer buff = new StringBuffer();
TextExtractionStrategy strategy;
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
strategy = parser.processContent(i,
new SimpleTextExtractionStrategy());
buff.append(strategy.getResultantText());
}
return buff.toString();
}
解析后內(nèi)容格式類(lèi)似pdfbox
總結(jié)
幾種方式各有利弊,開(kāi)源也罷,閉源也罷,其中利弊自己權(quán)衡。