您的位置:首页 > 财经 > 产业 > 黄山旅游攻略景点必去_台州品牌网站设计_专业seo网络营销公司_引流平台有哪些

黄山旅游攻略景点必去_台州品牌网站设计_专业seo网络营销公司_引流平台有哪些

2025/6/7 1:51:59 来源:https://blog.csdn.net/weixin_45280713/article/details/146584021  浏览:    关键词:黄山旅游攻略景点必去_台州品牌网站设计_专业seo网络营销公司_引流平台有哪些
黄山旅游攻略景点必去_台州品牌网站设计_专业seo网络营销公司_引流平台有哪些

需求:点击下载---》弹窗加入水印(可加可不加,加上就有水印,没有不加水印),点击之后下载文件

处理思路及流程

前端:

用户点击下载 → 收集水印参数 → 调用后端API → 处理响应为Blob → 触发文件下载

后端:

接收请求 → 验证权限 → 从Minio获取文件 → 判断文件类型 → 添加水印 → 返回处理后的文件流

前端

<template><button @click="downloadFileWithWatermark">下载文件并添加水印</button>
</template><script setup>
import axios from 'axios';const downloadFileWithWatermark = async () => {const watermarkText = '飞天小女警'; // 自定义水印内容const fileUrl = 'your_minio_file_url'; // MinIO 上文件的 URLtry {const response = await axios.get('/api/download', {params: {fileUrl,watermarkText},responseType: 'blob'});const url = window.URL.createObjectURL(new Blob([response]));const link = document.createElement('a');link.href = url;link.setAttribute('download', 'file_with_watermark.pdf'); // 根据文件类型修改文件名document.body.appendChild(link);link.click();document.body.removeChild(link);} catch (error) {console.error('下载失败:', error);}
};
</script>

Java

加jar包

<!-- Apache PDFBox 用于处理 PDF --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version></dependency>
import io.minio.MinioClient;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;@RestController
public class FileDownloadController {@Autowiredprivate MinioClient minioClient;@GetMapping("/api/download")public byte[] downloadFileWithWatermark(@RequestParam String fileUrl, @RequestParam String watermarkText) throws Exception {// 解析 MinIO 存储桶和对象名称String[] parts = fileUrl.split("/");String bucketName = parts[parts.length - 2];String objectName = parts[parts.length - 1];// 获取字节InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());byte[] content = inputStreamToByteArray(inputStream);inputStream.close();byte[] fileBytes;if (objectName.toLowerCase().endsWith(".pdf")) {fileBytes = addWatermarkToPdf(content, watermarkText);} else if (objectName.toLowerCase().endsWith(".jpg") || objectName.toLowerCase().endsWith(".png")) {fileBytes = addWatermarkToImage(content, watermarkText);} else {throw new IllegalArgumentException("不支持的文件类型");}// 设置响应头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);headers.setContentDispositionFormData("attachment", URLEncoder.encode(objectName, StandardCharsets.UTF_8));return fileBytes}private byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {ByteArrayOutputStream buffer = new ByteArrayOutputStream();int nRead;byte[] data = new byte[16384];while ((nRead = inputStream.read(data, 0, data.length)) != -1) {buffer.write(data, 0, nRead);}buffer.flush();return buffer.toByteArray();}private byte[] addWatermarkToPdf(byte[] content, String watermarkText) throws IOException {try (PDDocument document = PDDocument.load(content)) {for (PDPage page : document.getPages()) {try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {contentStream.setFont(PDType1Font.HELVETICA_BOLD, 20);contentStream.setNonStrokingColor(Color.LIGHT_GRAY);contentStream.beginText();contentStream.newLineAtOffset(100, 100);contentStream.showText(watermarkText);contentStream.endText();}}ByteArrayOutputStream outputStream = new ByteArrayOutputStream();document.save(outputStream);return outputStream.toByteArray();}}private byte[] addWatermarkToImage(byte[] content, String watermarkText) throws IOException {java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(content);BufferedImage image = ImageIO.read(bis);Graphics2D g2d = image.createGraphics();g2d.setColor(Color.LIGHT_GRAY);g2d.setFont(new Font("Arial", Font.BOLD, 20));g2d.drawString(watermarkText, 100, 100);g2d.dispose();ByteArrayOutputStream bos = new ByteArrayOutputStream();ImageIO.write(image, "png", bos);return bos.toByteArray();}
}

修改pdf加水印,因为没有对应的字体没输入文字水印之后pdf文件会打不开

所以现在改进方法:

从网站下载对应字体的ttf,我是从c:/windows/fonts/ 下找到对应的 “simhei.ttf”文件复制在“ssrc/main/resources/fonts”文件夹下;

修改对应加水印的代码,如下:

private byte[] addWatermarkToPdf(byte[] content, String watermarkText) throws IOException {try (PDDocument document = PDDocument.load(content)) {// 使用try-with-resources确保字体流关闭try (InputStream fontStream = getClass().getResourceAsStream("/fonts/simhei.ttf")) {//PDTrueTypeFont font = PDTrueTypeFont.loadTTF(document, fontStream);注意这是个大坑!PDTType0Font font = PDTType0Font.load(document, fontStream);for (PDPage page : document.getPages()) {try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {contentStream.setFont(font, 20);contentStream.setNonStrokingColor(Color.LIGHT_GRAY);contentStream.beginText();contentStream.newLineAtOffset(100, 100);contentStream.showText(watermarkText);contentStream.endText();}}}ByteArrayOutputStream outputStream = new ByteArrayOutputStream();document.save(outputStream);return outputStream.toByteArray();}
}

这样就基本都可以出来了,样式什么的需要后续自己调节。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com