xiaofei vor 7 Monaten
Ursprung
Commit
7db726c93d

+ 13 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java

@@ -636,6 +636,19 @@ public class SysController {
         }
     }
 
+    @ApiOperation(value = "PDF加水印")
+    @RequestMapping(value = "/pdf/watermark/preview", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
+    @Aac(auth = false)
+    public void filePreview(@ApiParam(value = "附件id", defaultValue = "") @RequestParam(value = "id", required = false) Long id,
+                              HttpServletResponse response) {
+        if(id == null){
+            throw ExceptionResultEnum.ERROR.exception("请求参数有误");
+        }
+
+        basicAttachmentService.addMaterMark(id, response);
+    }
+
     @ApiOperation(value = "查询用户权限")
     @RequestMapping(value = "/get_menu", method = RequestMethod.POST)
     public Result getMenu() {

+ 8 - 0
teachcloud-common/pom.xml

@@ -193,5 +193,13 @@
             <groupId>com.qmth.boot</groupId>
             <artifactId>tools-common</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itext-asian</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 3 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/BasicAttachmentService.java

@@ -5,6 +5,7 @@ import com.qmth.teachcloud.common.entity.BasicAttachment;
 import com.qmth.teachcloud.common.enums.UploadFileEnum;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
@@ -44,4 +45,6 @@ public interface BasicAttachmentService extends IService<BasicAttachment> {
     public void batchDeleteAttachment(List<BasicAttachment> basicAttachmentList);
 
     BasicAttachment saveAttachment(MultipartFile file, String requestMd5, UploadFileEnum file1);
+
+    void addMaterMark(Long id, HttpServletResponse response);
 }

+ 28 - 4
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/BasicAttachmentServiceImpl.java

@@ -1,8 +1,10 @@
 package com.qmth.teachcloud.common.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.boot.api.exception.ApiException;
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicAttachment;
@@ -14,10 +16,9 @@ import com.qmth.teachcloud.common.enums.UploadFileEnum;
 import com.qmth.teachcloud.common.mapper.BasicAttachmentMapper;
 import com.qmth.teachcloud.common.service.BasicAttachmentService;
 import com.qmth.teachcloud.common.service.CommonCacheService;
-import com.qmth.teachcloud.common.util.FileStoreUtil;
-import com.qmth.teachcloud.common.util.FileUtil;
-import com.qmth.teachcloud.common.util.ResultUtil;
-import com.qmth.teachcloud.common.util.ServletUtil;
+import com.qmth.teachcloud.common.service.FileUploadService;
+import com.qmth.teachcloud.common.service.SysUserService;
+import com.qmth.teachcloud.common.util.*;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -29,9 +30,11 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.*;
 
@@ -49,9 +52,13 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
 
     @Resource
     private FileStoreUtil fileStoreUtil;
+    @Resource
+    private FileUploadService fileUploadService;
 
     @Autowired
     private DictionaryConfig dictionaryConfig;
+    @Resource
+    private SysUserService sysUserService;
 
     @Resource
     CommonCacheService commonCacheService;
@@ -214,6 +221,23 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
         return basicAttachment;
     }
 
+    @Override
+    public void addMaterMark(Long id, HttpServletResponse response) {
+        SysUser sysUser = sysUserService.getById(ServletUtil.getRequestUserId());
+        BasicAttachment basicAttachment = this.getById(id);
+        if(basicAttachment == null){
+            throw ExceptionResultEnum.ERROR.exception("未找到附件");
+        }
+        FilePathVo filePathVo = JSON.parseObject(basicAttachment.getPath(), FilePathVo.class);
+        InputStream inputStream = fileUploadService.downloadFile(filePathVo.getPath(), filePathVo.getUploadType(), filePathVo.getType());
+        String waterMark = sysUser.getLoginName()+"("+sysUser.getRealName()+")";
+        try {
+            PDFAddWatermarkUtil.pdfAddWaterMark(inputStream, response.getOutputStream(), waterMark);
+        } catch (IOException e) {
+            throw ExceptionResultEnum.ERROR.exception("预览失败");
+        }
+    }
+
     /**
      * 删除附件公用
      *

+ 179 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/PDFAddWatermarkUtil.java

@@ -0,0 +1,179 @@
+package com.qmth.teachcloud.common.util;
+
+import com.itextpdf.text.Element;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.*;
+
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @Description: PDF增加水印工具类
+ */
+public class PDFAddWatermarkUtil {
+
+    /**
+     * 给PDF添加水印
+     *
+     * @param inputFilePath    原文件路径+名称,例如D:\\pdf\\test.pdf
+     * @param outputFilePath   添加水印后输出文件保存的路径+名称
+     * @param waterMarkContent 添加水印的内容
+     */
+    public static void pdfAddWaterMark(String inputFilePath, String outputFilePath, String waterMarkContent) {
+        try {
+            // 水印的高和宽
+            int waterMarkHeight = 30;
+            int watermarkWeight = 60;
+
+            // 水印间隔距离
+            int waterMarkInterval = 200;
+
+            // 读取PDF文件流
+            PdfReader pdfReader = new PdfReader(inputFilePath);
+
+            // 创建PDF文件的模板,可以对模板的内容修改,重新生成新PDF文件
+            PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(outputFilePath));
+
+            // 设置水印字体
+            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
+
+            // 设置PDF内容的Graphic State 图形状态
+            PdfGState pdfGraPhicState = new PdfGState();
+            // 填充透明度
+            pdfGraPhicState.setFillOpacity(0.2f);
+            // 轮廓不透明度
+            pdfGraPhicState.setStrokeOpacity(0.4f);
+
+            // PDF页数
+            int pdfPageNum = pdfReader.getNumberOfPages() + 1;
+
+            // PDF文件内容字节
+            PdfContentByte pdfContent;
+
+            // PDF页面矩形区域
+            Rectangle pageRectangle;
+
+            for (int i = 1; i < pdfPageNum; i++) {
+                // 获取当前页面矩形区域
+                pageRectangle = pdfReader.getPageSizeWithRotation(i);
+                // 获取当前页内容,getOverContent表示之后会在页面内容的上方加水印
+                pdfContent = pdfStamper.getOverContent(i);
+
+                // 获取当前页内容,getOverContent表示之后会在页面内容的下方加水印
+                // pdfContent = pdfStamper.getUnderContent(i);
+
+                pdfContent.saveState();
+                // 设置水印透明度
+                pdfContent.setGState(pdfGraPhicState);
+
+                // 开启写入文本
+                pdfContent.beginText();
+                // 设置字体
+                pdfContent.setFontAndSize(baseFont, 20);
+
+                // 在高度和宽度维度每隔waterMarkInterval距离添加一个水印
+                for (int height = waterMarkHeight; height < pageRectangle.getHeight(); height = height + waterMarkInterval) {
+                    for (int width = watermarkWeight; width < pageRectangle.getWidth() + watermarkWeight;
+                         width = width + waterMarkInterval) {
+                        // 添加水印文字并旋转35度角
+                        pdfContent.showTextAligned(Element.ALIGN_LEFT, waterMarkContent, (width - watermarkWeight) * 1.1f,
+                                height - waterMarkHeight, 35);
+                    }
+                }
+                // 停止写入文本
+                pdfContent.endText();
+            }
+            pdfStamper.close();
+            pdfReader.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 给PDF添加水印
+     *
+     * @param inputStream    原文件路径+名称,例如D:\\pdf\\test.pdf
+     * @param outputStream   添加水印后输出文件保存的路径+名称
+     * @param waterMarkContent 添加水印的内容
+     */
+    public static void pdfAddWaterMark(InputStream inputStream, OutputStream outputStream, String waterMarkContent) {
+        try {
+            // 水印的高和宽
+            int waterMarkHeight = 30;
+            int watermarkWeight = 60;
+
+            // 水印间隔距离
+            int waterMarkInterval = 200;
+
+            // 读取PDF文件流
+            PdfReader pdfReader = new PdfReader(inputStream);
+
+            // 创建PDF文件的模板,可以对模板的内容修改,重新生成新PDF文件
+            PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream);
+
+            // 设置水印字体
+            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
+
+            // 设置PDF内容的Graphic State 图形状态
+            PdfGState pdfGraPhicState = new PdfGState();
+            // 填充透明度
+            pdfGraPhicState.setFillOpacity(0.1f);
+            // 轮廓不透明度
+            pdfGraPhicState.setStrokeOpacity(0.4f);
+
+            // PDF页数
+            int pdfPageNum = pdfReader.getNumberOfPages() + 1;
+
+            // PDF文件内容字节
+            PdfContentByte pdfContent;
+
+            // PDF页面矩形区域
+            Rectangle pageRectangle;
+
+            for (int i = 1; i < pdfPageNum; i++) {
+                // 获取当前页面矩形区域
+                pageRectangle = pdfReader.getPageSizeWithRotation(i);
+                // 获取当前页内容,getOverContent表示之后会在页面内容的上方加水印
+                pdfContent = pdfStamper.getOverContent(i);
+
+                // 获取当前页内容,getOverContent表示之后会在页面内容的下方加水印
+                // pdfContent = pdfStamper.getUnderContent(i);
+
+                pdfContent.saveState();
+                // 设置水印透明度
+                pdfContent.setGState(pdfGraPhicState);
+
+                // 开启写入文本
+                pdfContent.beginText();
+                // 设置字体
+                pdfContent.setFontAndSize(baseFont, 20);
+
+                // 在高度和宽度维度每隔waterMarkInterval距离添加一个水印
+                for (int height = waterMarkHeight; height < pageRectangle.getHeight(); height = height + waterMarkInterval) {
+                    for (int width = watermarkWeight; width < pageRectangle.getWidth() + watermarkWeight;
+                         width = width + waterMarkInterval) {
+                        // 添加水印文字并旋转35度角
+                        pdfContent.showTextAligned(Element.ALIGN_LEFT, waterMarkContent, (width - watermarkWeight) * 1.1f,
+                                height - waterMarkHeight, 35);
+                    }
+                }
+                // 停止写入文本
+                pdfContent.endText();
+            }
+            pdfStamper.close();
+            pdfReader.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            pdfAddWaterMark("/Users/xiaofei/qmth/test/pdf/测试.pdf", "/Users/xiaofei/qmth/test/pdf/测试-watermark.pdf", "zhangsan(张三)");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}