java解析pdf获取pdf中内容信息

java解析pdf获取pdf中内容信息

今日项目中需要将pdf中的数据获取到进行校验数据,于是前往百度翻来覆去找到以下几种办法,做个笔记,方便日后查询。

废话不多说,我要直接上代码装逼了

第一种 使用开源组织提供的开源框架 pdfbox

api ; https://pdfbox.apache.org/

特点:免费,功能强大,解析中文或许会存在乱码,格式有点乱,没有国产解析的那么美化。

想要按行读取:

          PDFTextStripper stripper = new PDFTextStripper();
            stripper .setSortByPosition(sort); //sort设置为true 则按照行进行读取,默认是false

可以按照指定的模板,对pdf进行修改添加删除等操作,总之操作很骚,很强大。

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";  //仿宋常规
    public static final String CHARACTOR_FONT_CH_FILE = "SIMHEI.TTF";  //黑体常规

    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;

    /**
     * 功能:创建导出数据的目标文档
     * @param fileName 存储文件的临时路径
     * @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();
        }
        // 打开文档准备写入内容
        document.open();
    }

    /**
     * 将章节写入到指定的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();
        }
    }

    /**
     * 功能  创建PDF文档中的章节
     * @param title 章节标题
     * @param chapterNum 章节序列号
     * @param alignment 0表示align=left,1表示align=center
     * @param numberDepth 章节是否带序号 设值=1 表示带序号 1.章节一;1.1小节一...,设值=0表示不带序号
     * @param font 字体格式
     * @return Chapter章节
     */
    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;
    }

    /**
     * 功能:创建某指定章节下的小节
     * @param chapter 指定章节
     * @param title 小节标题
     * @param font 字体格式
     * @param numberDepth 小节是否带序号 设值=1 表示带序号 1.章节一;1.1小节一...,设值=0表示不带序号
     * @return section在指定章节后追加小节
     */
    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文档中添加的内容
     * @param text 内容
     * @param font 内容对应的字体
     * @return phrase 指定字体格式的内容
     */
    public static Phrase createPhrase(String text,Font font) {
        Phrase phrase = new Paragraph(text,font);
        return phrase;
    }

    /**
     * 功能:创建列表
     * @param numbered  设置为 true 表明想创建一个进行编号的列表
     * @param lettered 设置为true表示列表采用字母进行编号,为false则用数字进行编号
     * @param symbolIndent
     * @return list
     */
    public static List createList(boolean numbered, boolean lettered, float symbolIndent) {
        List list = new List(numbered, lettered, symbolIndent);
        return list;
    }

    /**
     * 功能:创建列表中的项
     * @param content 列表项中的内容
     * @param font 字体格式
     * @return listItem
     */
    public static ListItem createListItem(String content, Font font) {
        ListItem listItem = new ListItem(content, font);
        return listItem;
    }

    /**
     * 功能:创造字体格式
     * @param fontname
     * @param size 字体大小
     * @param style 字体风格
     * @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 字体风格
     * @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);
    }

    /**
     * 最后关闭PDF文档
     */
    public void closeDocument() {
        if(document != null) {
            document.close();
        }
    }


    /**
     * 读PDF文件,使用了pdfbox开源项目
     * @param fileName
     */
    public static  void readPDF(String fileName) {
        File file = new File(fileName);
        FileInputStream in = null;
        try {
            in = new FileInputStream(fileName);
            // 新建一个PDF解析器对象
            PDFParser parser = new PDFParser(new RandomAccessFile(file,"rw"));
            // 对PDF文件进行解析
            parser.parse();
            // 获取解析后得到的PDF文档对象
            PDDocument pdfdocument = parser.getPDDocument();
            // 新建一个PDF文本剥离器
            PDFTextStripper stripper = new PDFTextStripper();
            // 从PDF文档对象中剥离文本
            String result = stripper.getText(pdfdocument);
            FileWriter fileWriter = new FileWriter(new File("pdf.txt"));
            fileWriter.write(result);
            fileWriter.flush();
            fileWriter.close();
            System.out.println("PDF文件的文本内容如下:");
            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) {
                }
            }
        }
    }


    /**
     * 测试pdf文件的创建
     * @param args
     */
    public static void main(String[] args) {

        String fileName = "C:\Users\tizzy\Desktop\测试.pdf";  //这里先手动把绝对路径的文件夹给补上。
        PDFUtil pdfUtil = new PDFUtil();
        pdfUtil.writeChapterToDoc(chapter);
        pdfUtil.closeDocument();
    }
}

解析后的内容格式

合 计
备
注
xxxxxxxxxxx普通发票
价税合计(大写) (小写)
货物或应税劳务、服务名称 规格型号 单位 数 量 单 价 金 额 税率 税 额
购
买
方
销
售
方
收 款 人: 复 核: 开 票 人: 销 售 方:(章)
密
码
区
机器编号:
名    称:
纳税人识别号:
地 址、
开户行及账号:
名    称:
纳税人识别号:
地 址、
开户行及账号:
发票代码:
发票号码:
开票日期:
校 验 码:
电 话:
电 话:
¥1.00 ¥0.06
*xxxxxxxxxxx 1 1 1.00 6% 0.06
499111xxx80
壹圆零陆分
收款人 复核人 开票人
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号、7号xxxxx-xxxxx
招商银行1xxxxxxxxxx0
15xxxxxx1666
544xxxxx880
2019年04月10日
151xxx1 89xx13 56xx5 85xx80
¥1.06

第二种 使用国产的框架 Spire.PDF

包含两种版本

1 免费版
https://www.e-iceblue.cn/Downloads/Free-Spire-PDF-JAVA.html

友情提示: 免费版有 10 页的页数输出限制,在输出结果文档时只能输出前10页。将 PDF 文档转换为图片、Word、HTML、XPS等格式时,仅支持转换前 10 页。如超出限制,可升级到商业版,我们仅对免费版进行不定期维护。

2 商业版本
https://www.e-iceblue.cn/Introduce/Spire-PDF-JAVA.html

api
http://e-iceblue.cn/licensing/install-spirepdf-for-java-from-maven-repository.html

特点:商业版本收费,免费版本有限制,可供开发人员调试,解析格式友好,解析结果是按照行显示,对pdf 图形 ,水印 ,文本, 条形码等添加增删改操作,总之个人感觉比pdfbox顺手,但就是收费啊,谁让咱公司没钱呢。

主要功能

只需 Free Spire.PDF for Java,无需 Adobe Acrobat
Free Spire.PDF for Java 是一款完全独立的 PDF 类库。它的运行环境无需安装 Adobe Acrobat 或其他任何第三方组件。
多样化的PDF文档操作功能
Free Spire.PDF for Java 支持画文本、图片、表格、条形码、形状到 PDF,提取文本和图片,创建、填充和删除 PDF 表单,添加文本/图片水印到 PDF,添加、更新和删除 PDF 书签,操作超链接、附件和注释,以及添加图片/文本印章到 PDF 等。
文档信息设置
Free Spire.PDF for Java 支持设置 PDF 文档信息,例如文档属性设置,偏好设置(页面方向,页面大小,缩放比例等)。
高质量的文档转换功能
Free Spire.PDF for Java 支持将 PDF 文档高质量地转换为 Word、HTML、XPS、图片、SVG 和 PDF/A 格式,以及将 XPS 文档高质量地转换为 PDF 格式。
文档安全性设置
Free Spire.PDF for Java 支持给 PDF 文档添加和验证数字签名,加密和解密 PDF 文档,修改 PDF 文档的安全权限,以及检测签名后的 PDF 文档是否被修改。
易于集成
开发人员可以轻易地将 Free Spire.PDF for Java 集成到 Java(J2SE和J2EE)应用程序中。

api 更多功能如下图


在这里插入图片描述
在这里插入图片描述

1 仓库地址 和 依赖

<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 代码

//创建PdfDocument实例
PdfDocument doc = new PdfDocument();
//加载PDF文件
doc.loadFromFile("C:\\Users\\tizzy\\Desktop\\测试.pdf");

//创建StringBuilder实例
StringBuilder sb = new StringBuilder();

PdfPageBase page;
//遍历PDF页面,获取每个页面的文本并添加到StringBuilder对象
for(int i= 0;i<doc.getPages().getCount();i++){
    page = doc.getPages().get(i);
    sb.append(page.extractText(true));
}
FileWriter writer;
try {
    //将StringBuilder对象中的文本写入到文本文件
    writer = new FileWriter("ExtractText.txt");
    writer.write(sb.toString());
    writer.flush();
} catch (IOException e) {
    e.printStackTrace();
}

doc.close();

解析后格式内容如图

在这里插入图片描述

第三种 使用iTika 进行解析pdf

api : https://tika.apache.org/

对中文支持不是很友好,解析的格式和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();
      }

解析后内容格式类似pdfbox

总结

几种方式各有利弊,开源也罢,闭源也罢,其中利弊自己权衡。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容