spire.pdf 使用学习记录

  • 背景
  • 简介
  • 相似产品及特点
  • 官网地址
  • 功能实现
    • 切割pdf
      • 按每页切割
      • 按指定页切割
    • 将pdf转成txt
    • 识别pdf中的篇章节生成对应文本
    • 去除水印
    • 获取书签
    • 获取每页中图片
    • 项目地址

背景

通过打印机将一本纸质书转为pdf的格式,以下所有操作都是在这个基础上操作,最终目的生成n篇txt文件,每个txt名字规则是:起始页_篇&章&节 内容:是对应切割的内容;

简介

这是一款基于OCR框架的解析工具,拥有比价完整的Java 类库,及完善的API文档,不但具备pdf的读写,还支持文本和图片的提取,水印的添加,书签的增删改,表格的操作,同时还支持,将pdf转化成word、HTML、XPS、SVG、等多种方式;当然目前这类工具市面上有很多,不过通过比较最后选择了spire.pdf ;目前这款项目共有两个版本,一个是免费版本一个是付费版本,免费版本如果只是处理简单的pdf是没问题的,但是如果涉及到输出为pdf则会只显示前10页,第十一页则是预定的购买页介绍,不过介于spire.pdf的完善性我最后还是选择了他,至于10页的问题,后面会拿出我的处理办法,如果你是其他语言如.NET、Android、也可以使用这款产品;

相似产品及特点

  • PDFBox
  • itext
  • 百度
  • Tesseract 只能用于识别图片,如果需要先将pdf转为图片

官网地址

https://www.e-iceblue.cn/Introduce/Free-Spire-PDF-JAVA.html

功能实现

前往官网下载jar包或者直接在maven上通过坐标也可实现,不过maven上的肯定没有网页下载的新;

<!-- 事先配置maven仓库路径-->
<repositories><repository><id>com.e-iceblue</id><url>http://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories><!--maven中 spire.pdf镜像依赖-->
<dependencies><dependency><groupId> e-iceblue </groupId><artifactId>spire.pdf.free</artifactId><version>3.11.6</version></dependency>
</dependencies>

切割pdf

按每页切割

    /***每一页生成一个pdf文档*/public static void splitPdfOneByOne(){PdfDocument pdf = new PdfDocument();int count = pdf.getPages().getCount();System.out.println(count);pdf.loadFromFile("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\book.pdf");pdf.split("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\output\\surgery_{0}.pdf",0);pdf.close();}

按指定页切割

package com.wangcc.wangccocrdemo001.ocr;import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.graphics.PdfMargins;
import com.wangcc.wangccocrdemo001.util.FileUtil;import java.awt.geom.Point2D;
import java.io.File;/*** 拆分文档* 拆成每页一个* 拆成每九页一个(免费版最多只能处理九页)* @author wangcc* @createTime 2021年08月31日 23:25:00*/
public class SubPDF {/*** 每九页生成一个pdf**/public static void splitPdfMoreByOne(){String fileName = "C:\\Users\\wangchenchen\\Desktop\\boot-structure\\book.pdf";String outPath = "C:\\Users\\wangchenchen\\Desktop\\boot-structure\\outFile\\outPDFByMore";PdfDocument pdf = new PdfDocument();pdf.loadFromFile(fileName);int totalCount = pdf.getPages().getCount();PdfPageBase pageBase;PdfDocument document = new PdfDocument();int count = 1;for(int i = 41; i< 822;i++){System.out.println(i+"/"+822);pageBase = document.getPages().add(pdf.getPages().get(i).getSize(),new PdfMargins(0));pdf.getPages().get(i).createTemplate().draw(pageBase, new Point2D.Float(0,0));if(count % 9 == 0){String path = "\\splitPdf-"+i+".pdf";document.saveToFile(outPath+path);document = new PdfDocument();}count++;}if(document.getPages().getCount() >0){String path = "\\splitPdf-999999.pdf";document.saveToFile(outPath+path);}}/*** @Description //* @return void**/public static void splitPdfByNumber(Integer begin, Integer end,String filePath,String pdfOutPath){if(begin.equals("") || end.equals("") || filePath.equals("") || pdfOutPath.equals("")){System.out.println("传入参数有空.......");return;}if(begin >= end){System.out.println("截止页数不能小于或等于开始页数.......");return;}if(end-begin > 9){System.out.println("操作页数最多为9页");return;}File file = new File(pdfOutPath);if (file.exists()){FileUtil fileUtil = new FileUtil();fileUtil.DeleteFolder(pdfOutPath);}PdfDocument pdf = new PdfDocument();pdf.loadFromFile(filePath);int totalCount = pdf.getPages().getCount();PdfPageBase pageBase;PdfDocument document = new PdfDocument();for(int i = begin; i< end;i++){System.out.println(i+"/"+end);pageBase = document.getPages().add(pdf.getPages().get(i).getSize(),new PdfMargins(0));pdf.getPages().get(i).createTemplate().draw(pageBase, new Point2D.Float(0,0));String path = "\\surgery_"+i+".pdf";document.saveToFile(pdfOutPath+path);document = new PdfDocument();}}
}

将pdf转成txt

package com.wangcc.wangccocrdemo001.ocr;import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 读取所有拆分文件生成txt文件* @author wangcc* @createTime 2021年08月31日 23:51:00*/
public class ReadAllSplitFile {public static String fileName = "C:\\Users\\wangchenchen\\Desktop\\boot-structure\\outFile\\outPDFByMore\\";public static String outPath = "C:\\Users\\wangchenchen\\Desktop\\boot-structure\\outFile\\readPdfFile.txt";public static void main(String[] args) {List<File> fileList = readAllFile();List<String> pdfFileNameList = new ArrayList<>();for (File file:fileList) {pdfFileNameList.add(file.getName());}Collections.sort(pdfFileNameList, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int n1 = extractNumber(o1);int n2 = extractNumber(o2);return n1 - n2;}});File file = new File(outPath);if(file.exists()){file.delete();}for (String s:pdfFileNameList) {try {readFile(s);} catch (IOException e) {e.printStackTrace();}}}public static List<File> readAllFile(){String filePath = "C:\\Users\\wangchenchen\\Desktop\\boot-structure\\outFile\\outPDFByMore";ArrayList<File> fileList = new ArrayList<>();File file = new File(filePath);File[] files = file.listFiles();if(Objects.isNull(files)){return null;}for (File f:files) {if(f.isFile()){fileList.add(f);}}return fileList;}/*** @Param  orderStr 排序:asc,des,不区分大小写**/public static List<File> sortFileByName(List<File> fileList, final String orderStr){if(!orderStr.equalsIgnoreCase("asc") && !orderStr.equalsIgnoreCase("desc")){return fileList;}File[] files = fileList.toArray(new File[0]);Arrays.sort(files, new Comparator<File>() {@Overridepublic int compare(File o1, File o2) {int n1 = extractNumber(o1.getName());int n2 = extractNumber(o2.getName());if(orderStr == null || orderStr.length() < 1 || orderStr.equalsIgnoreCase("asc")){return n1 - n2;}else {//降序return n2 - n1;}}});return new ArrayList<File>(Arrays.asList(files));}public static int extractNumber(String name){int i;try {String s = name.replaceAll("[^\\d]", "");i = Integer.parseInt(s);}catch (Exception e){i = 0;}return i;}public static void readFile(String path) throws IOException {PdfDocument pdf = new PdfDocument();pdf.loadFromFile(fileName+path);PdfPageBase page;StringBuilder sb = new StringBuilder();Pattern pattern = Pattern.compile("(^(\\s*)第)(.{1,9})[章节卷集部篇回](\\s{1,10})(.{1,20})(\\s{1,10})");Pattern pattern1 = Pattern.compile("(\\s{0,10})([0-9][0-9]?[0-9]?[0-9]?)");//遍历PDF页面,获取每个页面的文本并添加到StringBuilder对象for(int i = 0;i < pdf.getPages().getCount();i++) {//System.out.println("循环遍历pdf页数:当前" + i + "页/" + pdf.getPages().getCount() + "页");page = pdf.getPages().get(i);int count = 0;String extractText = null;BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(page.extractText(true).getBytes())));while ((extractText = br.readLine())!= null){Matcher matcher = pattern.matcher(extractText);Matcher matcher1 = pattern1.matcher(extractText);/*末尾包含数字的*/if (count != 0 || matcher.find()){//System.out.println(extractText);if(!extractText.equals("") && !matcher1.find()){String s = extractText.replaceAll("\\s{5,9}", " ");sb.append(s+"\n");}}count++;}br.close();}FileWriter writer;try {//将StringBuilder对象中的文本写入到文本文件writer = new FileWriter(outPath,true);System.out.println(sb.toString());writer.write(sb.toString());writer.flush();writer.close();sb.delete(0,sb.length());} catch (IOException e) {e.printStackTrace();}pdf.close();}
}

识别pdf中的篇章节生成对应文本

去除水印

package com.wangcc.wangccocrdemo001.ocr;import com.spire.pdf.PdfDocument;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;/*** 去除水印(未必都有用,主要是看水印的类型)* 水印有两种*      1.文字,放在对应的位置*        2.大图片,png 背景透明* 一些特殊的水印原则上是去不掉的* @author wangcc* @createTime 2021年08月31日 23:46:00*/
public class ClearWaterMark {public static void main(String[] args) throws IOException {PdfDocument pdf = new PdfDocument();pdf.loadFromFile("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\out\\splitPdf-18.pdf");BufferedImage bufferedImage = null;for (int i = 0; i<pdf.getPages().getCount();i++){bufferedImage = pdf.saveAsImage(i);bufferedImage.getSubimage(bufferedImage.getMinX(),15,bufferedImage.getWidth(),bufferedImage.getHeight()-15);File saveFile = new File("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\outImg\\" + i + ".png");if(!saveFile.exists()){saveFile.mkdirs();}ImageIO.write(bufferedImage,"PNG",saveFile);bufferedImage.flush();}}
}

获取书签

package com.wangcc.wangccocrdemo001.ocr;import com.spire.pdf.PdfDocument;
import com.spire.pdf.bookmarks.PdfBookmark;
import com.spire.pdf.bookmarks.PdfBookmarkCollection;import java.io.FileWriter;
import java.io.IOException;/*** 获取书签* @author wangcc* @createTime 2021年08月31日 23:47:00*/
public class getBookMake {public static void main(String[] args) {PdfDocument pdf = new PdfDocument();pdf.loadFromFile("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\out\\splitPdf-18.pdf");PdfBookmarkCollection bookmarkCollection = pdf.getBookmarks();StringBuilder stringBuilder = new StringBuilder();/*获取书签*/GetBookMakeTitle(bookmarkCollection,stringBuilder);FileWriter writer;try {writer = new FileWriter("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\读取的书签.txt");writer.write(stringBuilder.toString());writer.flush();} catch (IOException e) {e.printStackTrace();}pdf.dispose();}public static void GetBookMakeTitle(PdfBookmarkCollection bookmarkCollection,StringBuilder stringBuilder){if(bookmarkCollection.getCount() > 0){for (int i = 0; i < bookmarkCollection.getCount(); i++){PdfBookmark bookmark = bookmarkCollection.get(i);stringBuilder.append(bookmark.getTitle());GetBookMakeTitle(bookmark,stringBuilder);}}}
}

获取每页中图片

package com.wangcc.wangccocrdemo001.ocr;import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Objects;/*** 提取每页pdf中的图片* @author wangcc* @createTime 2021年08月31日 23:41:00*/
public class ExtractImg {public static void main(String[] args) throws Exception{//加载测试文档InputStream inputStream = new BufferedInputStream(new FileInputStream(new File("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\demo.pdf")));PdfDocument pdf = new PdfDocument();//pdf.loadFromFile("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\demo.pdf");pdf.loadFromStream(inputStream);//定义一个int型变量int index = 0;//遍历PDF每一页for (int i= 0;i< pdf.getPages().getCount(); i ++){System.out.println(i+"/"+pdf.getPages().getCount());//获取PDF页面PdfPageBase page = pdf.getPages().get(i);//使用extractImages方法获取页面上图片for (BufferedImage image : page.extractImages()) {if(Objects.nonNull(image)){//指定输出图片名称File output = new File( String.format("C:\\Users\\wangchenchen\\Desktop\\boot-structure\\Img\\Image_%d.pdf", index++));//将图片保存为PNG格式文件ImageIO.write(image, "PNG", output);}}}}
}

项目地址

spire.pdf 下载

Spire.pdf-使用学习记录相关推荐

  1. 架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录

    唉   时至今日,已经不知道在嵌入式的道路上到底挣扎了多少个岁月,总感觉要"病入膏肓"了.此间总是不时出现一些疑惑:人家搞 Java.搞 C# 的动不动就是什么架构 / 框架的,搞 ...

  2. latex 三线表_LaTeX学习记录(3):使用图表

    学习记录(3):使用图表 每次跟朋友安利 的时候我都会讲这么一个故事: ❝ 当时设计天琴一号加速度计的控制器参数,出于数字控制参数切换的便利性,疯狂设计了十几套参数.然而写报告的时候傻了:老板要求每套 ...

  3. Latex学习记录2

    文章目录 Latex学习记录2 框架 命令和环境 公式 列表 代码 算法 表格 画图 浮动 目录 BIB texdoc 参考 Latex学习记录2 框架 \include \input 自己写的文件 ...

  4. 图解HTTP+彩色版 pdf版学习(更新中)

    图解HTTP+彩色版 pdf版学习 第一章 了解Web及网络基础 3.27 使用 HTTP 协议访问 Web 当我们在网页浏览器(Web browser)的地址栏中输入 URL时,Web 页面是如何呈 ...

  5. Mit6.S081学习记录

    Mit6.S081学习记录 前言 一.课程简述 二.课程资源 1,课程主页 2,参考书 3,实验环境 三.学习过程 Mit6.S081-实验环境搭建 Mit6.S081-GDB使用 Mit6.S081 ...

  6. Markdown个人学习记录

    Markdown个人学习记录 参考书籍:<了不起的Markdown>-毕小朋-电子工业出版社 第一章 Markdown概述 Markdown作为现在最流行的轻量级"写作语言&qu ...

  7. JAVA删除pdf空白页_【教程】Spire.PDF 教程:在C# 删除 PDF 中的空白页

    扫描双面打印纸张文档所创建的PDF可能包含空白页面,有时候空白页也可能是有意插入的. 在本文中,您将学习如何使用Spire.PDF检测并删除PDF文件中的空白页面. 空白页面通常被定义为不包含任何内容 ...

  8. linux个人学习记录

    linux学习记录 资料: Linux 黑马程序员_bilibili AcWing Linux基础课 可能是东半球最全面易懂的 Tmux 使用教程! Shell 教程 | 菜鸟教程 (runoob.c ...

  9. plink质控及转换文件、admixture软件学习记录

    plink质控及转换文件.admixture软件学习记录 目的:自定义ped文件和map文件,用plink质控及转换文件,使用admixture做群体结构学分析. ped文件和map文件根据格式用pa ...

  10. 【ANSYS Sherlock学习记录】Part 1、导入ODB文件

    Ansys Sherlock学习记录 最近开始学习ANSYS Sherlock 学习资料按照官方的用户指南进行学习 Chapter 1:Sherlock 入门 Chapter 2:项目工作流程指南 C ...

最新文章

  1. 神经网络 | 网络优化-线性神经网络-delta学习规则-梯度下降法(单层感知器-异或问题Python源代码)
  2. mysql 随机分组_MySql分组后随机获取每组一条数据的操作
  3. [转载].SSRAM、SDRAM和Flash简要介绍
  4. 星期五基准功能Java
  5. linux 高可用----keepalived+lvs
  6. 数据库基础:什么是列?数据类型是什么?
  7. 我和老公清北毕业,我能接受自己的孩子读三流学校吗?
  8. java unit scanner_Java输入输出常用类Scanner
  9. 计算机科学导论实验报告,上海电力学院计算机导论实验报告.docx
  10. 我的理解之JAVA中的4种访问权限
  11. 计算机专业名词TIME,date
  12. SpringMVC基础三
  13. swift 和 oc混编 找不到头文件等问题
  14. matlab三大重要数组之胞元数组
  15. MayaDay3模型模块:插入循环边
  16. spark 的第一个程序 WordCount(详细注释版)
  17. iOS微信授权登录中Universal Link(通用链接)的配置 ,解决ios13,ios14微信支付不走回调问题
  18. 我用ChatGPT做直播技术选型,卷死了同事
  19. 测试颜色度的软件是什么情况,颜色的秘密:为何需要色彩分析仪测量颜色
  20. 可视化图表之奥妙——百分比堆叠柱状图

热门文章

  1. matlab时变函数,MATLAB在《复变函数》教学中的应用(图文)
  2. C# Json转对象(object)
  3. 大白话理解LSTM神经网络(附实例讲解)
  4. 生鲜网超MySQL_天天生鲜项目实战-思路 数据库设计
  5. plc单片机组态软件php_学习plc单片机组态软件,嵌入式的一些心得
  6. MyBatis下载与简介
  7. P2 邹博机器学习logistic回归
  8. 特种作业操作电工作业2021年电力电缆考试题库
  9. 使用java的姿势完善【年、月、周】个人工作量总结
  10. 软件开发中的非功能需求类型