update 导出pdf时增加水印

This commit is contained in:
lijiarao
2024-09-10 16:11:43 +08:00
parent e8dc627d42
commit ab687e9012
7 changed files with 235 additions and 6 deletions
@@ -276,6 +276,10 @@
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,5 +1,6 @@
package com.jero.modules.system.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
@@ -9,6 +10,7 @@ import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.*;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import com.jero.modules.system.util.SysWaterMarkUtil;
import lombok.extern.slf4j.Slf4j;
import com.jero.common.api.vo.Result;
import com.jero.common.constant.CommonConstant;
@@ -74,6 +76,8 @@ public class CommonController {
*/
@Value(value="${jero.fileSuffixLimits}")
private String[] fileSuffixLimits;
@Resource
private SysWaterMarkUtil sysWaterMarkUtil;
/**
* @Author 政辉
@@ -227,6 +231,10 @@ public class CommonController {
fileName = ossFile.getFileName();
inputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url);
}
//pdf加水印
if ("pdf".equalsIgnoreCase(FileUtil.extName(fileName))) {
inputStream = sysWaterMarkUtil.addWatermarkToPdf(inputStream);
}
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("UTF-8"),"iso-8859-1"));
response.setContentType("application/force-download");// 设置强制下载不打开
if (type == null) {
@@ -264,9 +272,8 @@ public class CommonController {
ossFileService.updateAndPush(ossFile);
}
} catch (IOException e) {
log.error("预览文件失败" + e.getMessage());
log.error("预览文件失败" + e);
response.setStatus(404);
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
@@ -402,7 +409,10 @@ public class CommonController {
fileName = ossFile.getFileName();
inputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url);
}
//pdf加水印
if ("pdf".equalsIgnoreCase(FileUtil.extName(fileName))) {
inputStream = sysWaterMarkUtil.addWatermarkToPdf(inputStream);
}
ossFileService.updateById(ossFile);
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//if (loginUser.getIsCompanyUser()) {
@@ -449,9 +459,8 @@ public class CommonController {
ossFileService.updateAndPush(ossFile);
}
} catch (IOException e) {
log.error("预览文件失败" + e.getMessage());
log.error("预览文件失败" + e);
response.setStatus(404);
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
@@ -0,0 +1,153 @@
package com.jero.modules.system.util;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
import org.apache.pdfbox.util.Matrix;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 水印工具类
*
* @author CaiHaohan
*/
@Component
@Slf4j
public class SysWaterMarkUtil {
@Value("${watermark.font-size}")
private float fontSize;
@Value("${watermark.color.r}")
private int r;
@Value("${watermark.color.g}")
private int g;
@Value("${watermark.color.b}")
private int b;
@Value("${watermark.color.a}")
private int a;
@Value("${watermark.lineNumPerPage}")
private int lineNumPerPage;
@Value("${watermark.columnNumPerPage}")
private int columnNumPerPage;
@Value("${watermark.degree}")
private int degree;
@Value("${watermark.margin.left}")
private float marginLeft;
@Value("${watermark.margin.top}")
private float marginTop;
@Value("${watermark.dateFormat}")
private String dateFormat;
public List<String> getWaterMarkConfig() {
LoginUser loginUser = UserUtils.getLoginUser();
Date curDate = new Date();
String cudDateStr = DateUtils.date2Str(curDate, new SimpleDateFormat(dateFormat));
List<String> result = new ArrayList<>();
if (loginUser == null) {
result.add("汽车标准化工作平台 ");
}else {
result.add("汽车标准化工作平台 " + loginUser.getRealname());
}
result.add(cudDateStr);
return result;
}
public synchronized InputStream addWatermarkToPdf(InputStream inputStream) throws IOException {
List<String> watermarkText = getWaterMarkConfig();
PDDocument document = PDDocument.load(inputStream);
document.setAllSecurityToBeRemoved(true);
// 加载水印字体
ClassPathResource fontResource = new ClassPathResource("fonts/SourceHanSerif-VF.ttf");
PDType0Font font = PDType0Font.load(document, fontResource.getInputStream());
// 设置水印颜色和透明度
Color color = new Color(r, g, b, a);
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(0.4f);
graphicsState.setStrokingAlphaConstant(0.4f);
// 遍历每一页并添加水印
for (PDPage page : document.getPages()) {
// 获取页面尺寸以计算水印位置和大小
PDRectangle pageSize = page.getMediaBox();
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
// 根据页面宽度动态调整字体大小
float dynamicFontSize = pageWidth * (this.fontSize / 595); // 假设基准页面宽度为595单位
float xStep = pageWidth / columnNumPerPage;
float yStep = pageHeight / lineNumPerPage;
float rotationInRadians = (float) Math.toRadians(degree);
// 行间距,设为字体大小的一半
float lineSpacing = dynamicFontSize / 2;
// 计算两行文本的总高度
float totalTextHeight = (dynamicFontSize + lineSpacing) * (watermarkText.size() - 1);
for (float xPosition = pageSize.getLowerLeftX() + marginLeft; xPosition <= pageWidth - marginLeft; xPosition += xStep) {
for (float yPosition = pageSize.getLowerLeftY() + marginTop; yPosition <= pageHeight - marginTop; yPosition += yStep) {
try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
contentStream.setGraphicsStateParameters(graphicsState);
contentStream.setNonStrokingColor(color);
float textYPosition = yPosition + (totalTextHeight / 2);
for (String line : watermarkText) {
contentStream.beginText();
contentStream.setFont(font, dynamicFontSize);
contentStream.setRenderingMode(RenderingMode.FILL);
contentStream.setTextMatrix(Matrix.getRotateInstance(rotationInRadians, xPosition, textYPosition));
contentStream.showText(line);
contentStream.endText();
// 更新文本的Y坐标,为下一行准备
textYPosition -= (dynamicFontSize + lineSpacing);
}
}
}
}
}
// 创建一个临时的ByteArrayOutputStream保存修改过的PDF
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos);
document.close();
// 将ByteArrayOutputStream转换为ByteArrayInputStream以供返回
return new ByteArrayInputStream(baos.toByteArray());
}
}
@@ -0,0 +1,36 @@
package com.jero.modules.system.util;
import com.jero.common.system.vo.LoginUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
public class UserUtils {
/**
* 获取当前登录用户ID
*
*/
public static String getUserId() {
String userId = null;
try {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if(sysUser!=null){
userId = sysUser.getId();
}
} catch (UnavailableSecurityManagerException e) {
e.printStackTrace();
} catch (InvalidSessionException e) {
e.printStackTrace();
}
return userId;
}
/**
* 获取当前登录用户
*
*/
public static LoginUser getLoginUser() {
return (LoginUser) SecurityUtils.getSubject().getPrincipal();
}
}
@@ -363,4 +363,26 @@ template:
#入会申请表word
applicationWord: E:\\biao_zhun_suo\\template\\applicationWord.docx
#模版目录
templatePath: D:\\hzwl\\income_payments\\income_payments_managerment\\template\\
templatePath: D:\\hzwl\\income_payments\\income_payments_managerment\\template\\
# 水印配置项
watermark:
font-size: 13.0
# 每页几行
lineNumPerPage: 8
# 每页几列
columnNumPerPage: 3
# 倾斜角度
degree: 30
# 颜色
color:
r: 180
g: 180
b: 180
a: 1
# 页边距
margin:
top: 100
left: 60
# 日期格式
dateFormat: yyyy-MM-dd HH:mm:ss
+5
View File
@@ -278,6 +278,11 @@
<groupId>p6spy</groupId>
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
</dependencies>
</dependencyManagement>