Java使用PDFBOX操作pdf文件(一,加载和创建pdf)
前言:
之前想学习使用Java操作pdf的时候看过了IText的文档。确实IText的文档很全,也有一个官网可以很方便的查找信息。但IText的开源协议为AGPL,使用者必须传染性的开源代码,商业使用必须付费获取商业许可。所以有一些风险。所以转而来学习使用PDFBOX。现在pdfbox的文档并不是很多,列出如下链接以做参考。
https://iowiki.com/pdfbox/pdfbox_quick_guide.html
如果需要源码进行研究,可以在https://www.apache.org/dyn/closer.lua/pdfbox/2.0.25/pdfbox-2.0.25-src.zip下载使用
有一些坑在网上的资料也比较少,也可以到https://issues.apache.org/jira/browse/PDFBOX-5103里查找相关的issue(英文),如果你找到了bug也可以往里提。
一.加载已有的pdf文件
1.加载全文/页的文本
注意:PDFBOX依赖commons-logging,fontbox包,使用请确保fontbox与pdfbox的版本相同,不然可能会有兼容BUG(亲测)具体信息可以查看:https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox/2.0.25先准备一个pdf文件(有内容的),如下:
通过加载PDF文件获取文本内容:
public class LoadPDF {public static void main(String[] args) throws FileNotFoundException, IOException {//通过文件和输入流都可以加载pdf文件PDDocument doc = PDDocument.load(new FileInputStream("src/Target.pdf"));PDFTextStripper text = new PDFTextStripper();//获取全文件的所有文本String FinalText = text.getText(doc);System.out.println(FinalText);//关闭doc.close();}}
运行:
邮政银行卡类型查询指引
方法一:拨打中国邮政储蓄银行电话“95580”查询。
方法二:携带本人身份证及银行卡至邮政银行网点查询。
方法三:手机网银查询,步骤如下图:打开手机APP<邮储银行>,点击”我的“,点击"银行卡",查看薪资卡类型。
这样便很容易通过正则表达式进行内容的提取了。比如常见的一些招聘模块,通常有上传pdf简历的功能,这样大致也可以实现,只是方法有些不同。
2.加载保存pdf中的图片信息
当然,我们也可以从PDF文件中读取图片信息。
//打开PDF文件PDDocument doc = PDDocument.load(new FileInputStream("src/Target.pdf"));//获取第一页的数据PDPage pageOne = doc.getPage(0);//获取页面resourcesPDResources resources = pageOne.getResources();//获取COS对象的名字集合(如果不了解什么是COS对象,请参考这个链接//https://www.pdftron.com/documentation/cli/guides/pdf-cosedit/faq/#what-is-cosIterable<COSName> xObjectNames = resources.getXObjectNames();//遍历COS对象xObjectNames.forEach(item->{try {PDXObject xObject = resources.getXObject(item);System.out.println(item.getName());//如果为图片类型就调Java的图片处理接口,将其保存下来if(xObject instanceof PDImageXObject) {PDImageXObject imgobject = (PDImageXObject)xObject;BufferedImage image = imgobject.getImage();ImageIO.write(image, "png", new File("第"+Count+"张图片.png"));System.out.println("ImageSaved");Count++;}} catch (IOException e) {System.out.println("图片保存出错");e.printStackTrace();}});
运行:
二.创建普通的pdf文件
创建一个空的pdf非常的简单,只需要创建然后保存即可
PDDocument doc = new PDDocument();
doc.save(null);
如果要写入内容,需要使用PDFBOX提供的流对象进行写入。
写入英文
写入英文文本是不需要设置任何额外的东西,直接向流里面丢就可以了。
public static void main(String[] args) throws IOException {//创建文件,设置页码PDDocument doc = new PDDocument();PDPage pageOne = new PDPage(PDRectangle.A4);doc.addPage(pageOne);//创建页面内容流PDPageContentStream pageStream = new PDPageContentStream(doc, pageOne);//设置要使用的字体PDFont font = PDType1Font.COURIER_BOLD_OBLIQUE;pageStream.setFont(font,18);pageStream.beginText();//直接写入内容即可pageStream.showText("hello pdfbox");pageStream.endText();//记得关闭流对象要不然是无法成功保存pdf文档的pageStream.close();doc.save(new File("src\\hello.pdf"));doc.close();
}
看一下效果
内容是写上去了,但感觉位置如果不指定的话是随机的,下一节应该学习一下如下指定文字及图片绘制的位置。
写入中文
中文的写入则更加复杂。
如果直接把上述代码的写入字符串变成中文,则会出现如下异常
pageStream.showText("想要写入一些中文,但是会报错");
异常的详细信息:
Exception in thread "main" java.lang.IllegalArgumentException: U+6BD4 ('.notdef') is not available in this font Courier-BoldOblique encoding: WinAnsiEncodingat org.apache.pdfbox.pdmodel.font.PDType1Font.encode(PDType1Font.java:428)at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:333)at org.apache.pdfbox.pdmodel.PDAbstractContentStream.showTextInternal(PDAbstractContentStream.java:300)at org.apache.pdfbox.pdmodel.PDAbstractContentStream.showText(PDAbstractContentStream.java:254)at org.apache.pdfbox.pdmodel.PDPageContentStream.showText(PDPageContentStream.java:37)at PDFBOX3.MainTest.main(MainTest.java:35)
这是因为在pdf的14种原生的字体中并不支持中文(在PDFType1Font中可以通过静态属性列出),
如果需要写入中文,可以通过嵌入中文字体文件(支持中文的.ttf文件)或者直接从本地导入。
所以请先自备中文字体。(或者可以直接去C盘里找,路径为C:/Windows/Fonts)
现在,先加载中文字体就好了。
private static final float MARGIN_LEFT = 0.8f * 72; // 0.8 inchprivate static final float MARGIN_TOP = 0.4f * 72; // 0.4 inchprivate static final float LOGO_WIDTH = 72;private static final float LOGO_MARGIN = 18;private static final float FONT_SIZE_TITLE = 24;private static final float FONT_SIZE_SMALL = 10;private static final float LINE_OFFSET_FACTOR = -1.8f;/*** @param args* @throws IOException*/public static void main(String[] args) throws IOException {//创建文档和页面PDDocument document = new PDDocument();PDPage page = new PDPage(PDRectangle.A4);document.addPage(page);@SuppressWarnings("resource")PDPageContentStream contentStream = new PDPageContentStream(document, page);PDRectangle boundingBox = page.getBBox();contentStream.beginText();//加载字体文件contentStream.setFont(PDType0Font.load(document, MainTest.class.getResourceAsStream("SimHei.ttf")),24);contentStream.newLineAtOffset(MARGIN_LEFT + LOGO_WIDTH + LOGO_MARGIN,boundingBox.getHeight() - MARGIN_TOP - FONT_SIZE_TITLE);//写入中文 contentStream.showText("中国你好!");contentStream.newLineAtOffset(0, LINE_OFFSET_FACTOR * FONT_SIZE_SMALL);contentStream.showText("RiderKick");contentStream.endText();contentStream.close();document.save(new File("Chinese.pdf"));document.close();}
写入图片
写入图片和写入文字一样,只需要将图片加载到PDImageXObject里,然后再从对象流中写入文档即可
以下图为例
public static void main(String[] args) throws IOException {PDDocument doc = new PDDocument();PDPage pageOne = new PDPage(PDRectangle.A4);doc.addPage(pageOne);PDPageContentStream pageStream = new PDPageContentStream(doc, pageOne);PDFont font = PDType1Font.COURIER_BOLD_OBLIQUE;PDImageXObject img = PDImageXObject.createFromFile("src/PDFBOX3/AutoFac.png", doc);pageStream.setFont(font,18);pageStream.beginText();pageStream.showText("hi this is AutoFac");pageStream.endText();pageStream.drawImage(img, 50, 50);pageStream.close();doc.save(new File("src\\hello.pdf"));doc.close();}
Java使用PDFBOX操作pdf文件(一,加载和创建pdf)相关推荐
- PDF文件的加载及展示
项目需要显示PDF文件,于是遍寻了网络,发现的方法以下几种: 1.使用UIWebView加载,没啥说的,根据文件路径,网络或者本地皆可,创建一个NSURLRequest,然后用webView加载就可以 ...
- android 上传pdf文件,Android 加载PDF文件
今天按项目要求找了一个android的PDF控件,各种操作效果都非常好,在这里和大家分享一下. 用法很简单: 1.在build.gradle里面添加依赖 compile 'com.github.bar ...
- 如何从服务器上取pdf文件,如何从服务器响应创建pdf文件?
我在一个应用程序中工作,我需要从服务器上得到的响应创建pdf文件.有没有任何方法可以使用此响应创建pdf?反应如下: %PDF-1.4 %���� 2 0 obj <>st ...
- django-2 模板文件的加载
django-2 模板文件的加载 1.创建模板文件 index.html 2.在django使用模板文件 需要在app下创建templates文件夹 此为django固定模板文件位置 3.编辑 ...
- Java使用PDFBox操作PDF文件
1首先,导入jar (maven方式导入) PS: 这个jar里面囊括了所有的pdfbox操作工具类,导入这一个就够了 <dependency><groupId>org.apa ...
- Android加载预览PDF文件
从去年9月份进入新公司后,项目中需要在APP中展示PDF,这个之前没有接触过,因此也查了好多的资料和demo,这里我说明下我用过的pdf展示比较好点View或者第三方,本人亲测. 1.使用Google ...
- 导入Java文件还是class文件_java程序运行的时候,是把所有的class文件都加载到内存吗?还是用的什么加载什么?...
这一块还没有深入了解,不敢误人子弟. 我知道的,虚拟机在运行的时候,会预先加载一个常用的class,比如java.lang包下面的. 至于你在程序中自己引用的class文件/jar包之类的,是有一个加 ...
- java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)
相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...
- html 加载pdf文件内容不显示不出来,pdf.js首次加载pdf文件时找不到pdf文件,刷新后才能出现pdf文件...
前台点击文件学码的定一近,更工广款近,更工广款近,更名后,后台通过openoffice将doc文件转为pdf格式文件,然后存放在服务器tomcat'中,pdf.js首次加载服务器中tomcat中的转化 ...
最新文章
- ubuntu14.04系统扩容的方法
- iptables加载顺序问题及优化方法
- BZOJ3144: [Hnoi2013]切糕
- C++接收字符串数组_电脑编程 你该知道的字符知识 C语言程序设计字符数组全归纳...
- 计算机网络基础应用课程标准,王建波《计算机网络基础》课程标准.doc
- Windows XP 默认蓝色桌面的 RGB
- 华为eNSP Windows10安装教程及错误讲解
- 口腔行业的隐形冠军,现代牙科集团掘金步入新阶段
- AD快捷键无法使用的解决方法
- 学校教学的计算机网络教室它的网络类型,用于学校教学的计算机网络教室,它的网络类型属于( )...
- 电脑中病毒以后,如何删掉右键残留的菜单
- HALCON联合C#检测表面缺陷——检测缺陷原理(三)
- 两台设备(手动)设置相同的局域网IP地址会怎么样?
- 蓝绿红黑灰|常用的发布方式
- Python 简单编写一个注册邮箱
- 视频CMS是什么?你为什么需要它?
- 个人计算机使用的标准键盘,电脑键盘的基本操作规范 -电脑资料
- Kubectl(完整)基本操作命令
- 《塞尔达传说:旷野之息》技术分析:游戏神作是怎么炼成的
- scal 解析json字符串