java解析pdf獲取pdf中內(nèi)容信息

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)衡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容