基于html2canva jspdf 实现前端页面加水印 并导出页面PDF; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12761

效果图如下:

 

代码实现如下:

# 使用方法

```使用方法

<!-- 引入加入 导出pdf插件 -->

<script type="text/javascript" src="./static/html2canvas.js"></script>

<script type="text/javascript" src="./static/jspdf.debug.js"></script>

//  调用页面加水印方法

this.watermark({

"watermark_txt": "中国广东cc.gd"

});

// 调用下载pdf报告方法

downKcReport();

```

#### HTML代码部分

```html

<template>

<view class="content">

<view class="exportPdfBtn" @click="downKcReport()">导出PDF</view>

<!-- 可视化 -->

<view style=" border-radius: 4px; margin-top: -4px;">

<!-- 柱形图 堆叠 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px;"> 柱形图 堆叠

</h4>

<div class="mui-content-padded">

<div id="dsj_zscq" style="width: calc(100vw - 40px); height: 280px;"></div>

</div>

<!-- 折线图 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px;"> 折线图

</h4>

<div class="mui-content-padded">

<div id="dsj_cxcg" style="width: calc(100vw - 40px); margin: -18px 0px; height: 280px;">

</div>

</div>

<!-- 柱状图 + 折线图-->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

柱状图 + 折线图 </h4>

<div class="mui-content-padded">

<div id="dsj_zlhjl" style="width: calc(100vw - 40px); height: 290px;"></div>

</div>

<!-- 有效知识产权结构 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

饼图 </h4>

<div class="mui-content-padded">

<div id="dsj_zscqjg" style="width: calc(100vw - 40px); height: 306px;"></div>

</div>

<!-- 专利iPC结构 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

树形结构图 </h4>

<div class="mui-content-padded">

<div id="dsj_zlipc_content"

style="margin-left: -10px;  width: calc(100vw - 40px); height: auto; margin-bottom: 30px;">

</div>

</div>

<!-- 柱状图 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

柱状图 </h4>

<div class="mui-content-padded">

<div id="dsj_zljz" style="width: calc(100vw - 40px); height: 280px;"></div>

</div>

<!-- 专利法律状态分布 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

饼图 </h4>

<div class="mui-content-padded">

<div id="dsj_zlfl" style="width: calc(100vw - 40px); height: 280px;"></div>

</div>

<!-- 专利寿命分布 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

柱状图 </h4>

<div class="mui-content-padded">

<div id="dsj_zlsm" style="width: calc(100vw - 40px); height: 280px;"></div>

</div>

<!-- 树形结构图 -->

<h4 style="margin-left: 12px; font-size: 16px; height: 30px; line-height: 30px; margin-top: 0px;">

树形结构图 </h4>

<div class="mui-content-padded">

<div id="dsj_zllhsq" style="width: calc(100vw - 40px); height: auto; margin-bottom: 30px;">

</div>

</div>

</view>

</view>

</template>

```

#### JS代码 (引入组件 填充数据)

```javascript

<script>

import myIndex from '../index/index.js'

export default {

data() {

return {

title: 'Hello'

}

},

mounted() {

// 刷新Echart数据

this.refreshEchartData();

},

onLoad() {

//  页面加水印方法

this.watermark({

"watermark_txt": "中国广东cc.gd"

});

},

methods: {

//  页面加水印方法

watermark(settings) {

//默认设置

var defaultSettings = {

watermark_txt: "text",

watermark_x: 20, //水印起始位置x轴坐标

watermark_y: 80, //水印起始位置Y轴坐标

watermark_rows: 80, //水印行数

watermark_cols: 20, //水印列数

watermark_x_space: 80, //水印x轴间隔

watermark_y_space: 102, //水印y轴间隔

watermark_color: '#aaa', //水印字体颜色

watermark_alpha: 0.4, //水印透明度

watermark_fontsize: '14px', //水印字体大小

watermark_font: '微软雅黑', //水印字体

watermark_width: 180, //水印宽度

watermark_height: 80, //水印长度

watermark_angle: 20 //水印倾斜度数

};

//采用配置项替换默认值,作用类似jquery.extend

if (arguments.length === 1 && typeof arguments[0] === "object") {

console.log("arguments = " + JSON.stringify(arguments[0]));

// 获取参数配置

var src = arguments[0];

for (let key in src) {

if (src[key] && defaultSettings[key] && src[key] === defaultSettings[key])

continue;

else if (src[key])

defaultSettings[key] = src[key];

}

}

var oTemp = document.createDocumentFragment();

//获取页面最大宽度

var page_width = Math.max(document.body.scrollWidth, document.body.clientWidth);

var cutWidth = page_width * 0.0150;

var page_width = page_width - cutWidth;

//获取页面最大高度

var page_height = Math.max(document.body.scrollHeight, document.body.clientHeight) + 2860;

// var page_height = document.body.scrollHeight+document.body.scrollTop;

//如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔

if (defaultSettings.watermark_cols == 0 || (parseInt(defaultSettings.watermark_x + defaultSettings

.watermark_width * defaultSettings.watermark_cols + defaultSettings.watermark_x_space * (

defaultSettings.watermark_cols - 1)) > page_width)) {

defaultSettings.watermark_cols = parseInt((page_width - defaultSettings.watermark_x + defaultSettings

.watermark_x_space) / (defaultSettings.watermark_width + defaultSettings

.watermark_x_space));

defaultSettings.watermark_x_space = parseInt((page_width - defaultSettings.watermark_x -

defaultSettings

.watermark_width * defaultSettings.watermark_cols) / (defaultSettings.watermark_cols - 1));

}

//如果将水印行数设置为0,或水印行数设置过大,超过页面最大长度,则重新计算水印行数和水印y轴间隔

if (defaultSettings.watermark_rows == 0 || (parseInt(defaultSettings.watermark_y + defaultSettings

.watermark_height * defaultSettings.watermark_rows + defaultSettings.watermark_y_space * (

defaultSettings.watermark_rows - 1)) > page_height)) {

defaultSettings.watermark_rows = parseInt((defaultSettings.watermark_y_space + page_height -

defaultSettings

.watermark_y) / (defaultSettings.watermark_height + defaultSettings.watermark_y_space));

defaultSettings.watermark_y_space = parseInt(((page_height - defaultSettings.watermark_y) -

defaultSettings

.watermark_height * defaultSettings.watermark_rows) / (defaultSettings.watermark_rows - 1));

}

var x;

var y;

for (var i = 0; i < defaultSettings.watermark_rows; i++) {

y = defaultSettings.watermark_y + (defaultSettings.watermark_y_space + defaultSettings

.watermark_height) * i;

for (var j = 0; j < defaultSettings.watermark_cols; j++) {

x = defaultSettings.watermark_x + (defaultSettings.watermark_width + defaultSettings

.watermark_x_space) *

j;

var mask_div = document.createElement('div');

mask_div.id = 'mask_div' + i + j;

mask_div.className = 'mask_div';

mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));

//设置水印div倾斜显示

mask_div.style.webkitTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";

mask_div.style.MozTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";

mask_div.style.msTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";

mask_div.style.OTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";

mask_div.style.transform = "rotate(-" + defaultSettings.watermark_angle + "deg)";

mask_div.style.visibility = "";

mask_div.style.position = "absolute";

mask_div.style.left = x + 'px';

mask_div.style.top = y + 'px';

mask_div.style.overflow = "hidden";

mask_div.style.zIndex = "9999";

mask_div.style.pointerEvents = 'none'; //pointer-events:none  让水印不遮挡页面的点击事件

//mask_div.style.border="solid #eee 1px";

mask_div.style.opacity = defaultSettings.watermark_alpha;

mask_div.style.fontSize = defaultSettings.watermark_fontsize;

mask_div.style.fontFamily = defaultSettings.watermark_font;

mask_div.style.color = defaultSettings.watermark_color;

mask_div.style.textAlign = "center";

mask_div.style.width = defaultSettings.watermark_width + 'px';

mask_div.style.height = defaultSettings.watermark_height + 'px';

mask_div.style.display = "block";

oTemp.appendChild(mask_div);

};

};

document.body.appendChild(oTemp);

},

// 下载pdf报告

downKcReport() {

html2canvas(

document.body, {

scale: 2,

dpi: 192, //导出pdf清晰度

onrendered: function(canvas) {

var contentWidth = canvas.width;

var contentHeight = canvas.height;

//一页pdf显示html页面生成的canvas高度;

var pageHeight = contentWidth / 592.28 * 841.89;

//未生成pdf的html页面高度

var leftHeight = contentHeight;

//pdf页面偏移

var position = 0;

//html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])

var imgWidth = 595.28;

var imgHeight = 592.28 / contentWidth * contentHeight;

var pageData = canvas.toDataURL('image/jpeg', 1.0);

var pdf = new jsPDF('', 'pt', 'a4');

//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)

//当内容未超过pdf一页显示的范围,无需分页

if (leftHeight < pageHeight) {

pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);

} else {

while (leftHeight > 0) {

pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)

leftHeight -= pageHeight;

position -= 841.89;

//避免添加空白页

if (leftHeight > 0) {

pdf.addPage();

}

}

}

pdf.save(name + '.pdf');

console.log('成功导出pdf');

},

//背景设为白色(默认为黑色)

background: "#fff"

})

},

refreshEchartData() {

// 返回数据需在json转换格式工具 转成Json格式

let result = {

"data": {

"unionCompanyNum": 4,

"goldList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"fmsqYx": "1",

"cfmwyxzscqsl": "1",

"years": "1",

"yxzscqsl": "1",

"dnzlhjl": "1"

}],

"patentLifeList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"percentage": "1",

"quantity": "1",

"scope": "1-3",

"totalNum": "1"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"percentage": "1",

"quantity": "1",

"scope": "3-5",

"totalNum": "2"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"percentage": "1",

"quantity": "3",

"scope": "5-10",

"totalNum": "3"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"percentage": "1",

"quantity": "3",

"scope": "10-",

"totalNum": "4"

}],

"patentValueList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"fmgbZs": "1",

"fmsqYx": "1",

"syxxYx": "1",

"wgsjYx": "1",

"scope": "0-5",

"totalNum": "1",

"percentageHighRights": "1",

"percentageHigh": "1",

"dspw": "1",

"jslypw": "1"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"fmgbZs": "1",

"fmsqYx": "1",

"syxxYx": "1",

"wgsjYx": "1",

"scope": "5-10",

"totalNum": "1",

"percentageHighRights": "1",

"percentageHigh": "1",

"dspw": "1",

"jslypw": "1"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"fmgbZs": "1",

"fmsqYx": "2",

"syxxYx": "3",

"wgsjYx": "4",

"scope": "90-100",

"totalNum": "10"

}],

"legalList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"underTrial": "1",

"invalid": "1",

"efficient": "1",

"totalNum": "1",

"percentage": "1"

}],

"propertyRightList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"fmgbZs": "1",

"fmgbZsP": "1",

"fmsqYx": "1",

"fmsqYxP": "1",

"syxxYx": "1",

"syxxYxP": "1",

"wgsjYx": "1",

"wgsjYxP": "1",

"rzYx": "1",

"rzYxP": "1",

"maxPercentage": "1",

"maxPercentageRights": "1",

"dspw": "1",

"jslypw": "1"

}],

"unionPatentNum": 13,

"ipcList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"ipcDept": "1",

"ipcClass": "1",

"ipcNum": "1",

"ipcZbClass": "1",

"ipcZb": "1",

"dspw": "1",

"jslypw": "1"

}],

"yearList": [{

"isNewRecord": true,

"comId": "1",

"fmgbZs": "1",

"fmsqYx": "1",

"syxxYx": "1",

"wgsjYx": "1",

"rzYx": "1",

"years": "2022",

"dnkjcxcgkbjshl": "1",

"socialCode": "123456"

}, {

"isNewRecord": true,

"comId": "1",

"years": "2023",

"dnkjcxcgkbjshl": "2",

"socialCode": "123456"

}, {

"isNewRecord": true,

"comId": "1",

"years": "2026",

"dnkjcxcgkbjshl": "6",

"socialCode": "123456"

}, {

"isNewRecord": true,

"comId": "1",

"years": "2027",

"dnkjcxcgkbjshl": "7",

"socialCode": "123456"

}],

"unionList": [{

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"unionName": "测试5",

"unionNum": "5",

"unionCompany": "1"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"unionName": "测试4",

"unionNum": "4",

"unionCompany": "1"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"unionName": "测试3",

"unionNum": "3",

"unionCompany": "1"

}, {

"isNewRecord": true,

"comId": "1",

"socialCode": "123456",

"unionName": "测试1",

"unionNum": "1",

"unionCompany": "1"

}]

},

"statusCode": 200,

"header": {

"date": "Tue, 30 May 2023 07:08:28 GMT",

"powered-by": "JeeSite V5.0.1 0",

"transfer-encoding": "chunked",

"content-type": "application/json"

},

"errMsg": "request:ok"

};

let resultData = result.data;

if (resultData.yearList != undefined && resultData.yearList.length > 0) {

console.log('执行图表1');

// 填充图表1 2

myIndex.fillChartOneTwo(resultData.yearList);

}

if (resultData.goldList != undefined && resultData.goldList.length > 0) {

// 填充图表3

myIndex.fillChartThree(resultData.goldList);

}

if (resultData.propertyRightList != undefined && resultData.propertyRightList.length > 0) {

// 填充图表4

myIndex.fillChartFour(resultData.propertyRightList);

}

if (resultData.ipcList != undefined && resultData.ipcList.length > 0) {

// 填充图表5

myIndex.fillChartFive(resultData.ipcList);

}

if (resultData.patentValueList != undefined && resultData.patentValueList.length > 0) {

// 填充图表6

myIndex.fillChartSix(resultData.patentValueList);

}

if (resultData.legalList != undefined && resultData.legalList.length > 0) {

// 填充图表7 法律

myIndex.fillChartSeven(resultData.legalList);

}

if (resultData.patentLifeList != undefined && resultData.patentLifeList.length > 0) {

// 填充图表8 寿命

myIndex.fillChartEight(resultData.patentLifeList);

}

if (resultData.unionList != undefined && resultData.unionList.length > 0) {

// 填充图表9 专利联合

myIndex.fillChartNine(resultData, "广汽集团");

}

}

}

}

</script>

```

#### CSS

```CSS

<style>

.content {

display: flex;

flex-direction: column;

align-items: center;

justify-content: center;

}

.mui-content-padded {

margin: 10px 8px;

}

.mui-content-padded div {

font-size: 13px;

}

.exportPdfBtn {

width: 100px;

height: 40px;

line-height: 40px;

margin-top: 20px;

text-align: center;

}

</style>

```

基于html2canva jspdf 实现前端页面加水印 并导出页面PDF的更多相关文章

  1. Ionic页面加载前 ionic页面加载完成 ionic页面销毁执行的事件

    ionic 中$ionicView.beforeEnter(页面刚加载前)  $ionicView.afterEnter  (页面加载完成) $destroy(页面销毁) 广播事件 //ionic c ...

  2. 把页面上的图表导出为pdf文件,分享一种请求下载文件的方法

    最近客户提出一个需求,就是把页面上的图表导出为pdf文件. 找了很多资料.终于有了点头绪.最主要是参考了HighCharts的做法.http://www.hcharts.cn/ 实现原理:把页面图表的 ...

  3. Vue 给页面加水印指令(directive)

    页面需要水印 import Vue from 'vue' /** * watermark 指令 * 解决: 给页面生成水印 * 基本原理:给选择器添加背景图片 * 用法:v-watermark=&qu ...

  4. 页面加载后resize页面布局

    在我们写web的时候,有的时候页面加载完以后,布局位置有一些问题,手动改变窗口大小后则正常显示位置. 其实,我们手动改变窗口大小,是执行了resize方法. share一下兼容方法: coffee c ...

  5. 页面加载时,页面中DIV随之滑动出来;去掉页面滚动条

    <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...

  6. elementUI vue 页面加载的时候页面出现了黑字 页面优化处理 按钮弹出框文字

    elementUI 页面如果需要加载很多东西的时候, 自己定义的按钮或者弹出框dialog的文字就会显示在页面上, 一闪而过, 因此需要优化一下, elementUI 提供的loading有遮罩层, ...

  7. layui 页面加载 阴影 请求页面加载转圈页面

    var layerIndex= layer.load(1,{shade: [0.3, '#000']}); $.post('${pageContext.request.contextPath}/lea ...

  8. scrollReveal.js导致页面加载完之后页面中点击事件添加的css参数失效了(我的Hexo next博客引发的问题)

    文章目录 时间 背景 问题解决 个人博客:https://mmmmmm.me 源码:https://github.com/dataiyangu/dataiyangu.github.io 时间 2019 ...

  9. 基于ITextSharp插件在ASP.NET MVC中将图表导出为PDF

    样本: 在这个示例中,我们使用的是微软给我们提供的数据库,也就是家喻户晓的Northwind数据库.要下载Microsoft的免费样本Northwind数据库,您需要访问以下URL.下载Northwi ...

  10. HTML页面加载和解析流程详细介绍

    浏览器加载和渲染html的顺序 1. IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的. 2. 在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元 ...

随机推荐

  1. [ACM]TL-Kruskal

    #include<iostream> #include<cstdio> using namespace std; struct edge { int u; int v; int ...

  2. 一些随笔 No.1

    耦合 耦合是一个设计与逻辑上的问题 例如一个软件有20个功能,删除任意一个功能对别的19个功能不造成影响,就是低耦合 如果删除一个功能后其他功能会失去完整性,那么就是高耦合 Difference be ...

  3. 介绍一下js垃圾回收机制

    JavaScript中的垃圾回收机制负责自动管理内存,回收不再使用的对象所占用的内存空间.在JavaScript中,开发者不需要显式地分配和释放内存,垃圾回收器会自动完成这些操作.以下是关于JavaS ...

  4. 【LeetCode动态规划#07】01背包问题一维写法(状态压缩)实战,其二(目标和、零一和)

    目标和(放满背包的方法有几种) 力扣题目链接(opens new window) 难度:中等 给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在你有两个符号 + 和 -.对 ...

  5. 【译】ConfigureAwait FAQ

    .NET 在数年前就在语言和库中添加了 async/await.在那段时间里,它像野火一样蔓延开来,不仅在 .NET 生态系统中,而且在无数其他语言和框架中被复制.在 .NET 中也看到了大量的改进, ...

  6. day03-商家查询缓存02

    功能02-商铺查询缓存02 知识补充 (1)缓存穿透 https://blog.csdn.net/qq_45637260/article/details/125866738 缓存穿透(cache pe ...

  7. Gateway同时使用断言跟过滤器查询数据库报了这个错误怎么解决?

    DynamicServerListLoadBalancer for client shop-product-sentinel initialized: DynamicServerListLoadBal ...

  8. 笔记:C++学习之旅---面向对象程序的设计1

    笔记:C++学习之旅---面向对象程序的设计1 面向对象的主要特征 1.抽象 2.封装 3.继承 4.多态 抽象:将程序的每一部分都看作一个抽象的对象,即程序有一组抽象的对象组成的更复杂点,这些对象根 ...

  9. 使用Jmeter进行CPU、内存等监控

    一.需要的准备 1.jp@gc - PerfMon Metrics Collector插件(安装方法就不过多介绍啦!) 2.ServerAgent服务器(下载:https://github.com/u ...

  10. 【配置教程】撑起月6亿PV开源监控解决方案

    上次分享过<一个.Net Core开源监控解决方案,支持Redis.Elasticsearch.SqlServer>,这是Stack Overflow 开源的监控产品,基于.Net Cor ...