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

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

Demo: 实现PDF加水印以及自定义水印样式_第1张图片

<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>

你可能感兴趣的:(vue,js基础语法,HTML+CSS+JS,pdf,javascript,前端,vue.js)