-
2022-04-24 15:27:00
大体思路:html转换成canvas后生成图片导出pdf
1. 用到2个插件
html2canvas:html转canvas
jsPDF:canvas生成pdf(使用Javascript语言生成PDF的开源库)jspdf用法:将一个图片列表导出为pdf文件,根据图片宽高计算在pdf中的位置。
2. npm安装插件
npm install html2canvas
npm install jspdf
3. 自定义一个hooks函数:
import html2canvas from 'html2canvas'; import jsPDF from 'jspdf'; interface CompToPDFProps{ fileName:string; } const PDFFile = { A4:[592.28, 841.89], }; //自定义的hooks函数 const useCompToPDF = (props:CompToPDFProps) => { const {fileName} = props; const exportPDf = (element:HTMLElement | null)=>{ if(element){ html2canvas(element).then((canvas)=>{ //获取画布的宽高 let canvasWidth=canvas.width; let canvasHeight=canvas.height; //一页PDF显示html生成的canvas高度 let pdfPageHeight=(PDFFile.A4[1]/PDFFile.A4[0]) * canvasWidth; //未生成pdf的html页面内高度 let pdfAllHeight=canvasHeight; let position = 0; //页面偏移 //转换图片为dataURL,参数:图片格式和清晰度(0-1) let pageData = canvas.toDataURL('image/jpeg', 1.0); //html页面生成的canvas在pdf中图片的宽高 let imgWidth = PDFFile.A4[0] - 60 ; //减去边距宽度 let imgHeight = (canvasHeight/canvasWidth)*PDFFile.A4[0]; //方向p竖直 l横向,尺寸ponits,格式a4 let pdf =new jsPDF('p', 'pt', PDFFile.A4); //当内容未超过pdf一页显示的范围,无需分页 if(pdfAllHeight<pdfPageHeight){ // 从图片顶部开始打印 30 左右边距, 0 上下边距 pdf.addImage(pageData, 'jpeg', 30, 0, imgWidth, imgHeight); }else{ while(pdfAllHeight>0){ pdf.addImage(pageData, 'jpeg', 0, position, imgWidth, imgHeight); pdfAllHeight-=pdfPageHeight; position-=PDFFile.A4[1]; //避免添加空白页 if(pdfAllHeight>0){ pdf.addPage(); } } } pdf.save(`${fileName}.pdf`); }); } } return { exportPDf, }; }; export default useCompToPDF;
3. 调用这个hooks导出pdf
import React,{useRef} from 'React'; //调用 const ref = useRef<HTMLDivElement>(null); const { exportPDF } = useCompPDF({fileName:'报告'}); //导出按钮 <Button onclick={()=>{exportPDF(ref.current);}} > 导出 </Button> //导出内容 <div ref={ref} style={{padding:10}}> ··· 内容 ··· </div>
官网地址:
更多相关内容 -
前端导出PDF文件.zip
2020-06-30 19:56:36只要你懂一点前端,就能轻松实现,对比目前后端输出PDF的功能非常复杂和维护成本极高 Demo实现功能 功能 支持 页头 是 页脚 是 页码 是 图片是 超链接 是 自定义文件名 是 每页水印 是(可实现,demo未提供) ——... -
纯前端导出pdf (完全不需要后端)
2022-03-29 14:18:01纯前端导出pdf (完全不需要后端) 一、vue-print-nb插件 npm install vue-print-nb --save //在main.js中 import Print from 'vue-print-nb' Vue.use(Print); 直接在vue中使用即可 <template> <div...前言
纯前端导出pdf (完全不需要后端)
一、vue-print-nb插件
npm install vue-print-nb --save
//在main.js中
import Print from 'vue-print-nb' Vue.use(Print);
直接在vue中使用即可
<template> <div class="home"> <button v-print="printObj">导出pdf</button> <div id="printMe" style="background:red;"> <p style="color:green;">评标区</p> <h1 style="font-size:20px;color:blue;">标题</h1> <img alt="Vue logo" src="../assets/logo.png" /> <HelloWorld msg="Welcome to Your Vue.js App" /> </div> </div> </template>
二、window.print()方法
//直接使用 function printpage(){ window.print(); }
三、html2canvas+jspdf(分页+ 不分页)
使用这种方式需要注意的是 根据需求, 如果需求的每页有一定的高度可以使用分页的方式更加美观, 但如果高度是动态的 建议使用不分页的方式 不会造成页面被裁切.
分页
// 导出页面为PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default{ install (Vue, options) { Vue.prototype.getPdf = function () { allowTaint: true; var title = this.htmlTitle; var element = document.getElementById("printMe"); // 这个dom元素是要导出pdf的div容器 var w = element.offsetWidth; // 获得该容器的宽 var h = element.offsetWidth; // 获得该容器的高 var offsetTop = element.offsetTop; // 获得该容器到文档顶部的距离 var offsetLeft = element.offsetLeft; // 获得该容器到文档最左的距离 var canvas = document.createElement("canvas"); var abs = 0; var win_i = document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条) var win_o = window.innerWidth; // 获得当前窗口的宽度(包含滚动条) if (win_o > win_i) { abs = (win_o - win_i) / 2; // 获得滚动条长度的一半 } canvas.width = w * 2; // 将画布宽&&高放大两倍 canvas.height = h * 2; var context = canvas.getContext("2d"); context.scale(2, 2); context.translate(-offsetLeft - abs, -offsetTop); // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此 // translate的时候,要把这个差值去掉 html2Canvas(element,{ allowTaint: true, //允许跨域 useCORS: true, //允许图片跨域 scale: 2 // 提升画面质量,但是会增加文件大小 }).then(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; //页面偏移 var position = 0; //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高 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(title + '.pdf'); }); } } }
不分页
toImage() { // 第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等 window.pageYoffset = 0; document.documentElement.scrollTop = 0; document.body.scrollTop = 0; html2canvas(document.getElementById("printMe"), { backgroundColor: "white", useCORS: true, //支持图片跨域 scale: 1, //设置放大的倍数 width: 1136, scrollY: 0, scrollX: 0, // height:100000, windowHeight: document.getElementById("printMe").scrollHeight, }).then((canvas) => { // 生成图片导出 // const a = document.createElement("a"); // a.href = canvas.toDataURL("image/png"); // a.download = this.title; // a.click(); // 生成pdf导出 var shareContent = document.querySelector("#printMe"); var width = shareContent.offsetWidth / 4; var height = shareContent.offsetHeight / 4; // console.log(height); var pageData = canvas.toDataURL("image/jpeg", 1.0); var img = new Image(); img.setAttribute("src", pageData); img.onload = function () { // 获取dom高度、宽度 img.width = img.width / 2; img.height = img.height / 2; img.style.transform = "scale(0.5)"; if (width > height) { // 此可以根据打印的大小进行自动调节 // eslint-disable-next-line var pdf = new jsPDF("l", "mm", [width * 0.3, height * 0.3]); } else { // eslint-disable-next-line var pdf = new jsPDF("p", "mm", [width * 0.3, height * 0.3]); } pdf.addImage(pageData, "jpeg", 0, 0, width * 0.3, height * 0.3); pdf.save("导出的报表名字" + ".pdf"); }; }); },
使用 html2canvas+jspdf 踩坑记
- 在vue项目中用html2canvas遇到因为有滚动条截图不完整问题的解决方法(设置height和windowHeight)
在生成图片前让页面滚动到最顶端. window.pageYoffset = 0; document.documentElement.scrollTop = 0; document.body.scrollTop = 0;
如果仍然无法解决,则可以: html2canvas(document.getElementById('dialog'), { backgroundColor: 'white', useCORS: true, //支持图片跨域 scale: 1, //设置放大的倍数 height: document.getElementById('dialog').scrollHeight, windowHeight: document.getElementById('dialog').scrollHeight })
-
图片跨域问题
1.在img标签上添加 crossorigin=“anonymous” 属性。允许图片跨域 不过设置这个之后,图片会无法显示 会报错Redirect at origin 'http://sub1.xx.com' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://sub2.xx.com' is therefore not allowed access.
这是因为你img是在缓存数据中 读取的 并没有访问远程这个图片的时候没有携带请求头。可以在图片路径上拼接上固定 字符串 ‘?any_string_is_ok’
<img class="companyLogo" crossorigin="anonymous" :src="indexPreviewData.companyInfo.logo + '?any_string_is_ok'" />
注意一定是固定字符串 。如果是随机字符串的话会导致CDN的缓存被击穿
2.使用 html2Canvas的时候 需要配置useCORS为 true
这个属性是 html2Canvas 开启跨域用的 可以在html2Canvas的文档上找到 -
canvas画布在主流浏览器中的尺寸限制
在IOS10下,自带浏览器和微信下,超过40964096像素则显示不了红色方块;
HUAWEI NXT-TL00手机自带浏览器和UC浏览器下,不能超过81928192像素;
在PC,CHROME浏览器,360浏览器,不能超过1638416384像素;
搜狗浏览器,要比1638416384稍微小一些;
firefox,最大数在11164*11164左右;
IE11、EDGE浏览器,没找到极限,只不过越大电脑越慢内存消耗严重;
总结
各有各的优势与缺陷, 一般情况下最好前后端使用文件流的方式导出最合适!!!
-
纯前端导出PDF分页截取问题处理
2022-05-06 11:38:50使用window.print()导出pdf,并解决截断问题需求:一个页面内放入两部分记录,数据由后端动态渲染(高度不一),导出的pdf要两部分分别各占一个A4
html代码:
js代码
methods: { exportPdf () { const printHTML = document.querySelector('#printId').innerHTML window.document.body.innerHTML = printHTML window.print() // 调用window打印方法 window.location.reload() } }
效果:
-
前端导出pdf文件
2021-09-13 11:23:38this.$get(url, {}, { responseType: 'blob' }).then(res => { //创建隐藏的可下载链接 const blob = new Blob([res]); const link = document.createElement('a'); ... evt.initEvent('click',this.$get(url, {}, { responseType: 'blob' }).then(res => { //创建隐藏的可下载链接 const blob = new Blob([res]); const link = document.createElement('a'); const evt = document.createEvent('HTMLEvents'); evt.initEvent('click', false, false); link.href = URL.createObjectURL(blob); //触发点击 link.download = req.name + suffixName; link.style.display = 'none'; //字符内容转变成blob地址 document.body.appendChild(link); link.click();//然后移除 //释放内存 window.URL.revokeObjectURL(link.href); document.body.removeChild(link ); });
-
前端导出pdf功能(超详细)
2021-03-02 17:55:58实现思路:将html页面生成pdf文件,需首先将页面转换为图片,然后再输出成pdf。 一、先引入html2canvas npm install html2canvas 二、项目内引入 import html2canvas from 'html2canvas' 三、生成方法 html <... -
vue:前端导出PDF 加图片:前端
2022-04-07 20:06:53npm i vue-to-pdf --save <div id="exportPdf" ref=...导出(pdf)</input> 使用该组件需要在main.js中进行配置 import Print from 'vue-to-pdf' Vue.use(Print) // 注册 方法 //导出(pdf) savePdf(){ this. -
前端导出pdf以及导出内容截断的解决办法
2021-06-11 06:33:34pdf.save(pdfName + ‘.pdf‘) } else { try { pdf.deletePage(0); setTimeout(createImpl, 500, canvas); } catch (err) { // console.log(err); } } } }) }); 原文:... -
前端导出pdf
2019-09-02 14:17:231.安装插件 yarn add jspdf@1.4.1 yarn add html2canvas 2.引入 import ... import {default as JSPDF} from ‘jspdf’; // this.text 是要导出的内容 handleExport = () => { html2canvas(thi... -
pdfmake支持html,pdfMake前端导出pdf
2021-06-23 05:44:54pdfMake前端导出pdf目前导出PDF还是后端(或nodejs)比较好. (如果没有必要)导出方案后端: IText,wkhtmltopdf...等等.前端: jsPdf,pdfKit,react-pdf...等等.现在网上一提到前端导出pdf的绝大多数都是... -
JS纯前端导出PDF及分页和使用window.print()保存PDF
2021-09-06 17:49:25最近由于项目要求需要将导出PDF类文件,其中涉及到固定表头,翻页,样式调整等问题 一开始选择了网上较多讲解的使用html2canvas.js和jspdf.js先转图片再转PDF的方法。 var xsxf = document.getElementById("export... -
纯前端导出PDF之采坑记录
2020-01-03 18:00:421、导出pdf思路 step1:将要导出的页面“截图”为图片(html2canvas); step2:将图片专为pdf,实现下载pdf功能(jsPDF); 2、具体代码 function exportPdf() { const target = document.getElementById... -
前端导出PDF
2020-05-15 17:27:52前端导出PDF小记直接上代码(dom)直接上代码(js) 最近开发接到需求,要求导出页面dom为PDF的文件,开发中的一些问题在这里做个记录,开发使用vue.js,自行下载JsPdf(html2canvas.js、html2canvas.min.js、jsPdf.debug... -
Angular8 使用jspdf、html2canvas 前端导出PDF
2021-04-16 14:54:42Html <div id="pdfbox"> pdf内容,html </div> <button class="btn btn-cyan" (click)="ExportPDF()"> <i class="fa fa-plus-circle">...导出</span> </butto -
前端导出 pdf 分页带表头,导出pdf 不分页
2022-08-01 16:15:28前端导出pdf -
前端vue导出pdf
2022-06-21 17:55:08纯vue前端导出pdf(html类似) -
纯前端导出pdf
2021-10-24 20:50:39导出部分js代码 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default { install (Vue, options) { Vue.prototype.$getPdf = function (id, title) { // 获取当前浏览器滚动条... -
前端导出PDF之pdfmake
2021-07-10 14:19:28pdfmake通过编辑特定格式的 pdf描述对象,传给pafmake ,来生成pdf 默认pdfmake不支持中文 如何支持中文 要支持中文,就需要配置中文字体。根据文档介绍有两种方式:1.使用在线字体配置。2.使用本地 vfs(virtual ... -
简述前端如何导出PDF的功能实现
2022-01-14 16:09:04前端导出PDF 首先,你需要安装相关插件或依赖 npm install html2canvas npm install jspdf 在项目的 src/utils 目录下新建tools.js文件,写入以下内容 import html2canvas from 'html2canvas'; import JsPDF ... -
前端导出pdf文档-jspdf用法
2022-06-08 14:04:49导出pdf -
纯前端将网页导出pdf文件
2021-11-29 10:31:57另存为pdf文件也挺方便哒,但是很多人不知道呀)。 引入js文件(快夸我,别人都是让你们自己去网上找,给的本地文件引用地址): <script src=... -
前端PDF 导出功能
2022-03-10 11:00:33一、在 Vue 中,将 html 内容导出为 PDF 代码如下(示例): <div ref="PDF"> <!-- 我是需要导出的内容 --> </div> // 生成pdf getPDF() { this.generatePDF( this.$refs.PDF, "我是下载的... -
前端VUE导出PDF
2021-07-29 09:12:30导出PDF图片参考步骤1、安装需要的包2、写一个工具JS,打印界面打印时用来调用3、解决内容截取不全、模糊等问题4、写在 参考 1、Vue 导出PDF文件,导出pdf模糊,导出图片不全,导出不清晰问题终极解决方案 (作者:IT... -
前端vue导出PDF
2021-11-29 20:06:52async function getPdf(title,domName,_this) {//文件名,'name' // return let a4HeightRef=0 let leftHeight=0 let position=0 let pdfProgress=1 let a4Width=831.89 let a4Height=579.28 let canvasList=[] ... -
Vue 前端导出 PDF & Excel(jspdf、html2canvas、vue-json-excel)
2020-11-04 14:28:39有时我们前端会遇到懒蛋子后端 or 膈应人的产品,让我们前端自己导出 PDF & Excel,没关系,心(bao)平(tiao)气(ru)和(lei) 的跟他说:我可以! 一、html2canvas + jsPDF 导出 PDF 插件用到的是:html2canvas 和... -
前端实现 导出图片,导出PDF(截图原理)
2021-07-15 17:13:08导出图片 1.安装依赖 yarn add dom-to-image 或 npm install dom-to-image --save yarn add file-saver 或 npm install file-saver --save 2.代码实现 //导入包 import domtoimage from 'dom-to-image'; import { ... -
前端页面导出PDF文件,并添加水印
2022-04-11 15:58:45最近在维护一个老项目(后端是ssm,前端是jsp),要求导出一个报表页,导出为pdf文档。表头需要增加 ‘内部资料,不宜公开‘,同时页面增加水印。 导出效果: 如下图(仅展示一部分): 整体思路: 本来想着java...