From 5c46f4a347749bc0a7b0abb50842e42fdff7e273 Mon Sep 17 00:00:00 2001 From: caihaohan Date: Fri, 22 Sep 2023 18:00:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B8=A6=E6=B0=B4=E5=8D=B0=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LawsCommonController.java | 97 ++++++++++++++++++- .../laws/enterprise/util/WaterMarkUtil.java | 92 ++++++++++++++++++ .../com/jero/modules/sys/utils/UserUtils.java | 20 ++++ 3 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/WaterMarkUtil.java create mode 100644 laws-modules/src/main/java/com/jero/modules/sys/utils/UserUtils.java diff --git a/laws-modules/src/main/java/com/jero/modules/laws/common/controller/LawsCommonController.java b/laws-modules/src/main/java/com/jero/modules/laws/common/controller/LawsCommonController.java index 40bf858b..5c2a9805 100644 --- a/laws-modules/src/main/java/com/jero/modules/laws/common/controller/LawsCommonController.java +++ b/laws-modules/src/main/java/com/jero/modules/laws/common/controller/LawsCommonController.java @@ -1,27 +1,39 @@ package com.jero.modules.laws.common.controller; +import cn.hutool.core.io.FileUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.jero.common.api.vo.Result; import com.jero.common.exception.JeroBootException; import com.jero.common.util.MessageUtils; +import com.jero.common.util.MinioUtil; import com.jero.modules.laws.common.constant.ResultCommon; import com.jero.modules.laws.common.service.ILawsCommonService; import com.jero.modules.laws.common.vo.ManyStandardSelectionBox; import com.jero.modules.laws.common.vo.ManyStandardSelectionBoxVO; +import com.jero.modules.laws.enterprise.util.WaterMarkUtil; +import com.jero.modules.oss.entity.OSSFile; +import com.jero.modules.oss.service.IOSSFileService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; /** * @Author: liao * @Date: 2023/9/11 15:40 * @Description: 法规通用操作 */ +@Slf4j @Api(tags="法规通用操作") @RestController @RequestMapping("/laws/standard/common") @@ -30,6 +42,12 @@ public class LawsCommonController { @Autowired private ILawsCommonService lawsCommonService; + @Resource + private WaterMarkUtil waterMarkUtil; + + @Resource + private IOSSFileService ossFileService; + @ApiOperation(value="多选标准弹框", notes="多选标准弹框") @GetMapping(value = "/getManyStandardSelectionBox") public Result> getManyStandardSelectionBox(ManyStandardSelectionBoxVO selectionBoxVO, @@ -52,4 +70,75 @@ public class LawsCommonController { return Result.OK(lawsCommonService.getManyStandardSelectionBox(selectionBoxVO, pageNo, pageSize)); } + + /** + * 下载带水印的PDF文件 + * + * @param id 传入文件id + * @param response + */ + @ApiOperation(value="PDF带水印下载", notes="PDF带水印下载") + @GetMapping(value = "/downloadWithWaterMark/{id}") + public void downloadWithWaterMark(@PathVariable String id, HttpServletResponse response) { + // 查询数据表数据是否存在 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(OSSFile::getId, id); + OSSFile ossFile = ossFileService.getOne(queryWrapper); + if (null == ossFile) { + throw new JeroBootException("文件不存在.."); + } + String fileUrl = ossFile.getUrl(); + // minio 下载 + // 通过MinioUtil查询时 只需要桶后面的路径 + String minioUrl = MinioUtil.getMinioUrl(); + // Linux/unix 系统下文件路径分隔符为"/" 获取minio与存储桶的路径 + minioUrl = minioUrl + MinioUtil.getBucketName() + "/"; + String url = fileUrl.replace(minioUrl, ""); + // 文件名称 + String fileName = ossFile.getFileName(); + response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); + // 设置强制下载不打开 + response.setContentType("application/force-download"); + // 然后在您的controller方法中: + if ("pdf".equals(FileUtil.extName(fileName))) { + try (InputStream originalInputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url); + InputStream watermarkedInputStream = waterMarkUtil.addWatermarkToPdf(originalInputStream); + OutputStream outputStream = response.getOutputStream()) { + + if (originalInputStream == null) { + return; + } + + byte[] buf = new byte[1024]; + int len; + while ((len = watermarkedInputStream.read(buf)) > 0) { + outputStream.write(buf, 0, len); + } + response.flushBuffer(); + + } catch (Exception e) { + log.error(e.getMessage()); + response.setStatus(404); + e.printStackTrace(); + } + } else { + try (InputStream inputStream = MinioUtil.getMinioFile(MinioUtil.getBucketName(), url); + OutputStream outputStream = response.getOutputStream() + ) { + byte[] buf = new byte[1024]; + int len; + if(inputStream==null) { + return; + } + while ((len = inputStream.read(buf)) > 0) { + outputStream.write(buf, 0, len); + } + response.flushBuffer(); + } catch (Exception e){ + log.error(e.getMessage()); + response.setStatus(404); + e.printStackTrace(); + } + } + } } diff --git a/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/WaterMarkUtil.java b/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/WaterMarkUtil.java new file mode 100644 index 00000000..34accdf4 --- /dev/null +++ b/laws-modules/src/main/java/com/jero/modules/laws/enterprise/util/WaterMarkUtil.java @@ -0,0 +1,92 @@ +package com.jero.modules.laws.enterprise.util; + +import com.jero.modules.system.entity.SysUser; +import com.jero.modules.system.service.ISysUserService; +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.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Component; +import com.jero.modules.sys.utils.UserUtils; + +import javax.annotation.Resource; +import java.awt.*; +import java.io.*; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +/** + * 水印工具类 + * @author CaiHaohan + */ +@Component +public class WaterMarkUtil { + + @Resource + private ISysUserService userEoService; + + public String getWaterMarkConfig() { + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); + String formattedDate = currentDate.format(formatter); + + SysUser user = userEoService.getById(UserUtils.getUserId()); + String userName = user.getNameWorkNo(); + + return userName + " " + formattedDate; + } + + public InputStream addWatermarkToPdf(InputStream inputStream) throws IOException { + String watermarkText = getWaterMarkConfig(); + PDDocument document = PDDocument.load(inputStream); + + // 设置水印字体、字体大小、颜色和透明度 + ClassPathResource fontResource = new ClassPathResource("fonts/SourceHanSerif-VF.ttf"); + PDType0Font font = PDType0Font.load(document, fontResource.getInputStream()); + float fontSize = 13.0f; + Color color = new Color(100, 100, 100, 0); + PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState(); + graphicsState.setNonStrokingAlphaConstant(0.4f); + graphicsState.setStrokingAlphaConstant(0.4f); + + // 遍历每一页并添加水印 + for (PDPage page : document.getPages()) { + // 获取页面尺寸以计算水印位置 + PDRectangle pageSize = page.getMediaBox(); + float xStep = pageSize.getWidth() / 4; + float yStep = pageSize.getHeight() / 4; + float rotationInRadians = (float) Math.toRadians(20); + + for (float xPosition = pageSize.getLowerLeftX(); xPosition <= pageSize.getWidth(); xPosition += xStep) { + for (float yPosition = pageSize.getLowerLeftY(); yPosition <= pageSize.getHeight(); yPosition += yStep) { + // 创建内容流并设置图形状态参数 + try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) { + contentStream.setGraphicsStateParameters(graphicsState); + contentStream.setFont(font, fontSize); + contentStream.setNonStrokingColor(color); + contentStream.beginText(); + contentStream.setRenderingMode(RenderingMode.FILL); + // 设置水印文本的旋转和位置 + contentStream.setTextMatrix(Matrix.getRotateInstance(rotationInRadians, xPosition, yPosition)); + contentStream.showText(watermarkText); + contentStream.endText(); + } + } + } + } + + // 创建一个临时的ByteArrayOutputStream保存修改过的PDF + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + document.save(baos); + document.close(); + + // 将ByteArrayOutputStream转换为ByteArrayInputStream以供返回 + return new ByteArrayInputStream(baos.toByteArray()); + } + +} diff --git a/laws-modules/src/main/java/com/jero/modules/sys/utils/UserUtils.java b/laws-modules/src/main/java/com/jero/modules/sys/utils/UserUtils.java new file mode 100644 index 00000000..dd48a0c2 --- /dev/null +++ b/laws-modules/src/main/java/com/jero/modules/sys/utils/UserUtils.java @@ -0,0 +1,20 @@ +package com.jero.modules.sys.utils; + +import com.jero.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; + +/** + * @author: Mzaxd + * @Date: 2023/7/7 14:54 + */ +public class UserUtils { + + public static String getUserId() { + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + return sysUser.getId(); + } + + public static LoginUser getCurrentUser() { + return (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } +}