Vue项目将页面导出为pdf格式文件

Vue项目将页面导出为pdf格式文件
  1. 安装依赖
npm install html2canvas --save
npm install jspdf --save
  1. 封装工具

在utils中新建文件pdf.js, 内容如下

import html2canvas from "html2canvas";
import jsPDF from "jspdf";

export const downloadPDF = page => {
  html2canvas(page).then(function(canvas) {
    canvas2PDF(canvas);
  });
};

const canvas2PDF = canvas => {
  let contentWidth = canvas.width;
  let contentHeight = canvas.height;
  let imgHeight = contentHeight;
  let imgWidth = contentWidth;
  let pdf = new jsPDF("l", "px", [contentWidth, contentHeight]);

  pdf.addImage(
    canvas.toDataURL("image/jpeg", 1.0),
    "JPEG",
    0,
    0,
    imgWidth,
    imgHeight
  );
  //导出文件的名字,可以自定义
  pdf.save("运行图.pdf");
};

new jspdf()参数说明
第一个参数 l:横向 p:纵向
第二个参数 测量单位(“pt”,“mm”, “cm”, “m”, “in” or “px”)
第三个参数 可选默认为“a4”,如果自定义指定大小这样 [100, 600]

  1. 完整测试代码
<template>
   <div id="demo">
      <p> <el-button type="primary" @click="loadPdf">导出</el-button> </p>
      <el-table :data="tableData" style="width: 100%">
         <el-table-column prop="date" label="日期" width="180">
         </el-table-column>
         <el-table-column prop="name" label="姓名" width="180">
         </el-table-column>
         <el-table-column prop="address" label="地址">
         </el-table-column>
      </el-table>

   </div>
</template>

<script>
import { downloadPDF } from '@/utils/pdf.js'
export default {
   data() {
      return {
         tableData: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
         }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
         }, {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
         }, {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
         }]
      };
   },

   methods: {
      loadPdf() {
         downloadPDF(document.getElementById('demo'))
      }
   }
}
</script>
<style lang='css' scoped></style>

4.页面和最后的pdf

  • 页面图片
    在这里插入图片描述

  • pdf
    在这里插入图片描述

### 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]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值