vue项目中将html转为pdf并下载

个人项目地址: SubTopH前端开发个人站

(自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面)

SubTopH前端开发个人站icon-default.png?t=N7T8https://subtop.gitee.io/subtoph.github.io/#/home

以上 ? 是个人前端项目,欢迎提出您的建议?

以下是正文内容...............

首先安装所需要的依赖

yarn add html2canvas
yarn add jspdf

下面是一个简单的案例,导出A4尺寸pdf

html代码

<template>
  <div class="biographical-notes-page">
    <p class="daochu" @click="getPdf">导出</p>
    <div class="biographical-notes" id="resultsHuiZongTableId">
      <div class="my-info">
        <div class="photo-box">
          <img src=" />
        </div>
        <div class="info-text">
          <p>
            <span>姓名:xxx</span>
          </p>
          <p>
            <span>年龄:xx</span>
          </p>
          <p>
            <span>电话:xxxxxxx</span>
          </p>
          <p>
            <span>邮箱:xxxxxxx@163.com</span>
          </p>
          <p>
            <span>工作经验:x年</span>
          </p>
          <p>
            <span>学历学位:本科</span>
          </p>
        </div>
      </div>
    </div>
    <!-- 加载动画 -->
    <div class="loading" v-if="loading">
      <p>PDF文件生成中...</p>
    </div>
  </div>
</template>

javaScript代码,重点是dpi设置控制pdf分辨率

<script>
import { reactive, toRefs, onBeforeMount, onMounted } from 'vue';
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
export default {
  name: '',
  setup() {
    const data = reactive({
      loading: false
    });
    onBeforeMount(() => {});
    onMounted(() => {});
    const [PDF_WIDTH, PDF_HEIGHT] = [595.28, 841.89];
    const getPdf = () => {
      const ele = document.querySelector('#resultsHuiZongTableId');
      downloadPdf(ele, 'A4.pdf');
    };
    const downloadPdf = (element, filename, options) => {
      if (!element) return;
      let marginX = (options && (options.marginX || options.margin)) || 0;
      let marginY = (options && (options.marginY || options.margin)) || 0;
      data.loading = true;
      return html2Canvas(element, {
        allowTaint: true,
        useCORS: true,
        dpi: 300, // 设置截图的分辨率
        scale: 300 / 96 // 设置截图缩放比例,以适应pdf的dpi
      }).then((canvas) => {
      
        let [contentWidth, contentHeight] = [canvas.width, canvas.height];
        let [realPdfWidth, realPdfHeight] = [
          PDF_WIDTH - marginX * 2,
          PDF_HEIGHT - marginY * 2
        ];

        let singlePageContentHeight = Math.ceil(
          (contentWidth / realPdfWidth) * realPdfHeight
        );
        let pageCount = Math.ceil(contentHeight / singlePageContentHeight);

        let pdf = new JsPDF({
          orientation: 'p',
          unit: 'px',
          format: [PDF_WIDTH, PDF_HEIGHT],
          compress: true
        });

        if (pageCount < 2) {
          pdf.addImage(
            canvas.toDataURL(),
            'JPEG',
            marginX,
            marginY,
            realPdfWidth,
            realPdfHeight
          );
        } else {
          for (let i = 0; i < pageCount; i++) {
            if (i > 0) {
              pdf.addPage();
            }

            let singlePageImgData = canvas
              .getContext('2d')
              .getImageData(
                0,
                i * singlePageContentHeight,
                contentWidth,
                singlePageContentHeight
              );

            let tempCanvas = document.createElement('canvas');
            tempCanvas.width = contentWidth;
            tempCanvas.height = singlePageContentHeight;
            tempCanvas.getContext('2d').putImageData(singlePageImgData, 0, 0);

            pdf.addImage(
              tempCanvas.toDataURL(),
              'JPEG',
              marginX,
              marginY,
              realPdfWidth,
              realPdfHeight
            );
          }
        }
        data.loading = false;
        let res = pdf.save(filename);
        console.log(res)
        return res;
      });
    };

    return {
      getPdf,
      ...toRefs(data)
    };
  }
};
</script>

css代码

<style scoped lang="less">
.daochu {
  position: absolute;
  top: 100px;
  left: 0px;
  color: #fff;
  cursor: pointer;
}
.loading{
  position: absolute;
  top:0;
  left:0;
  width:100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.456);
  p{
    line-height: 800px;
    text-align: center;
    color:#fff;
    font-weight: 700;
  }
}
.biographical-notes-page {
  position: relative;
  width: 100%;
  height: 100%;
  background: #000;
  overflow: auto;
  padding: 20px 0;
  box-sizing: border-box;
  color: #000;
  .biographical-notes {
    // font-family: '苹方';
    width: 1190px;
    min-height: 1682px;
    margin: 0px auto;
    background: #fff;
    padding: 20px 40px;
    box-sizing: border-box;
    .my-info {
      overflow: hidden;
      .photo-box {
        float: left;
        width: 200px;
        height: 260px;
        background: @TSB;
        img{
          width: 100%;
        }
      }
      .info-text {
        padding: 20px 40px;
        float: left;
        p {
          line-height: 36px;
        }
      }
    }
    .info-title {
      color: @TSB;
      font-size: 22px;
      margin-top: 30px;
    }
    .info-content {
      margin-top: 10px;
      span {
        font-size: 16px;
        line-height: 32px;
        display: block;
        color: #777;
      }
    }
  }
}

简单的转pdf案例,可根据实际业务场景进行扩展