当前位置:首页 > VUE

vue 实现导出pdf

2026-01-08 08:40:03VUE

使用 html2canvas 和 jsPDF 实现导出 PDF

在 Vue 项目中安装 html2canvas 和 jsPDF 依赖:

npm install html2canvas jspdf

创建一个方法将指定 DOM 元素转换为 PDF:

import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'

export default {
  methods: {
    exportToPDF() {
      const element = document.getElementById('pdf-content')
      html2canvas(element).then(canvas => {
        const imgData = canvas.toDataURL('image/png')
        const pdf = new jsPDF('p', 'mm', 'a4')
        const imgWidth = 210
        const pageHeight = 295
        const imgHeight = canvas.height * imgWidth / canvas.width
        let heightLeft = imgHeight
        let position = 0

        pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight)
        heightLeft -= pageHeight

        while (heightLeft >= 0) {
          position = heightLeft - imgHeight
          pdf.addPage()
          pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight)
          heightLeft -= pageHeight
        }

        pdf.save('export.pdf')
      })
    }
  }
}

使用 vue-html2pdf 插件

安装 vue-html2pdf 插件:

npm install vue-html2pdf

在组件中使用:

import VueHtml2pdf from 'vue-html2pdf'

export default {
  components: {
    VueHtml2pdf
  },
  methods: {
    generateReport() {
      this.$refs.html2Pdf.generatePdf()
    }
  }
}

模板部分:

<template>
  <div>
    <button @click="generateReport">导出PDF</button>
    <vue-html2pdf
      ref="html2Pdf"
      :filename="'report.pdf'"
      :paginate-elements-by-height="1400"
      :pdf-quality="2"
      :manual-pagination="false"
      pdf-format="a4"
      pdf-orientation="portrait"
    >
      <section slot="pdf-content">
        <!-- 这里放要导出的内容 -->
        <div id="pdf-content">...</div>
      </section>
    </vue-html2pdf>
  </div>
</template>

使用 PDFMake 库实现

安装 pdfmake 依赖:

npm install pdfmake

创建 PDF 内容:

import pdfMake from 'pdfmake/build/pdfmake'
import pdfFonts from 'pdfmake/build/vfs_fonts'
pdfMake.vfs = pdfFonts.pdfMake.vfs

export default {
  methods: {
    exportPDF() {
      const docDefinition = {
        content: [
          { text: 'PDF标题', style: 'header' },
          '这里是PDF内容...',
          { text: '表格示例', style: 'subheader' },
          {
            table: {
              body: [
                ['列1', '列2', '列3'],
                ['值1', '值2', '值3']
              ]
            }
          }
        ],
        styles: {
          header: { fontSize: 18, bold: true },
          subheader: { fontSize: 15, bold: true }
        }
      }
      pdfMake.createPdf(docDefinition).download('document.pdf')
    }
  }
}

使用浏览器打印功能

通过 CSS 媒体查询优化打印样式:

@media print {
  body * {
    visibility: hidden;
  }
  #print-area, #print-area * {
    visibility: visible;
  }
  #print-area {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
  }
}

调用浏览器打印 API:

export default {
  methods: {
    printPDF() {
      window.print()
    }
  }
}

注意事项

确保导出的内容在 DOM 中完全渲染后再执行导出操作,可以在 nextTick 中调用导出方法:

this.$nextTick(() => {
  this.exportToPDF()
})

对于复杂布局,可能需要调整 html2canvas 的配置参数:

html2canvas(element, {
  scale: 2,  // 提高分辨率
  logging: false,
  useCORS: true,
  allowTaint: true
})

中文显示问题可以通过引入中文字体解决,在 jsPDF 中:

const pdf = new jsPDF({
  orientation: 'p',
  unit: 'mm',
  format: 'a4',
  hotfixes: ['px_scaling']
})
pdf.addFont('simhei.ttf', 'simhei', 'normal')
pdf.setFont('simhei')

vue 实现导出pdf

标签: vuepdf
分享给朋友:

相关文章

vue实现搜索

vue实现搜索

Vue 实现搜索功能 在 Vue 中实现搜索功能通常涉及数据绑定、事件监听和过滤逻辑。以下是几种常见的实现方式: 使用计算属性过滤列表 <template> <div>…

vue实现下拉菜单

vue实现下拉菜单

实现下拉菜单的基本思路 使用Vue实现下拉菜单可以通过动态绑定v-show或v-if控制菜单显示隐藏,结合事件监听(如@click或@mouseenter)触发状态切换。以下是两种常见实现方式:…

vue实现分支

vue实现分支

Vue 实现分支的方法 在 Vue 项目中实现分支功能通常涉及条件渲染、动态组件或路由控制。以下是几种常见的实现方式: 条件渲染(v-if/v-show) 使用 Vue 的指令根据条件显示不同内容…

vue实现静态查询

vue实现静态查询

Vue 实现静态查询 在 Vue 中实现静态查询通常指不依赖后端接口,直接在前端处理数据筛选或搜索功能。以下是几种常见实现方式: 使用计算属性过滤数据 通过计算属性对静态数据进行筛选,适合简单查询…

vue实现年历

vue实现年历

Vue 实现年历的方法 使用 Vue 实现年历可以通过组件化开发方式,结合日期计算和动态渲染完成。以下是两种常见的实现方式: 基于原生 Vue 的日历组件 创建 Calendar.vue 组件文件…

vue实现多级弹窗

vue实现多级弹窗

Vue 多级弹窗实现方法 方法一:使用动态组件与递归组件 在 Vue 中可以通过动态组件配合递归组件实现多级弹窗。定义一个基础弹窗组件,通过递归调用自身实现层级嵌套。 基础弹窗组件模板示例: &…