一、html2canvas – 將dom變成圖片:
下載或者安裝html2canvas:官網(wǎng)
1、將文檔放在本地,用原生js進(jìn)行引用和使用。
① 新建一個(gè)名為 html2canvas.min.js
的文件,并且將線上的內(nèi)容進(jìn)行復(fù)制。
② 引入 js 文件:
// js直接引入 -- 未嘗試
<script type="text/javascript" src="XXX/html2canvas.js"></script>
// layui使用
// 首先在html2canvas.js文件中添加exports
layui.define([],function(exports){
// 復(fù)制的內(nèi)容...
exports('html2canvas',html2canvas);
})
// 其次進(jìn)行自定義插件的引入
layui.define(['appsmenu'],function (exports) {
exports("conf", {
// 第三方擴(kuò)展
extend: {
// 引入html轉(zhuǎn)圖片的插件
html2canvas: "lay/extends/html2canvas.min",
}
}
})
2、使用 npm
進(jìn)行安裝使用:
待續(xù)。。。
二、jsPDF – 將圖片變成pdf:
下載或者安裝jsPDF :
- github
- 中文網(wǎng)站
-
CDN
- Jspdf.es.js:ES 2015 模塊格式。
- Jspdf.umd.js:UMD模塊格式,用于 AMD 或腳本標(biāo)簽加載。
- Jspdf.polyfills.js:Internet Explorer等舊瀏覽器所需的兼容文件。
1、將文檔放在本地,用原生js進(jìn)行引用和使用。
① 新建一個(gè)名為 jsPDF.min.js
的文件,并且將線上(我找到的都不能用)或者資源 的內(nèi)容進(jìn)行復(fù)制。
② 引入 js 文件:
// js直接引入 -- 未嘗試
<script type="text/javascript" src="XXX/jsPDF.js"></script>
// CDN引入 -- 未嘗試
<script type="text/javascript" src="https://cdn.staticfile.org/jspdf/2.5.1/jspdf.umd.min.js"></script>
// layui使用
// 首先在jsPDF.min.js文件中添加exports
layui.define([],function(exports){
exports('jsPDF',jsPDF);
})
// 其次進(jìn)行自定義插件的引入
layui.define(['appsmenu'],function (exports) {
exports("conf", {
// 第三方擴(kuò)展
extend: {
// 引入圖片轉(zhuǎn)pdf的插件
jsPDF: "lay/extends/jsPDF.min",
}
}
})
2、使用 npm
進(jìn)行安裝使用:
待續(xù)。。。
三、普通使用(html2canvas+jsPDF):
1、 layui
或者原生js
使用:
// html:
<div id="box">
<button id="btn">下載為pdf</button>
內(nèi)容....
</div>
// js:
// layui引入:
layui.define(['html2canvas', 'jsPDF'], function (exports) {
var html2canvas = layui.html2canvas; // 引入html轉(zhuǎn)圖片
var jsPDF = layui.jsPDF; // 引入圖片轉(zhuǎn)pdf
// 初始化
var init = function() {
// 點(diǎn)擊下載按鈕
document.getElementById("btn").onclick=function(){
html2canvas(document.getElementById("box"),{
allowTaint: false, // 是否允許跨域圖像。會(huì)污染畫布,導(dǎo)致無法使用canvas.toDataURL 方法
backgroundColor: '#fff', // 畫布背景色(如果未在DOM中指定)。設(shè)置null為透明
useCORS: true, // 是否嘗試使用CORS從服務(wù)器加載圖像
dpi: 192, // 導(dǎo)出pdf清晰度
scale: window.devicePixelRatio * 3, // 用于渲染的比例。默認(rèn)為瀏覽器設(shè)備像素比率。
}).then(canvas => {
// html生成圖片的數(shù)據(jù)
var imageData = canvas.toDataURL('image/jpeg', 1.0);
// 原本的html頁(yè)面的寬高
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
// 當(dāng)分辨率是72像素/英寸時(shí),A4紙像素長(zhǎng)寬分別是842×595
var a4Width = 595; // A4 寬度
var a4Height = (595 / canvasWidth) * canvasHeight; // A4總高度
// 生成pdf的一頁(yè)顯示html的高度
let pageHeight = canvasWidth / 595 * 842;
// 未生成pdf的html頁(yè)面高度,最初是整體的高度
let restHeight = canvasHeight;
// 頁(yè)面上下偏移的大小
var position = 0;
/**
* 參數(shù)1:方向:l:橫向 p:縱向
* 參數(shù)2:?jiǎn)挝唬?pt"、"mm"、"cm"、"m"、"in"、"px"
* 參數(shù)3:格式:默認(rèn)為a4
*/
var pdf = new jsPDF('p', 'pt', 'a4');
// 當(dāng)內(nèi)容未超過pdf一頁(yè)顯示的范圍,無需分頁(yè)
if (restHeight < pageHeight) {
/**
* 將圖像添加到PDF中
* 參數(shù)1:圖片的url
* 參數(shù)2:圖片的格式
* 參數(shù)3:圖片上下偏移的大小
* 參數(shù)4:原始寬度
* 參數(shù)5:原始高度
*/
pdf.addImage(imageData, 'JPEG', 0, position, a4Width, a4Height );
} else {
while(restHeight > 0) {
pdf.addImage(imageData, 'JPEG',0, position, a4Width, a4Height)
restHeight -= pageHeight;
position -= 842;
if(restHeight > 0) {
// 在PDF文檔中添加新頁(yè)面
pdf.addPage();
}
}
}
// 保存為pdf格式的文件
pdf.save('生成的pdf文件.pdf')
})
}
}
var Class = {
init: function (options) {
init();
return this;
}
}
exports('XXX', Class);
)}
2、 vue/react
框架進(jìn)行使用:
待續(xù)。。。文章來源:http://www.zghlxwxcb.cn/news/detail-719177.html
四、模塊分割(html2canvas+jsPDF – 文字會(huì)截?cái)?,除了讓后端做,沒找到別的解決辦法,感覺后端的插件比前端的更好用…):
參考鏈接:https://blog.csdn.net/qq_32244819/article/details/109678481文章來源地址http://www.zghlxwxcb.cn/news/detail-719177.html
具體代碼:
// 點(diǎn)擊下載按鈕
document.getElementById("btn").onclick=function(){
outPutPdfFn()
}
// 導(dǎo)出方法
var outPutPdfFn = function() {
const A4_WIDTH = 592.28; // A4紙的寬
const A4_HEIGHT = 841.89; // A4紙的高
console.log('正在導(dǎo)出pdf,請(qǐng)稍候...');
let target = document.getElementById('box'); // 需要打印的頁(yè)面的dom
let pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT; // 根據(jù)比例換算一頁(yè)的高度
// 獲取分割的dom,即class類名為splitItem的dom
let splitItemAll = document.getElementsByClassName('splitItem');
// 進(jìn)行分割操作,當(dāng)分塊的內(nèi)容超出a4紙的高度,則在這個(gè)塊之前插入一個(gè)空白的塊,將原有的塊下移進(jìn)行分割
for (let i = 0; i < splitItemAll.length; i++) {
// 計(jì)算當(dāng)前模塊需要分成幾部分
let modulesNum = Math.ceil((splitItemAll[i].offsetTop + splitItemAll[i].offsetHeight) / pageHeight);
if (isSplit(splitItemAll, i, modulesNum * pageHeight)) {
let divParent = splitItemAll[i].parentNode; // 獲取當(dāng)前需要分割塊的父節(jié)點(diǎn)
let newNode = document.createElement('div');
newNode.className = 'emptyDiv';
newNode.style.background = '#ffffff';
// 計(jì)算需要插入塊的高度
let _H = modulesNum * pageHeight - (splitItemAll[i].offsetTop + splitItemAll[i].offsetHeight);
newNode.style.height = _H + 'px';
newNode.style.width = '100%';
let nextDom = splitItemAll[i].nextSibling; // 獲取當(dāng)前需要分割塊的下一個(gè)兄弟節(jié)點(diǎn)
// 判斷兄弟節(jié)點(diǎn)是否存在
console.log(nextDom);
if (nextDom) {
// 存在則將新節(jié)點(diǎn)插入到下一個(gè)兄弟節(jié)點(diǎn)的前面
divParent.insertBefore(newNode, nextDom);
} else {
// 不存在則直接添加
divParent.appendChild(newNode);
}
}
}
getPdf('導(dǎo)出pdf', 'box')
}
/**
* 計(jì)算當(dāng)前內(nèi)容是否跨越了a4大小,以此分割
* @params nodes 拿到的所有需要分割的dom
* @params index 當(dāng)前需要分割內(nèi)容的索引
* @params pageHeight A4紙的高度
*/
var isSplit = function(nodes, index, pageHeight) {
// 當(dāng)前需要分割的內(nèi)容:內(nèi)容高度+內(nèi)容距離頁(yè)面定位父元素(/body)的高度 < 頁(yè)面的高度
// 當(dāng)前需要分割的內(nèi)容的下一個(gè)兄弟節(jié)點(diǎn):內(nèi)容高度+內(nèi)容距離頁(yè)面定位父元素(/body)的高度 > 頁(yè)面的高度
if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {
return true;
}
return false;
}
// 導(dǎo)出pdf
var getPdf = function(title, dom) {
html2canvas(document.getElementById(dom),{
allowTaint: false, // 是否允許跨域圖像。會(huì)污染畫布,導(dǎo)致無法使用canvas.toDataURL 方法
backgroundColor: '#fff', // 畫布背景色(如果未在DOM中指定)。設(shè)置null為透明
useCORS: true, // 是否嘗試使用CORS從服務(wù)器加載圖像
dpi: 192, // 導(dǎo)出pdf清晰度
scale: window.devicePixelRatio * 3 // 用于渲染的比例。默認(rèn)為瀏覽器設(shè)備像素比率。增加清晰度
}).then(canvas => {
// html生成圖片的數(shù)據(jù)
var imageData = canvas.toDataURL('image/jpeg', 1.0);
// 原本的html頁(yè)面的寬高
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
// 當(dāng)分辨率是72像素/英寸時(shí),A4紙像素長(zhǎng)寬分別是842×595
var a4Width = 592.28; // A4 寬度
var a4Height = (592.28 / canvasWidth) * canvasHeight; // A4總高度
// 生成pdf的一頁(yè)顯示html的高度
let pageHeight = canvasWidth / 592.28 * 841.89;
// 未生成pdf的html頁(yè)面高度,最初是整體的高度
let restHeight = canvasHeight;
// 頁(yè)面上下偏移的大小
var position = 0;
/**
* 參數(shù)1:方向:l:橫向 p:縱向
* 參數(shù)2:?jiǎn)挝唬?pt"、"mm"、"cm"、"m"、"in"、"px"
* 參數(shù)3:格式:默認(rèn)為a4
*/
var pdf = new jsPDF('p', 'pt', 'a4');
// 當(dāng)內(nèi)容未超過pdf一頁(yè)顯示的范圍,無需分頁(yè)
if (restHeight < pageHeight) {
/**
* 將圖像添加到PDF中
* 參數(shù)1:圖片的url
* 參數(shù)2:圖片的格式
* 參數(shù)3:圖片上下偏移的大小
* 參數(shù)4:原始寬度
* 參數(shù)5:原始高度
*/
pdf.addImage(imageData, 'JPEG', 0, 0, position, a4Height );
} else {
while(restHeight > 0) {
pdf.addImage(imageData, 'JPEG',0, position, a4Width, a4Height)
restHeight -= pageHeight;
position -= 841.89;
if(restHeight > 0) {
// 在PDF文檔中添加新頁(yè)面
pdf.addPage();
}
}
}
// 保存為pdf格式的文件
pdf.save(`${title}.pdf`)
})
}
五、echarts圖表模糊的解決辦法:
// 方法一:初始化echarts的時(shí)候,添加清晰度配置 devicePixelRatio
echarts.init(chartDom, null, { devicePixelRatio: window.devicePixelRatio * 3 });
// 方法二:使用svg渲染,這個(gè)效果更好,就是需要調(diào)整grid,不然圖表不完整
// echarts.init(chartDom, null, { renderer: "svg" })
到了這里,關(guān)于純前端--原生js將html頁(yè)面變成pdf文件(html2canvas+jsPDF)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!