我是如何接触到PDFBox的
疫情期间,周末在家老实呆着,女友在学法律,但女友学习法律的pdf文件资料里每页都有一些类似培训机构联系方式的一些文字,共三四百页,用普通的编辑软件删除不了,如果要删除的话必须开通会员,也可能我没找到免费的软件吧,我国的办公编辑软件也真够可以的了,编辑个PDF还要收费,我是程序员,也明白软件开发需要成本和消耗,但如果作为大众使用者还是接受不了收费软件.于是乎,作为猿的我只能自己研究下怎么自己写代码去掉那些不怎么好看的文字,上网查找资料有哪些基于Java的类库可以读取PDF,就找到了很多猿都用的PDFBox,PDFBox同样是来自给我们猿贡献了很多免费软件的Apache基金会.
Apache PDFBox介绍
直接去官网Apache PDFBox,看版本已经发布到2.0了,首页说该类库的功能对PDF文件有:创建,提取文字,分割合并,填写表格,打印,另存为图片和加密功能,对于我的需求来说足够了,操作文档pdf操作内置对象文档,看不懂翻译即可
需求代码
我的需求是去掉PDF里每页的固定位置的文字(多余的培训机构的联系方式),以下称"多余部分",但我经过测试发下,哪些其实不是文字而是图片,整页是一张大图片,那更好操作了,首先maven引入dependency你懂得,计划为共分为三步.
1.先把pdf三四百页,以每页为一张图片导出来
/**
* pdf 转换为图片
* @param pdfPath pdf文件路径
* @param imgPath 图片导出目标路径
*/
public static void getImgInPDF(String pdfPath,String imgPath){
PDDocument document = null;
try {
File pdfFile = new File(pdfPath);
// 加载pdf文档,在pdmodel包
document = PDDocument.load(pdfFile);
// PDF文档总页数
System.out.println("共 "+num+" 页.");
// PDF文档渲染对象,在rendering包
PDFRenderer renderer = new PDFRenderer(document);
String startDate = DateTool.now();
int pageCount = document.getNumberOfPages();
System.out.println("共 "+pageCount+" 页.");
for (int i = 0; i < pageCount; i++) {
/**
* renderImage(i,1.9f)
*
* i: 指定页对象下标,从0开始,0即第一页
*
* 1.9f:DPI值(Dots Per Inch),官方描述比例因子,其中1=72 DPI
* DPI是指每英寸的像素,也就是扫描精度,DPI越低,扫描的清晰度越低
* 根据根据自己需求而定,我导出的图片是 927x1372
*/
BufferedImage image = renderer.renderImage(i,1.9f);
// 导出图片命名为:0-n.jpeg
ImageIO.write(image, "JPEG", new File(imgPath+i+".jpeg"));
System.out.println("导出 "+imgPath+i+".jpeg...");
}
System.out.println("开始时间:"+startDate);
System.out.println("结束时间:"+ DateTool.now());
}catch (Exception e){
e.printStackTrace();
}
}
2.java操作图片去掉固定位置的RGB(多余部分), 这部操作简单了
/**
* 设置图片的指定区域为指定颜色
* @param imgPath 图片路径
*/
public static void cleanImgRgb(String imgPath){
try{
String startDate = DateTool.now();
File dir = new File(imgPath);
File[] img = dir.listFiles();
// 处理imgPath中所有带jpeg后缀的图片
for (int i = 0; i < img.length; i++) {
String imgName = img[i].getName();
if(imgName.contains("jpeg")){
System.out.println("正在处理:"+imgName);
BufferedImage bufImage = ImageIO.read(new File(imgPath+imgName));
int rgb = 0xffffff; // 替换多余部分为白色rgb
int width = 470;// 替换区域宽
int height = 34;// 替换区域高
int startX = 230;// 替换区域x开始点
int startY = 16;// 替换区域y开始点
// rgb颜色数组,替换多余部分的width*height的总数
int[] rgbArray = new int[width*height];
for (int j = 0; j < width*height; j++) {
rgbArray[j] = rgb;
}
bufImage.setRGB(startX,startY,width,height,rgbArray,0,width);
FileOutputStream out = new FileOutputStream(imgPath+imgName);
ImageIO.write(bufImage, "JPEG",out);
}
}
System.out.println("开始时间:"+startDate);
System.out.println("结束时间:"+ DateTool.now());
}catch (Exception e){
e.printStackTrace();
}
}
3.再把处理过后的图片对应的插入到PDF每页里面,并覆盖以前,这步最重要!!!!
/**
* 插入图片到pdf,400+张依次插入到pdf的400+页中
* @param pdfPath pdf路径
* @param imgPath 要插入的图片路径(正是第一步的图片路径)
* @param start 插入pdf开始页
* @param end 插入pdf结束页
*/
private static void imgInsertToPdf(String pdfPath,String imgPath,int start,int end){
try {
System.out.println("图片路径:"+imgPath);
File file = new File(pdfPath);
PDDocument document = PDDocument.load(file);
int pageSie = document.getNumberOfPages();
System.out.println("pdf总页数:"+pageSie);
int insert = 0;
System.out.println("开始时间:"+ DateTool.now());
for (;start <=end; start++) {
insert++;
String img = imgPath+start+".jpeg";
System.out.println("第"+(start+1)+"个文件,图片"+img);
// 当前页
PDPage page = document.getPage(start);
File imgFile = new File(img);
if(imgFile.exists() && imgFile.getName().endsWith( ".jpeg" ) ){
//根据图片路径创建一张图片
PDImageXObject pdImage = PDImageXObject.createFromFile(img,document);
/**
* (document, page,false, true)
* document: pdf对象
* page : 当前页对象
* false : 是否是追加内容,false不追加,清空之前的内容
* true : 是否压缩
*/
PDPageContentStream contents = new PDPageContentStream(document, page,false, true);
/**
* 比例值
* 如果pdf页大,图片小,可调整此值放大图片沾满
* 建议值 0-1
*/
float scale = 0.527f;
// 绘制开始的xy点
contents.drawImage(pdImage, 0, 0, pdImage.getWidth() * scale, pdImage.getHeight() * scale);
contents.close();
//Saving the document 保存文档
document.save(pdfPath);
}else{
break;
}
}
System.out.println("插入次数:"+insert);
System.out.println("结束时间:"+ DateTool.now());
System.out.println("插入完毕.....");
//Closing the document
document.close();
}catch (Exception e){
e.printStackTrace();
}
}
PDFBox常用API,更多看官网
// pdf路径
String pdfPath = "/Users/Documents/pdf_file.pdf";
File file = new File(pdfPath);
// 加载pdf
PDDocument document = PDDocument.load(file);
/**
* 1.读取pdf文本
*/
// 文本分离器
PDFTextStripper textStripper = new PDFTextStripper();
// 输出pdf的文本内容
System.out.println(textStripper.getText(document));
/**
* 2.删除页面,存在的页,从0开始
*/
document.removePage(2);
// 获取总页数
document.getNumberOfPages();
/**
* 3.添加页面
*/
PDPage my_page = new PDPage();
document.addPage(my_page);
// 保存pdf
document.save("Path");
/**
* 4.插入图像
*/
// 获取pdf中的图片
PDFRenderer renderer = new PDFRenderer(document);
// 后去指定页的图像
BufferedImage image = renderer.renderImage(0);
// 另存到
ImageIO.write(image, "JPEG", new File("/Users/Documents/pdf_img.jpg"));
/**
* 5.合并pdf文档
*/
File pdf1 = new File("F:/worksp/pdfbox/pdf_1.pdf");
PDDocument doc1 = PDDocument.load(pdf1);
File pdf2 = new File("/Users/Documents/pdf_2.pdf");
PDDocument doc2 = PDDocument.load(pdf2);
// 合并后的文件
PDFMergerUtility merger = new PDFMergerUtility();
merger.setDestinationFileName("/Users/Documents/merger.pdf");
merger.addSource(file1);
merger.addSource(file2);
// 合并
merger.mergeDocuments();
doc2.close();
doc1.close();
// 关闭
document.close();