首页 前端知识 vue 纯前端预览pdf,纯前端实现pdf加水印下载文件也带水印,防止pdf下载

vue 纯前端预览pdf,纯前端实现pdf加水印下载文件也带水印,防止pdf下载

2024-05-27 09:05:50 前端知识 前端哥 995 139 我要收藏

效果图

1.pdf预览

  原理:主要是利用pdfh5这个插件来完成的

  使用方法:

  1.页面需要有一个容器例子:<div id="demo"></div>

  2.下载pdfh5插件

npm install pdfh5

  (注意:webpack5之后不会下载polyfill 需要手动下载 所以引入pdfh5的时候会报错)

  解决方案:下载 node-polyfill-webpack-plugin

npm install node-polyfill-webpack-plugin

  之后再vue.config.js里面配置

  // 头部引入

  const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

  const { defineConfig } = require('@vue/cli-service')

  module.exports = defineConfig({

    //...

    configureWebpack: {

      plugins: [new NodePolyfillPlugin()],

    }

  })

  3.解决报错之后下面直接使用

  this.pdfh5 = new Pdfh5("#demo", {

    pdfurl: this.url,

  });

  -----另外 需要我们引入css样式 还需要我们自己写一点css样式来修改转成pdf后里面图片过大 再最下面        

  2.pdf加水印

  原理:利用的是将pdf文件转化成二进制文件 再用画图的方式往里面画文字

  主要利用插件:pdf-lib @pdf-lib/fontkit

npm install pdf-lib

npm install @pdf-lib/fontkit

  (注意:这里使用字体的时候需要引入两个字体包再同级目录下的font下的两个包)

  这里面的预览还是用到的pdfh5来预览的

  使用方法:直接调用addWarker(url,warkerName) 方法

  参数说明:url:需要添加水印的pdf文件地址  

           warkerName添加水印字

  注意:一半这种都不允许下载 禁止鼠标右击事件就是再我们的元素上加上@contextmenu.prevent事件

  并且加css样式:

        

* {

    -webkit-touch-callout: none;

    -webkit-user-select: none;

    -moz-user-select: none;

    -ms-user-select: none;

    user-select: none;

  }

  下载pdf还是用的pdfh5中的download方法

另外附上完整代码

 <template>

  <div>

      <div class="xlsx-content">

          <div class="btnPdf">

              <button @click="viewpdf">预览pdf</button>

              <button @click="currenNum">查看当前页数</button>

              <button @click="addWarker">pdf加水印</button>

              <button @click="downPdf">下载pdf</button>

          </div>

          <div class="pdf" @contextmenu.prevent>

              <div id="demo"></div>

          </div>

      </div>

  </div>

</template>

<script>

import Pdfh5 from "pdfh5";

import "pdfh5/css/pdfh5.css";

import fontkit from "@pdf-lib/fontkit";

import {

    degrees,

    PDFDocument,

    rgb

} from "pdf-lib";

export default {

    components: {},

    data() {

        return {

            url: "自己输入pdf地址",

            pdfh5: null,

        };

    },

    methods: {

        // 预览pdf

        viewpdf() {

            (this.url =

                "自己输入pdf地址"),

            (this.pdfh5 = new Pdfh5("#demo", {

                pdfurl: this.url,

            }));

            this.pdfh5.on("render", function (status, msg, time) {

                this.goto(5);

            });

        },

        // 获取当前进度

        currenNum() {

            console.log(this.pdfh5, this.pdfh5.currentNum); //这里获取的就是进度

        },

        // 添加水印

        addWarker(url, warkerName) {

            url = '自己输入pdf地址'

            warkerName = '水印文字'

            let that = this;

            changeBlob().then((res) => {

                res.arrayBuffer().then((rel) => {

                    // 获取arrauBuffer文件

                    viewmodifyPdf(rel);

                });

            });

            //地址转文件

            function changeBlob() {

                return new Promise((resolve) => {

                    const xhr = new XMLHttpRequest();

                    xhr.open("GET", url, true);

                    xhr.responseType = "blob";

                    xhr.onload = () => {

                        if (xhr.status === 200) {

                            resolve(xhr.response);

                        }

                    };

                    xhr.send();

                });

            }

            // 预览水印文件

            async function viewmodifyPdf(file) {

                // 将arrayBuff文件加载pdf文件

                const pdfDoc = await PDFDocument.load(file);

                // 引入自定义字体

                let url = require("./font/Alibaba_PuHuiTi_2.0_55_Regular_85_Bold.ttf");

                const fontBytes = await fetch(url).then((res) => res.arrayBuffer());

                // 自定义字体挂载

                pdfDoc.registerFontkit(fontkit);

                const customFont = await pdfDoc.embedFont(fontBytes);

                // 获取文档所有页

                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(warkerName, {

                                x: 230 * j,

                                y: (height / 4) * i,

                                size: 16,

                                font: customFont, //这里使用的是自定义字体

                                color: rgb(0.46, 0.53, 0.6),

                                rotate: degrees(-45),

                                opacity: 0.3,

                            });

                        }

                    }

                }

                // 获取水印文件

                const pdfBytes = await pdfDoc.save();

                let blobData = new Blob([pdfBytes], {

                    type: "application/pdf;Base64"

                });

                that.url = window.URL.createObjectURL(blobData) + "#toolbar=0";

                that.pdfh5 = new Pdfh5("#demo", {

                    pdfurl: that.url,

                });

            }

        },

        downPdf() {

            this.pdfh5.download("test");

        },

    },

};

</script>

<style lang="scss" scoped>

.pdf {

    width: 400px;

    height: 500px;

}

// 因为是禁止下载 所以页面也不允许右击保存

img {

    pointer-events: none;

}

* {

    -webkit-touch-callout: none;

    -webkit-user-select: none;

    -moz-user-select: none;

    -ms-user-select: none;

    user-select: none;

}

</style><style>

/* 解决pdfh5内部图片太大的问题 */

.pdfjs .pdfViewer {

    position: relative;

    top: 0;

    left: 0;

    width: 100% !important;

    padding: 10px 8px;

}

.pdfjs .pdfViewer .pageContainer {

    width: 100% !important;

    margin: 0px auto 8px auto;

    position: relative;

    overflow: visible;

    -webkit-box-shadow: darkgrey 0px 1px 3px 0px;

    -moz-box-shadow: darkgrey 0px 1px 3px 0px;

    box-shadow: darkgrey 0px 1px 3px 0px;

    background-color: white;

    box-sizing: border-box;

}

.pdfjs .pdfViewer .pageContainer img {

    width: 100% !important;

    height: 100% !important;

    position: relative;

    z-index: 100;

    pointer-events: none;

    /* user-select:none; */

}

</style>

转载请注明出处或者链接地址:https://www.qianduange.cn//article/9636.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!