vue3 html 转 pdf,实现点击按钮将指定区域转为pdf并下载

70 阅读2分钟

前言

最近有个需求,其中有一点:前端点击按钮将表单生成pdf并下载。前端后端都能做,如果后端去做的话还需要占用资源去保存pdf模板,而且关键的是我们内部文件系统还会定时清除文件,到时候还得隔一段时间去更新模板,考虑到这些,我决定还是在前端实现。以下是我实现的一个demo。

借助 html2pdf.js

安装
npm i html2pdf.js
使用

以下是 js 部分

import html2pdf from 'html2pdf.js'

const exportToPdf = async () => {
  const element = document.getElementById('content-to-export')
  const opt = {
    margin: 1,
    filename: 'myfile.pdf',
    image: { type: 'jpeg', quality: 0.98 },
    html2canvas: { scale: 2, useCORS: true },
    jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
  }
  
  try {
    await html2pdf().set(opt).from(element).save()
  } catch (error) {
    console.error('生成PDF时出错:', error)
  }
}

以下是 html 部分

<div id="content-to-export">
  <h1>PDF导出测试</h1>
  <div class="container">
    <div class="table-header">
      <h2>员工信息表</h2>
    </div>

    <div class="table-container">
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>部门</th>
            <th>职位</th>
            <th>入职日期</th>
            <th>状态</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1001</td>
            <td>张三</td>
            <td>技术部</td>
            <td>前端工程师</td>
            <td>2020-03-15</td>
            <td><span class="status active">活跃</span></td>
          </tr>
          <tr>
            <td>1002</td>
            <td>李四</td>
            <td>市场部</td>
            <td>市场经理</td>
            <td>2019-05-20</td>
            <td><span class="status active">活跃</span></td>
          </tr>
          <tr>
            <td>1003</td>
            <td>王五</td>
            <td>财务部</td>
            <td>财务分析师</td>
            <td>2021-01-10</td>
            <td><span class="status active">活跃</span></td>
          </tr>
          <tr>
            <td>1004</td>
            <td>赵六</td>
            <td>人力资源</td>
            <td>招聘专员</td>
            <td>2018-11-05</td>
            <td><span class="status pending">待审核</span></td>
          </tr>
          <tr>
            <td>1005</td>
            <td>钱七</td>
            <td>技术部</td>
            <td>后端工程师</td>
            <td>2022-02-28</td>
            <td><span class="status active">活跃</span></td>
          </tr>
          <tr>
            <td>1006</td>
            <td>孙八</td>
            <td>产品部</td>
            <td>产品经理</td>
            <td>2019-08-12</td>
            <td><span class="status inactive">未活跃</span></td>
          </tr>
          <tr>
            <td>1007</td>
            <td>周九</td>
            <td>销售部</td>
            <td>销售代表</td>
            <td>2020-07-22</td>
            <td><span class="status active">活跃</span></td>
          </tr>
          <tr>
            <td>1008</td>
            <td>吴十</td>
            <td>客户支持</td>
            <td>支持专员</td>
            <td>2021-09-30</td>
            <td><span class="status active">活跃</span></td>
          </tr>
        </tbody>
      </table>
    </div>
    
    <div class="footer">
        显示 8 条记录
    </div>
  </div>
</div>
<button @click="exportToPdf">导出为PDF</button>

以下 css 代码

<style scoped lang="less">
.table-header {
  padding: 20px;
  background: #4e73df;
  color: white;
}

.table-header h2 {
  font-weight: 500;
}

.table-container {
  overflow-x: auto;
}

.footer {
  text-align: center;
  margin-top: 10px;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th, td {
  padding: 16px 20px;
  text-align: left;
  border-bottom: 1px solid #e0e0e0;
}

th {
  background-color: #f8f9fc;
  color: #4e73df;
  font-weight: 600;
  position: sticky;
  top: 0;
}
</style>

效果如下

下载后的pdf如下