【记录】pdf添加水印(文字、图片水印)
先上效果图 由于透明度设置的比较低,可能看不太清右上角的是文字和图片的水印,图片打码了。
该实现中有word转pdf的方法,如有需要请移步另一个word转pdf的帖子,小白一个写的比较冗余哈。
pom
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
业务逻辑
@Override
public void loadPdf(HttpServletRequest request, HttpServletResponse response, PdfDTO pdfDTO) throws Exception {
String realPath = request.getSession().getServletContext().getRealPath(File.separator);
long docTime = System.currentTimeMillis();
//包含doc、docx下载到本地
if (pdfDTO.getStrUrl().contains(".doc") || pdfDTO.getStrUrl().contains(".docx")) {
logger.info("realPath路径为:" + realPath);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String fileAdd = sdf.format(new Date());
String inputPath = realPath + File.separator + fileAdd + File.separator;
logger.info("inputPath路径为:" + inputPath);
File file = new File(inputPath);
if (!file.exists() && !file.isDirectory()) {
file.mkdir();
}
long newPdfTime = System.currentTimeMillis();
String fileName = docTime + ".doc";
String newPdf = newPdfTime + ".pdf";
String rePath = inputPath + File.separator + File.separator + fileName;
String newPdfPath = inputPath + File.separator + File.separator + newPdf;
//将下载的doc、docx保存到本地
downloadFile(pdfDTO.getStrUrl(), rePath);
logger.info("保存的doc路径:" + realPath);
long l = System.currentTimeMillis();
//读取本地doc、docx 转换成pdf
PdfUtil.doc2pdf(rePath, newPdfPath);
logger.info("doc转pdf生成的新pdf路径:" + newPdfPath);
long l1 = System.currentTimeMillis();
logger.info("生成pdf用时为:" + (l1 - l));
//把转完的pdf打上水印
// 要输出的pdf文件
Date date = new Date();
SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1 = sdff.format(date);
String waterPdf = System.currentTimeMillis() + ".pdf";
String waterPdfPath = inputPath + File.separator + File.separator + waterPdf;
logger.info("打完水印的路径为:" + waterPdfPath);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(waterPdfPath)));
waterMark(bos, newPdfPath, pdfDTO.getType());
//将打完水印的pdf输出到前台
downPdf(request, response, waterPdfPath);
//删除文件夹下所有内容
deleteDir(inputPath);
return;
}
long l = System.currentTimeMillis();
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1 = simpleDateFormat.format(date);
/* String outputFilePath = "D:\\b.pdf"; String returnUrl = request.getScheme() + "://" + request.getServletPath() + ":" + request.getServerPort() + request.getContextPath() + "/unload/";*/
logger.info("realPath路径为:" + realPath);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String fileAdd = sdf.format(new Date());
String inputPath = realPath + File.separator + fileAdd + File.separator;
logger.info("inputPath路径为:" + inputPath);
File file = new File(inputPath);
if (!file.exists() && !file.isDirectory()) {
file.mkdir();
}
String fileName = l + ".pdf";
logger.info("fileName文件名:" + fileName);
String rePath = inputPath + File.separator + File.separator + fileName;
logger.info("rePath保存路径以及文件名:" + rePath);
// 给获取到的pdf添加水印
waterMark(new URL(pdfDTO.getStrUrl()), rePath, pdfDTO.getType());
// 下载pdf
downPdf(request, response, rePath);
// 删除之前生成的pdf
deletePdf(inputPath, fileName);
}
主要实现
//给PDF添加水印
//inputFile 文件路径+名称
//outputFile 添加水印后输出文件保存的路径+名称
//waterMarkName 添加水印的内容
public static void waterMark(BufferedOutputStream bos, String input, Integer type) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String format = sdf.format(date);
//String waterMarkName = type == 1 ? "用印" : "XX管理有限公司" + "\n" + AuthUtil.getUserAccount() + "\n" + format;
//切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, bos);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
//gs.setFillOpacity(0.5f);//改透明度
gs.setStrokeOpacity(0.3f);
int total = reader.getNumberOfPages() + 1;
String waterMarkName = "";
String waterMarkName2 = AuthUtil.getUserAccount();
if (type == 1) {
waterMarkName = "定稿";
}
if (type == 2) {
waterMarkName = "XX管理有限公司";
}
PdfContentByte under;
// 仅添加一个水印
if (type == 1) {
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.25f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 20);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 80), (height - 40), 0);
InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
byte[] bytes = inputStream2byte(path);
Image image = Image.getInstance(bytes);
image.setAbsolutePosition((width - 65),
(height - 52)); // set the first background image of the absolute
image.scaleToFit(40, 40);
under.addImage(image);
under.endText();
}
}
if (type == 2) {
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.4f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 30);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 300), (height - 300), 45);
//String path = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"water.png";
InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
byte[] bytes = inputStream2byte(path);
Image image = Image.getInstance(bytes);
image.setAbsolutePosition((width - 495),
(height - 475)); // set the first background image of the absolute
image.scaleToFit(50, 50);
image.setRotationDegrees(45);
under.addImage(image);
under.endText();
}
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.4f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 30);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName2, (width - 300), (height - 350), 45);
under.endText();
}
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.4f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 30);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, format, (width - 295), (height - 400), 45);
under.endText();
}
}
//下边这一段可添加多个水印
// Rectangle pageRect = null;
// FontMetrics metrics;
// int interval = -5;
// int textH = 0;
// int textW = 0;
// label.setText(waterMarkName);
// metrics = label.getFontMetrics(label.getFont());
// textH = metrics.getHeight();
// textW = metrics.stringWidth(label.getText());
// for (int i = 1; i < total; i++) {
// gs.setFillOpacity(0.4f); // 透明度
// pageRect = reader.getPageSizeWithRotation(i);
// under = stamper.getOverContent(i);//在内容上方加水印
// //under = stamper.getUnderContent(i);//在内容下方加水印
// under.saveState();
// under.setGState(gs);
// under.beginText();
// under.setFontAndSize(base, 25);
//
// // 水印文字成30度角倾斜
// for (int height = interval + textH; height < pageRect.getHeight();
// height = height + textH * 15) {
// for (int width = interval + textW; width < pageRect.getWidth() + textW;
// width = width + textW * 1) {
// under.showTextAligned(Element.ALIGN_LEFT
// , waterMarkName, width - textW,
// height - textH, 30);
// }
// }
// // 添加水印文字
// under.endText();
// }
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
该方法和上面实现基本一致,传参不同
//给PDF添加水印
//inputFile 文件路径+名称
//outputFile 添加水印后输出文件保存的路径+名称
//waterMarkName 添加水印的内容
public static void waterMark(URL inputFile, String outputFile, Integer type) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String format = sdf.format(date);
//切记这里的参数是文件的路径 ,路径必须是双斜杠的如F:\\test.pdf,不能是F:/test.pdf 或者F:\test.pdf
PdfReader reader = new PdfReader(inputFile);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
//gs.setFillOpacity(0.5f);//改透明度
gs.setStrokeOpacity(0.3f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
String waterMarkName = "";
String waterMarkName2 = AuthUtil.getUserAccount();
if (type == 1) {
waterMarkName = "定稿";
}
if (type == 2) {
waterMarkName = "XX管理有限公司";
}
/*label.setText(waterMarkName);*/
PdfContentByte under;
// 仅添加一个水印
if (type == 1) {
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.25f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 20);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 80), (height - 40), 0);
//String path = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"water.png";
InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
byte[] bytes = inputStream2byte(path);
Image image = Image.getInstance(bytes);
image.setAbsolutePosition((width - 65),
(height - 52)); // set the first background image of the absolute
image.scaleToFit(40, 40);
under.addImage(image);
under.endText();
}
}
if (type == 2) {
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.4f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 30);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, (width - 300), (height - 300), 45);
//String path = Thread.currentThread().getContextClassLoader().getResource("").getPath()+"water.png";
InputStream path = Thread.currentThread().getContextClassLoader().getResourceAsStream("water.png");
byte[] bytes = inputStream2byte(path);
Image image = Image.getInstance(bytes);
image.setAbsolutePosition((width - 495),
(height - 475)); // set the first background image of the absolute
image.scaleToFit(50, 50);
image.setRotationDegrees(45);
under.addImage(image);
under.endText();
}
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.4f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 30);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName2, (width - 300), (height - 350), 45);
under.endText();
}
for (int i = 1; i < total; i++) {
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
under = stamper.getOverContent(i);// 在内容上方加水印
//under = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.4f);//改透明度
under.setGState(gs);
under.beginText();
under.setColorFill(BaseColor.LIGHT_GRAY);//改变颜色
under.setFontAndSize(base, 30);//改水印文字大小
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, format, (width - 295), (height - 400), 45);
under.endText();
}
}
//下边这一段可添加多个水印
// Rectangle pageRect = null;
// FontMetrics metrics;
// int interval = -5;
// int textH = 0;
// int textW = 0;
// label.setText(waterMarkName);
// metrics = label.getFontMetrics(label.getFont());
// textH = metrics.getHeight();
// textW = metrics.stringWidth(label.getText());
// for (int i = 1; i < total; i++) {
// gs.setFillOpacity(0.4f); // 透明度
// pageRect = reader.getPageSizeWithRotation(i);
// under = stamper.getOverContent(i);//在内容上方加水印
// //under = stamper.getUnderContent(i);//在内容下方加水印
// under.saveState();
// under.setGState(gs);
// under.beginText();
// under.setFontAndSize(base, 25);
//
// // 水印文字成30度角倾斜
// for (int height = interval + textH; height < pageRect.getHeight();
// height = height + textH * 15) {
// for (int width = interval + textW; width < pageRect.getWidth() + textW;
// width = width + textW * 1) {
// under.showTextAligned(Element.ALIGN_LEFT
// , waterMarkName, width - textW,
// height - textH, 30);
// }
// }
// // 添加水印文字
// under.endText();
// }
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
帮助工具类
/** * 下载文件到本地 * * @param fileUrl 远程地址 * @param fileLocal 本地路径 * @throws Exception */
public void downloadFile(String fileUrl, String fileLocal) throws Exception {
URL url = new URL(fileUrl);
HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
urlCon.setConnectTimeout(6000);
urlCon.setReadTimeout(6000);
int code = urlCon.getResponseCode();
if (code != HttpURLConnection.HTTP_OK) {
throw new Exception("文件读取失败");
}
//读文件流
DataInputStream in = new DataInputStream(urlCon.getInputStream());
DataOutputStream out = new DataOutputStream(new FileOutputStream(fileLocal));
byte[] buffer = new byte[2048];
int count = 0;
while ((count = in.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
out.close();
in.close();
}
//input转byte[]
public static byte[] inputStream2byte(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = inputStream.read(buff, 0, 100)) > 0) {
byteArrayOutputStream.write(buff, 0, rc);
}
return byteArrayOutputStream.toByteArray();
}
// 下载加水印之后的文件
public void downPdf(HttpServletRequest httpRequest, HttpServletResponse response, String fileName)
throws IOException {
long l = System.currentTimeMillis();
String filename = AuthUtil.getUserId() + l + ".pdf";
File file = new File(fileName);
// 文件存在才下载
if (file.exists()) {
OutputStream out = null;
FileInputStream in = null;
try {
// 读取要下载的内容
in = new FileInputStream(file);
// 告诉浏览器下载的方式以及一些设置
// 解决文件名乱码问题,获取浏览器类型,转换对应文件名编码格式,IE要求文件名必须是utf-8, firefox要求是iso-8859-1编码
String agent = httpRequest.getHeader("user-agent");
if (agent.contains("FireFox")) {
filename = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
} else {
filename = URLEncoder.encode(filename, "UTF-8");
}
// 设置下载文件的mineType,告诉浏览器下载文件类型
String mineType = httpRequest.getServletContext().getMimeType(filename);
response.setContentType(mineType);
// 设置一个响应头,无论是否被浏览器解析,都下载
response.setHeader("Content-disposition", "attachment; filename=" + filename);
// 将要下载的文件内容通过输出流写到浏览器
out = response.getOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
}
}
}
//删除文件加下所有内容
public static void deleteDir(String path) {
File file = new File(path);
if (!file.exists()) { //判断是否待删除目录是否存在
System.err.println("The dir are not exists!");
return;
}
String[] content = file.list();//取得当前目录下所有文件和文件夹
for (String name : content) {
File temp = new File(path, name);
if (temp.isDirectory()) { //判断是否是目录
deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
temp.delete();//删除空目录
} else {
if (!temp.delete()) { //直接删除文件
System.err.println("Failed to delete " + name);
}
}
}
return;
}
//下载后删除该pdf,否则会造成文件越来越多
private void deletePdf(String inputPath, String fileName) {
File file = new File(inputPath);
if (file.isDirectory()) {
String[] dirPathList = file.list();
for (int i = 0; i < Objects.requireNonNull(dirPathList).length; i++) {
String filePath = inputPath + File.separator + dirPathList[i];
File fileDelete = new File(filePath);
if (Func.equals(fileDelete.getName(), fileName)) {
fileDelete.delete();
}
deletePdf(filePath, fileName);
}
}
}
原文作者:Dooooooooooong
原文地址: https://blog.csdn.net/weixin_46697618/article/details/121693704
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/weixin_46697618/article/details/121693704
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章