更新优化版转: JAVA 实现给PDF的图像批量添加超链接-优快云博客
我的PDF长这样:
因为需要给每个图片增加对应的超链接,工作比较繁琐,所以做了如下尝试。
步骤一:获取PDF上的图片信息(因为图片布局不规范,无法按照固定的坐标去添加链接,所以先获取各个图片的布局坐标):
package pdf.pdf;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.exporting.PdfImageInfo;
import java.awt.geom.Rectangle2D;
import java.util.*;
public class GetCoordinateOfImage {
public List<Point> getCoordinateOfImage(PdfDocument doc,Integer num) throws Exception {
if(doc.getPages().getCount()==0){
System.out.println("第"+num+"页getCoordinateOfImage IS NULL!!!");
return null;};
PdfPageBase page = doc.getPages().get(num);
//获取第一页上的图片信息
PdfImageInfo[] imageInfo = page.getImagesInfo();
Map<String,List<Integer>> map=new HashMap<>();
List<Integer> listX=new ArrayList<>();
List<Integer> listY=new ArrayList<>();
for (int i = 0; i < imageInfo.length; i++) {
//获取指定图片的边界属性
Rectangle2D rect = imageInfo[i].getBounds();
listX.add((int) rect.getMinX());
listY.add((int) rect.getMinY());
//File outputfile = new File("第 " + (i) + "张" + i + ".jpg");
//ImageIO.write(imageInfo[i].getImage(), "jpg", outputfile);
}
Integer pageNum=num+1;
List<Integer> listXFinal=new ArrayList<>();
List<Integer> listYFinal=new ArrayList<>();
listXFinal=ListUtils.duplicateListBySet(listX);
listYFinal=ListUtils.reverse(ListUtils.duplicateListBySet(listY));
System.out.println( "第"+pageNum+"页的X数据为:"+listXFinal);
System.out.println( "第"+pageNum+"页的Y数据为:"+listYFinal);
System.out.println( "第"+pageNum+"页的数据为:"+ ListUtils.listPoint(ListUtils.deviation(listXFinal),ListUtils.deviation(listYFinal)));
System.out.println( "第"+pageNum+"页的数据量为:"+ListUtils.listPoint(ListUtils.deviation(listXFinal),ListUtils.deviation(listYFinal)).size());
return ListUtils.listPoint(ListUtils.deviation(listXFinal),
ListUtils.deviation(listYFinal));
}
}
步骤2:根据图片坐标,用org.apache.pdfbox添加区域超链接:
package pdf.pdf;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary;
import java.io.IOException;
import java.util.List;
public class AddLinks {
public static void main(String[] args) throws Exception {
}
public String addLink(PDDocument document, int pageNumber,
String url, List<Point> lists) throws IOException {
Integer pagenum=pageNumber+1;
System.out.println("页码"+pagenum+"开始添加link任务!");
String tips="";
List<String> picUrls=ReadExcelData.getFinalList("/Users/gwx/Desktop/java/pdf/表格.xlsx",pageNumber);
if(pageNumber>9) {return "PDF任务全部完成!!!!";}
else{
for(int i = 0; i <= lists.size(); i++){
if(i>51){return "页码"+pagenum+"完成添加link任务!";}
try {
System.out.println(String.format("页码%d添加link第%d张图片的对角坐标为:((%f, %f,%f, %f)),", pagenum, i+1,lists.get(i).getStartX(),lists.get(i).getStartY(),
lists.get(i).getStartX() + lists.get(i).getWidth(),
lists.get(i).getStartY() + lists.get(i).getHight()));
PDAnnotationLink txtLink = new PDAnnotationLink();
//设置每个图片的坐标 16和46是我试出来的,没啥科学规律
PDRectangle position = new PDRectangle();
position.setLowerLeftX(lists.get(i).getStartX());
position.setLowerLeftY(lists.get(i).getStartY()+16);
position.setUpperRightX(lists.get(i).getStartX() + lists.get(i).getWidth());
position.setUpperRightY(lists.get(i).getStartY() + 46);
txtLink.setRectangle(position);
// 去除边框
PDBorderStyleDictionary borderStyle = new PDBorderStyleDictionary();
borderStyle.setWidth(0);
txtLink.setBorderStyle(borderStyle);
PDActionURI action = new PDActionURI();
action.setURI(picUrls.get(i));
txtLink.setAction(action);
page.getAnnotations().add(txtLink);
tips= "Finished!";
} catch (IOException e) {
tips="页码"+pagenum+"添加失败==》"+e.getMessage();
}
System.out.println(String.format("页码%d添加link第%d张图添加成功",pagenum,i+1));
}}
tips="页码"+pagenum+"完成添加link任务!";
return tips;
}
}
步骤3:main函数调用方法,执行:
package pdf.pdf;
import com.spire.pdf.PdfDocument;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import java.io.File;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
//创建PdfDocument对象
PdfDocument doc = new PdfDocument();
//加载一个PDF文档
doc.loadFromFile("/Users/gwx/Desktop/java/pdf/416--添加链接.pdf");
File file = new File("/Users/gwx/Desktop/java/pdf/416--添加链接.pdf");
PDDocument doc1 = PDDocument.load(file);
GetCoordinateOfImage test=new GetCoordinateOfImage();
for (int i = 2; i <doc1.getNumberOfPages(); i++) {
Integer pageNum=i+1;
System.out.println("页码任务"+pageNum+"开始喽~");
PDPage page=doc1.getPage(i);
List<Point> list=test.getCoordinateOfImage(doc,i);
PDFReader.readImage(page,i,doc1,list);
}
doc1.save("ceshi.pdf");
doc1.close();
doc.close();
}
}
程序运行结果如下:
maven配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pdf.pdf</groupId>
<artifactId>pdf</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>20</maven.compiler.source>
<maven.compiler.target>20</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<!--xlsx(07)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf</artifactId>
<version>9.6.2</version>
<scope>system</scope>
<systemPath>${pom.basedir}/src/main/resources/lib/spire.pdf-9.6.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.27</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>jempbox</artifactId>
<version>1.8.17</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>xmpbox</artifactId>
<version>2.0.27</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId>
<version>2.0.27</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.27</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-reflect</artifactId>
<version>3.7</version>
</dependency>
</dependencies>
</project>