记录一下springboot给Pdf文件加水印的解决方法
1、引入第三方包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2、水印帮助方法
package com.example.pdf.demo.util;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author tiankk
*/
public class PdfUtils {
/**
* pdf添加水印
* @param inputFile 需要添加水印的文件
* @param outputFile 添加完水印的文件存放路径
* @param waterMarkName 需要添加的水印文字
* @param opacity 水印字体透明度
* @param fontsize 水印字体大小
* @param angle 水印倾斜角度(0-360)
* @param heightdensity 数值越大每页竖向水印越少
* @param widthdensity 数值越大每页横向水印越少
* @param cover 是否覆盖
* @return
*/
public static boolean addwaterMark(String inputFile, String outputFile, String waterMarkName,
float opacity, int fontsize, int angle, int heightdensity, int widthdensity,boolean cover) {
if (!cover){
File file=new File(outputFile);
if (file.exists()){
return true;
}
}
File file=new File(inputFile);
if (!file.exists()){
return false;
}
PdfReader reader = null;
PdfStamper stamper = null;
try {
int interval = -5;
reader = new PdfReader(inputFile);
stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
//这里是透明度设置
gs.setFillOpacity(opacity);
//这里是条纹不透明度
gs.setStrokeOpacity(0.2f);
int total = reader.getNumberOfPages() + 1;
System.out.println("Pdf页数:" + reader.getNumberOfPages());
JLabel label = new JLabel();
FontMetrics metrics;
int textH = 0;
int textW = 0;
label.setText(waterMarkName);
metrics = label.getFontMetrics(label.getFont());
//字符串的高, 只和字体有关
textH = metrics.getHeight();
//字符串的宽
textW = metrics.stringWidth(label.getText());
PdfContentByte under;
//这个循环是确保每一张PDF都加上水印
for (int i = 1; i < total; i++) {
pageRect = reader.getPageSizeWithRotation(i);
under = stamper.getOverContent(i); //在内容上方添加水印
//under = stamper.getUnderContent(i); //在内容下方添加水印
under.saveState();
under.setGState(gs);
under.beginText();
//under.setColorFill(BaseColor.PINK); //添加文字颜色 不能动态改变 放弃使用
under.setFontAndSize(base, fontsize); //这里是水印字体大小
for (int height = textH; height < pageRect.getHeight() * 2; height = height + textH * heightdensity) {
for (int width = textW; width < pageRect.getWidth() * 1.5 + textW; width = width + textW * widthdensity) {
// rotation:倾斜角度
under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, angle);
}
}
//添加水印文字
under.endText();
}
System.out.println("添加水印成功!");
return true;
} catch (IOException e) {
System.out.println("添加水印失败!错误信息为: " + e);
e.printStackTrace();
return false;
} catch (DocumentException e) {
System.out.println("添加水印失败!错误信息为: " + e);
e.printStackTrace();
return false;
} finally {
//关闭流
if (stamper != null) {
try {
stamper.close();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
reader.close();
}
}
}
}
3、调用帮助方法并输出文件流
package com.example.pdf.demo.controller;
import com.example.pdf.demo.util.PdfUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.UUID;
/**
* @author tiankk
*/
@RestController
@RequestMapping("file")
public class FileController {
@GetMapping("downloadFile/{fileName}")
public void downloadFile(@PathVariable("fileName") String fileName, HttpServletResponse response) {
//需要添加水印的文件
String inputFile = "E:\\ChromeDownLoad\\test.pdf";
//添加完水印的文件存放路径
String outputFile = "E:\\ChromeDownLoad\\test(水印).pdf";
//需要添加的水印文字
String waterMarkName = "测试水印";
//水印字体透明度
float opacity = 0.3f;
//水印字体大小
int fontsize = 30;
//水印倾斜角度(0-360)
int angle = 30;
//数值越大每页竖向水印越少
int heightdensity = 20;
//数值越大每页横向水印越少
int widthdensity = 4;
PdfUtils.addwaterMark(inputFile, outputFile, waterMarkName, opacity, fontsize, angle, heightdensity, widthdensity,false);
fileName = UUID.randomUUID().toString() + "_" + fileName + ".pdf";
String path = null;
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
try {
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
}
byte[] buff = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
path = "E:\\ChromeDownLoad";
os = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(new File(path + "\\少有人走的路[派克](水印).pdf")));
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
} catch (FileNotFoundException e1) {
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
版权声明:本文为niuniu0108原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。