当前位置: 首页 > news >正文

Demo: 实现PDF加水印以及自定义水印样式

实现PDF加水印以及自定义水印样式

在这里插入图片描述

<template><div><button @click="previewHandle">预览</button><button @click="downFileHandle">下载</button><el-input v-model="watermarkText" /><el-input v-model.number="watermarkrotate" /><iframe id="log_frame" class="log-iframe" frameborder="0" :src="pdfPreviewUrl"></iframe></div>
</template><script setup>
import { ref, reactive, onMounted } from 'vue'
import { degrees, PDFDocument, rgb, StandardFonts } from "pdf-lib";
import fontkit from '@pdf-lib/fontkit'const pdfFileEnd = ref('http://111.229.162.189:8003/file/construction/2024_01_08/三高共管对接接口(5)_14ba6d68.pdf')
const pdfPreviewBlob = ref()
const pdfPreviewUrl = ref('/pdf/web/viewer.html?file=http://111.229.162.189:8003/file/construction/2024_01_08/三高共管对接接口(5)_14ba6d68.pdf')const watermarkText = ref('2024-01-17') // 水印文字
const watermarkrotate = ref(45) // 水印旋转角度// PDF 下载
const addWatermark = async (rotate) => {/*2.获取pdf文件的arrarybuffer文件流可请求后台接口返回的base64文件流,然后转成arrayBuffer类型可访问前端项目中的本地文件,不能直接访问服务器链接文件,会有跨域问题*/try {// 1.通过url获取pdf文件的arrarybuffer文件流const existingPdfBytes = await fetch(pdfFileEnd.value).then((res) => res.arrayBuffer());// 2.将arraybuffer数据转成pdf文档const pdfDoc = await PDFDocument.load(existingPdfBytes);// 3.1  内置字体(不支持中文), 如果水印中不包含中文可直接用内置字体(不支持中文)// const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);// 3.2 自定义字体,如不需要使用自定义字体可以将这一段全部注释掉,也不用下载自定义字体文件和自定义字体工具fontkit// 将自己下载好的.ttf文件放置项目中,然后访问文件路径(不支持访问本地文件)// const fontBytes = await fetch("@/assets/DS-DIGIT.TTF").then((res) => res.arrayBuffer());// pdfDoc.registerFontkit(fontkit); // 自定义字体挂载、fontkit为自定义字体注册工具// const fontkitFile = await pdfDoc.embedFont(fontBytes);//  4. 为每页pdf添加文字水印const pages = pdfDoc.getPages();for (let i = 0; i < pages.length; i++) {const noPage = pages[i];const { width, height } = noPage.getSize();for (let i = 0; i < 10; i++) {for (let j = 0; j < 3; j++) {noPage.drawText(watermarkText.value, {x: 230 * j + 36,y: (height / 4) * i + 20,size: 20,// font: fontkitFile, //字体(内置/自定义)color: rgb(0.46, 0.53, 0.6),rotate: degrees(rotate),opacity: 0.3,});}}}//5. 保存pdf文件的unit64Arrary文件流const pdfBytes = await pdfDoc.save();pdfPreviewBlob.value = pdfBytes// const blob = new Blob([pdfBytes], { type: 'application/pdf' });// const url = window.URL.createObjectURL(blob);// pdfPreviewUrl.value = '/pdf/web/viewer.html?file=' + url// saveByteArray("水印PDF.pdf", pdfBytes);} catch (error) {console.log("文件下载失败!");}
}
// 预览文件
const previewHandle = async () => {console.log(typeof(watermarkrotate.value));await addWatermark(watermarkrotate.value)const blob = new Blob([pdfPreviewBlob.value], { type: 'application/pdf' });const url = window.URL.createObjectURL(blob);pdfPreviewUrl.value = '/pdf/web/viewer.html?file=' + url
}
// 下载文件
const downFileHandle = () => {var blob = new Blob([pdfPreviewBlob.value], { type: "application/pdf" });var link = document.createElement("a");link.href = window.URL.createObjectURL(blob);link.download = '水印pdf';link.click();
}onMounted(() => {addWatermark()
})
</script><style lang="scss" scoped>
.log-iframe {width: 800px;height: 520px;
}
</style>
http://www.lryc.cn/news/285675.html

相关文章:

  • 每日OJ题_算法_二分查找①_力扣704. 二分查找
  • 【Python】--- 基础语法(1)
  • 详解gorm中DB对象的clone属性
  • 数据库(MySQL库表操作)
  • 内网穿透的应用-如何使用Docker部署Redis数据库并结合内网穿透工具实现公网远程访问
  • 计算机网络复试
  • Android学习之路(23)组件化框架ARouter的使用
  • HCIA vlan练习
  • Ubuntu下安装Gazebo仿真器
  • Chatgpt+Comfyui绘图源码说明及本地部署文档
  • ts中 any 和 unknown 有什么区别,分别什么时候使用
  • C++中命名空间、缺省参数、函数重载
  • 【笔记】Helm-3 主题-12 Helm插件指南
  • 2023.1.17 关于 Redis 持久化 AOF 策略详解
  • P2PNet推理和训练
  • pyexecjs原生js加密算法逆向
  • 数据结构Java版(4)——链表
  • cfssl简单使用
  • 基于Word2vec词聚类的关键词实现
  • 开源项目_大模型应用_Chat2DB
  • 【线性代数与矩阵论】范数理论
  • 【C++】priority_queue模拟实现过程中值得注意的点
  • Git提交 ssh: connect to host github.com port 22: Connection timed out解决方案
  • Java调用WebService接口,SOAP协议HTTP请求返回XML对象
  • Django框架二
  • 工业相机与镜头参数及选型
  • VSCode使用Makefile Tools插件开发C/C++程序
  • 用C语言验证“三门定理”
  • 计算机网络-分层结构,协议,接口,服务
  • 前端开发 2: CSS