一、功能实现列表
本文实现给PDF文件添加水印有以下几种情况(水字数):
- 本地PDF文件添加网络图片、文字
- 本地PDF文件添加本地图片、文字
- 网络PDF文件添加网络图片、文字
- 网络PDF文件添加本地图片、文字
二、效果展示
实现思路
- 导入依赖
- 加载PDF文件
- 创建新PDF印章
- 将水印转换为可添加到PDF的
iText Image
对象 - 循环PDF文件页数,添加水印
- 关闭流
三、实现过程
- 引入依赖
<!--pdf处理-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
- 引用工具实现
@PostMapping
public void pdf() throws Exception {
String oldPdfPath="";
String newPdfPath="";
String imagePath="";
PdfUtil.addLocalImageToPdf("","","");
}
四、代码工具
package com.joolun.cloud.mall.common.util;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* pdf工具
* @author lenovo
*/
public class PdfUtil {
/**
* 将网络地址的pdf文件添加【网络图片水印】并保存本地
* @param oldPdfUrl 未添加水印
* @param newPdfPath 添加过水印的目录
* @param imageUrl 水印网络地址
* @throws Exception
*/
public static void addNetImageToPdf(String oldPdfUrl,String newPdfPath,String imageUrl) throws Exception {
// 1. 加载PDF文件
PdfReader reader = new PdfReader(new URL(oldPdfUrl));
// 2. 创建新的pdf文件签章
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(newPdfPath));
// 3. 下载网络图片并将其转换为可添加到PDF的iText Image对象
//定义一个URL对象,就是你想下载的图片的URL地址
URL url = new URL(imageUrl);
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为10秒
conn.setConnectTimeout(10 * 1000);
//通过输入流获取图片数据
InputStream is = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] bytes = readInputStream(is);
Image watermark = Image.getInstance(bytes);
//设置图片大小
watermark.scaleAbsolute(75, 40);
// 4. 循环处理PDF文件的每一页,为每一页添加水印
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfContentByte canvas = stamper.getUnderContent(i);
canvas.saveState();
float width = reader.getPageSize(i).getWidth();
float height = reader.getPageSize(i).getHeight();
watermark.setAbsolutePosition((width - watermark.getScaledWidth()) / 2, (height - watermark.getScaledHeight()) / 2);
canvas.addImage(watermark);
canvas.restoreState();
}
// 5. 关闭所有流
stamper.close();
reader.close();
}
/**
* 将本地地址的pdf文件添加【本地图片水印】并保存本地
* @param oldPdfPath 未添加水印的目录
* @param newPdfPath 添加过水印的目录
* @param imagePath 图片水印的目录
* @throws Exception
*/
public static void addLocalImageToPdf(String oldPdfPath,String newPdfPath,String imagePath) throws Exception {
// 1. 加载PDF文件
File pdfFile = new File(oldPdfPath);
PdfReader reader = new PdfReader(pdfFile.getAbsolutePath());
// 2. 创建新的pdf文件签章
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(newPdfPath));
// 3. 图片将其转换为可添加到PDF的iText Image对象
Image watermark = Image.getInstance(imagePath);
//设置图片大小
watermark.scaleAbsolute(75, 40);
// 4. 循环处理PDF文件的每一页,为每一页添加水印
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfContentByte canvas = stamper.getUnderContent(i);
canvas.saveState();
float width = reader.getPageSize(i).getWidth();
float height = reader.getPageSize(i).getHeight();
watermark.setAbsolutePosition((width - watermark.getScaledWidth()) / 2, (height - watermark.getScaledHeight()) / 2);
canvas.addImage(watermark);
canvas.restoreState();
}
// 5. 关闭所有流
stamper.close();
reader.close();
}
/**
* 将网络地址的pdf文件添加【文字水印】并保存
* @param oldPdfUrl 未添加水印
* @param newPdfPath 添加过水印的目录
* @param text 文字水印
* @throws Exception
*/
public static void addTextToNetPdfUtil(String oldPdfUrl,String newPdfPath,String text) throws Exception {
// 1. 加载PDF文件
PdfReader reader = new PdfReader(new URL(oldPdfUrl));
// 2. 创建新的pdf文件签章
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(newPdfPath));
// 4. 循环处理PDF文件的每一页,为每一页添加水印
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfContentByte canvas = stamper.getUnderContent(i);
canvas.beginText();
canvas.setFontAndSize(BaseFont.createFont(), 20);
canvas.setGrayFill(0.5f);
canvas.showTextAligned(Element.ALIGN_CENTER, text, reader.getPageSize(i).getWidth() / 2,
reader.getPageSize(i).getHeight() / 2, 45);
canvas.endText();
}
// 5. 关闭所有流
stamper.close();
reader.close();
}
/**
* 将本地地址的pdf文件添加【文字水印】并保存
* @param oldPdfUrl 未添加水印
* @param newPdfPath 添加过水印的目录
* @param text 文字水印
* @throws Exception
*/
public static void addTextToLocalPdfUtil(String oldPdfUrl,String newPdfPath,String text) throws Exception {
// 1. 加载PDF文件
File pdfFile = new File(oldPdfUrl);
PdfReader reader = new PdfReader(pdfFile.getAbsolutePath());
// 2. 创建新的pdf文件签章
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(newPdfPath));
// 4. 循环处理PDF文件的每一页,为每一页添加水印
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfContentByte canvas = stamper.getUnderContent(i);
canvas.beginText();
canvas.setFontAndSize(BaseFont.createFont(), 20);
canvas.setGrayFill(0.5f);
canvas.showTextAligned(Element.ALIGN_CENTER, text, reader.getPageSize(i).getWidth() / 2,
reader.getPageSize(i).getHeight() / 2, 45);
canvas.endText();
}
// 5. 关闭所有流
stamper.close();
reader.close();
}
/**
* 获取流的二进制
* @param inStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[6024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len;
//使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
}
五、总结
实现方法都是一样的,里面参数可以自己摸索。