java解析pdf獲取pdf中內(nèi)容信息
今日項(xiàng)目中需要將pdf中的數(shù)據(jù)獲取到進(jìn)行校驗(yàn)數(shù)據(jù)强品,于是前往百度翻來(lái)覆去找到以下幾種辦法酵颁,做個(gè)筆記,方便日后查詢送矩。
廢話不多說(shuō),我要直接上代碼裝逼了
第一種 使用開源組織提供的開源框架 pdfbox
api 舌镶; https://pdfbox.apache.org/
特點(diǎn):免費(fèi),功能強(qiáng)大豪娜,解析中文或許會(huì)存在亂碼餐胀,格式有點(diǎn)亂,沒(méi)有國(guó)產(chǎn)解析的那么美化瘤载。
想要按行讀确裨帧:
PDFTextStripper stripper = new PDFTextStripper();
stripper .setSortByPosition(sort); //sort設(shè)置為true 則按照行進(jìn)行讀取,默認(rèn)是false
可以按照指定的模板鸣奔,對(duì)pdf進(jìn)行修改添加刪除等操作墨技,總之操作很騷,很強(qiáng)大挎狸。
1 pdfbox 需要帶入依賴
<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讀寫類
* @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();
}
// 打開文檔準(zhǔn)備寫入內(nèi)容
document.open();
}
/**
* 將章節(jié)寫入到指定的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開源項(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ì)(大寫) (小寫)
貨物或應(yīng)稅勞務(wù)、服務(wù)名稱 規(guī)格型號(hào) 單位 數(shù) 量 單 價(jià) 金 額 稅率 稅 額
購(gòu)
買
方
銷
售
方
收 款 人: 復(fù) 核: 開 票 人: 銷 售 方:(章)
密
碼
區(qū)
機(jī)器編號(hào):
名 稱:
納稅人識(shí)別號(hào):
地 址鞭衩、
開戶行及賬號(hào):
名 稱:
納稅人識(shí)別號(hào):
地 址学搜、
開戶行及賬號(hào):
發(fā)票代碼:
發(fā)票號(hào)碼:
開票日期:
校 驗(yàn) 碼:
電 話:
電 話:
¥1.00 ¥0.06
*xxxxxxxxxxx 1 1 1.00 6% 0.06
499111xxx80
壹圓零陸分
收款人 復(fù)核人 開票人
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)版本有限制暮屡,可供開發(fā)人員調(diào)試,解析格式友好毅桃,解析結(jié)果是按照行顯示,對(duì)pdf 圖形 褒纲,水印 ,文本钥飞, 條形碼等添加增刪改操作外厂,總之個(gè)人感覺(jué)比pdfbox順手,但就是收費(fèi)啊代承,誰(shuí)讓咱公司沒(méi)錢呢汁蝶。
主要功能
只需 Free Spire.PDF for Java,無(wú)需 Adobe Acrobat
Free Spire.PDF for Java 是一款完全獨(dú)立的 PDF 類庫(kù)论悴。它的運(yùn)行環(huán)境無(wú)需安裝 Adobe Acrobat 或其他任何第三方組件掖棉。
多樣化的PDF文檔操作功能
Free Spire.PDF for Java 支持畫文本、圖片膀估、表格幔亥、條形碼、形狀到 PDF察纯,提取文本和圖片帕棉,創(chuàng)建、填充和刪除 PDF 表單饼记,添加文本/圖片水印到 PDF香伴,添加、更新和刪除 PDF 書簽具则,操作超鏈接即纲、附件和注釋,以及添加圖片/文本印章到 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 文檔是否被修改兼砖。
易于集成
開發(fā)人員可以輕易地將 Free Spire.PDF for Java 集成到 Java(J2SE和J2EE)應(yīng)用程序中奸远。
api 更多功能如下圖
1 倉(cāng)庫(kù)地址 和 依賴
<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ì)象中的文本寫入到文本文件
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類似
1依賴
<!-- 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)容格式類似pdfbox
總結(jié)
幾種方式各有利弊懒叛,開源也罷,閉源也罷耽梅,其中利弊自己權(quán)衡薛窥。