实现点击按钮导出页面pdf

发布于:2024-07-05 ⋅ 阅读:(15) ⋅ 点赞:(0)

在Vue 3 + Vite项目中,你可以使用html2canvasjspdf库来实现将页面某部分导出为PDF文档的功能。以下是一个简单的实现方式:

1.安装html2canvasjspdf

pnpm install html2canvas jspdf

2.在Vue组件中使用这些库来实现导出功能:

<template>
  <div>
    <button @click="exportToPDF">导出PDF</button>
    <div ref="pdfContent" class="pdf-content">
      <!-- 这里是你想要导出的页面部分 -->
    </div>
  </div>
</template>
 
<script lang="ts">
import { defineComponent, ref } from 'vue';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
 
export default defineComponent({
  setup() {
    const pdfContent = ref<HTMLElement | null>(null);
 
    const exportToPDF = async () => {
      if (pdfContent.value) {
        const canvas = await html2canvas(pdfContent.value);
        const imgData = canvas.toDataURL('image/png');
        const doc = new jsPDF({
          orientation: 'portrait',
          unit: 'px',
          format: 'a4',
        });
        const imgProps = doc.getImageProperties(imgData);
        const pdfWidth = doc.internal.pageSize.getWidth();
        const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
        doc.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
        doc.save('exported.pdf');
      }
    };
 
    return {
      pdfContent,
      exportToPDF,
    };
  },
});
</script>
 
<style>
.pdf-content {
  /* 样式按需定制 */
}
</style>

最后点击导出按钮,即可成功按设置导出你想要导出的部分内容到pdf文档了,如下所以,打开pdf即可:

封装方法htmlToPdf.ts

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
// title:下载文件的名称  htmlId:包裹的标签的id
const htmlToPdf = (title: string, htmlId: string) => {
  var element = document.querySelector(htmlId) as HTMLElement
  window.pageYOffset = 0
  document.documentElement.scrollTop = 0
  document.body.scrollTop = 0
  setTimeout(() => {
    // // 以下注释的是增加导出的pdf水印 !!!!!!!!!!!!!
    // const value = '我是水印'
    // //创建一个画布
    // let can = document.createElement('canvas')
    // //设置画布的长宽
    // can.width = 400
    // can.height = 500

    // let cans = can.getContext('2d') as any
    // //旋转角度
    // cans.rotate((-15 * Math.PI) / 180)
    // cans.font = '18px Vedana'
    // //设置填充绘画的颜色、渐变或者模式
    // cans.fillStyle = 'rgba(200, 200, 200, 0.40)'
    // //设置文本内容的当前对齐方式
    // cans.textAlign = 'left'
    // //设置在绘制文本时使用的当前文本基线
    // cans.textBaseline = 'Middle'
    // //在画布上绘制填色的文本(输出的文本,开始绘制文本的X坐标位置,开始绘制文本的Y坐标位置)
    // cans.fillText(value, can.width / 8, can.height / 2)
    // let div = document.createElement('div')
    // div.style.pointerEvents = 'none'
    // div.style.top = '20px'
    // div.style.left = '-20px'
    // div.style.position = 'fixed'
    // div.style.zIndex = '100000'
    // div.style.width = element.scrollHeight + 'px'
    // div.style.height = element.scrollHeight + 'px'
    // div.style.background =
    //   'url(' + can.toDataURL('image/png') + ') left top repeat'
    // element.appendChild(div) // 到页面中

    html2Canvas(element, {
      allowTaint: true,
      useCORS: true,
      scale: 2, // 提升画面质量,但是会增加文件大小
      height: element.scrollHeight, // 需要注意,element的 高度 宽度一定要在这里定义一下,不然会存在只下载了当前你能看到的页面   避雷避雷!!!
      windowHeight: element.scrollHeight,
    }).then(function (canvas) {
      var contentWidth = 1948
      var contentHeight = canvas.height*1948 / canvas.width
      // console.log('contentWidth', contentWidth)
      // console.log('contentHeight', contentHeight)
      // 一页pdf显示html页面生成的canvas高度;
      var pageHeight = (contentWidth * 841.89) / 592.28
      // 未生成pdf的html页面高度
      var leftHeight = contentHeight

      // console.log('pageHeight', pageHeight)
      // console.log('leftHeight', leftHeight)
      // 页面偏移
      var position = 0
      // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高  //40是左右页边距
      var imgWidth = 595.28-60
      var imgHeight = (592.28 / contentWidth) * contentHeight

      var pageData = canvas.toDataURL('image/jpeg', 1.0)

      var pdf = new JsPDF('portrait', 'px', 'a4')

      // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
      // 当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < pageHeight) {
        // console.log('没超过1页')
        pdf.addImage(pageData, 'JPEG', 2, 2, imgWidth, imgHeight)
        // pdf.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight)
      } else {
        while (leftHeight > 0) {
          // console.log('超过1页')
          pdf.addImage(pageData, 'JPEG', 5, position, imgWidth, imgHeight)
          leftHeight -= pageHeight
          position -= 841.89
          // 避免添加空白页
          if (leftHeight > 0) {
            pdf.addPage()
          }
        }
      }
      pdf.save(title + '.pdf')
    })
  }, 1000)
}

export default htmlToPdf