vue实现打印,导出为pdf(纯前端且亲测有用)

本文详细介绍了如何在Vue项目中实现纯前端的打印功能和PDF导出。对于打印,通过vue-print-nb插件进行配置,包括安装、引入、设置id和v-print指令。对于PDF导出,文章提到了需要安装相关包,指定id,创建事件处理方法并在自定义文件中编写代码来完成操作。这两个功能均能处理包含图片的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

打印

开始打算直接用原始的 window.print() 但很曲折,打印出来没有样式还会有各种各样的问题,然后直接放弃

1、首先 npm install vue-print-nb --save

2、然后在main.js 里面引入并且注册(

import Print from 'vue-print-nb'
Vue.use(Print)

3、在你想要打印的那个模块行内添加id=‘名字’

在这里插入图片描述

4、在你点击的按钮或者是图标上添加v-print

v-print="printObj"  // 'printObj'是下一个步骤里面起的名字

在这里插入图片描述

5、在data中添加一个’printObj’

data() {
    return {
       printObj: {
        id: "printer",       // 上面绑定的id名字
        popTitle: '标题名字',    // 需要显示的标题名字
        extraCss: 'https://www.google.com,https://www.google.com',
        extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>'
      },
    };
  },

这样打印的话就可以了(只要保证层级没问题,图片在打印预览的时候可以显示)

导出pdf

1、npm装两个包

第一个.将页面html转换成图片
npm install --save html2canvas 
第二个.将图片生成pdf
npm install jspdf --save

2、在你想导出的那个模块行内添加一个id=‘pinter’

在这里插入图片描述

3、在你点击的按钮或者是图标上添加一个点击事件(这个名字是下一个步骤的方法名)

 @click="downloadHtmlToPdf()"

在这里插入图片描述

4、在文件夹中新建一个文件取名downloadHtmlToPdf

在这里插入图片描述
然后在文件里面写入下面的内容注意里面的#printer是你绑定的id(上面第二步骤的id)


import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
    install(Vue, options) {
        Vue.prototype.downloadHtmlToPdf = function () {
            var title = this.htmlTitle
            html2Canvas(document.querySelector('#printer'), {    // 这个id很重要,一旦填写错了或者不填写就会报错
                allowTaint: true,
                useCORS: true
            }).then(function (canvas) {
                let contentWidth = canvas.width
                let contentHeight = canvas.height
                let pageHeight = contentWidth / 592.28 * 841.89
                let leftHeight = contentHeight
                let position = 0
                let imgWidth = 595.28
                let imgHeight = 592.28 / contentWidth * contentHeight
                let pageData = canvas.toDataURL('image/jpeg', 1.0)
                let PDF = new JsPDF('', 'pt', 'a4')
                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')
            }
            )
        }
    }
}

5、在main.js里面引入上面写的文件并且注册

import downloadHtmlToPdf from '@/util/downloadHtmlToPdf'
Vue.use(downloadHtmlToPdf)

在这里插入图片描述
这样就算页面中有img图片也可以导出

### Vue3 前端页面导出 PDF实现方法 在 Vue3 项目中实现前端页面导出PDF 功能,主要依赖于 `html2canvas` 和 `jsPDF` 这两个库。以下是详细的实现方式: #### 使用 html2canvas 和 jsPDF 库 通过 `html2canvas` 将 HTML 页面渲染成 Canvas 图片,再利用 `jsPDF` 将图片插入到 PDF 文档中并保存。 安装所需依赖: ```bash npm install html2canvas jspdf --save ``` 创建工具函数文件(如 `utils/exportPdf.js`): ```javascript import { jsPDF } from "jspdf"; import html2canvas from "html2canvas"; export function exportHtmlToPdf(elementId, filename = "document") { const element = document.getElementById(elementId); if (!element) throw new Error("Element not found"); html2canvas(element).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdfWidth = 210; // A4 width in mm const pdfHeight = (canvas.height * pdfWidth) / canvas.width; const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); doc.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); // 添加页码功能 let totalPages = Math.ceil(pdfHeight / 297); // 计算总页数 for (let i = 1; i <= totalPages; i++) { doc.setPage(i); doc.setFontSize(10); doc.setTextColor(150); doc.text(`第 ${i} 页`, 180, 285); // 设置页脚位置 } doc.save(`${filename}.pdf`); }); } ``` 调用此工具函数的方法如下: ```javascript <template> <div id="content"> <!-- 需要导出的内容 --> <h1>这是需要导出的页面</h1> <p>一些文字内容...</p> </div> <button @click="handleExport">导出 PDF</button> </template> <script> import { exportHtmlToPdf } from '@/utils/exportPdf'; export default { methods: { handleExport() { try { exportHtmlToPdf('content', 'example-document'); // 调用导出函数 } catch (error) { console.error(error.message); } } } }; </script> ``` 上述代码实现了将指定 DOM 元素导出PDF 文件的功能[^2]。同时支持自定义文件名以及简单的分页逻辑[^5]。 --- #### 后端返回二进制流的方式 如果后端提供了生成好的 PDF 数据,则可以直接将其下载至本地。具体实现如下: 接收后端响应的数据,并触发浏览器下载行为: ```javascript async function downloadPdfFromBackend(apiUrl) { try { const response = await fetch(apiUrl, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: localStorage.getItem('token') || '' } }); if (!response.ok) throw new Error('Failed to get the file'); const res = await response.arrayBuffer(); const blob = new Blob([new Uint8Array(res)], { type: 'application/pdf' }); // 创建 Blob 对象 const url = URL.createObjectURL(blob); // 创建临时链接地址 const a = document.createElement('a'); // 创建虚拟<a>标签 a.href = url; a.download = 'output.pdf'; // 下载后的文件名称 document.body.appendChild(a); a.click(); // 执行点击事件 URL.revokeObjectURL(url); // 清理内存中的对象URL document.body.removeChild(a); } catch (err) { console.error(err.message); } } // 在组件中调用 <button @click="downloadPdfFromBackend('/api/generate-pdf')">从后端获取并下载 PDF</button> ``` 这种方式适用于后端已经完成复杂业务处理的情况,例如动态生成报表等场景[^4]。 --- #### 自动分割页面与添加页码 对于复杂的多页布局需求,可以扩展分页逻辑。核心思路是对目标区域的高度进行量,并按需拆分为多个子区域分别绘制到不同页面上。 示例代码片段展示如何手动切分高度较大的内容: ```javascript function splitAndAddPages(doc, contentCanvas, pageHeightLimit) { const totalHeight = contentCanvas.height; const pagesCount = Math.ceil(totalHeight / pageHeightLimit); for (let pageIndex = 0; pageIndex < pagesCount; pageIndex++) { const startOffsetY = pageIndex * pageHeightLimit; const endOffsetY = Math.min((pageIndex + 1) * pageHeightLimit, totalHeight); const croppedCanvas = document.createElement('canvas'); const ctx = croppedCanvas.getContext('2d'); croppedCanvas.width = contentCanvas.width; croppedCanvas.height = endOffsetY - startOffsetY; ctx.drawImage(contentCanvas, 0, startOffsetY, contentCanvas.width, endOffsetY - startOffsetY, 0, 0, contentCanvas.width, endOffsetY - startOffsetY); const imageData = croppedCanvas.toDataURL('image/png'); doc.addImage(imageData, 'PNG', 0, 0, 210, pageHeightLimit); if (pageIndex !== pagesCount - 1) { doc.addPage(); // 新增一页 } } } ``` 以上代码能够有效解决大尺寸页面无法一次性完全显示的问题[^1]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值