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

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

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

SubTopH前端开发个人站https://subtop.gitee.io/subtoph.github.io/#/home

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

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

首先安装所需要的依赖

复制代码
yarn add html2canvas
yarn add jspdf

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

html代码

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分辨率

javascript 复制代码
<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代码

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案例,可根据实际业务场景进行扩展

相关推荐
markyankee1011 小时前
Vue.js 入门指南:从零开始构建你的第一个应用
vue.js
zhanshuo2 小时前
不依赖框架,如何用 JS 实现一个完整的前端路由系统
前端·javascript·html
火柴盒zhang2 小时前
websheet在线电子表格(spreadsheet)在集团型企业财务报表中的应用
前端·html·报表·合并·spreadsheet·websheet·集团财务
khalil2 小时前
基于 Vue3实现一款简历生成工具
前端·vue.js
一头生产的驴4 小时前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
孤水寒月8 小时前
基于HTML的悬窗可拖动记事本
前端·css·html
祝余呀8 小时前
html初学者第一天
前端·html
速易达网络11 小时前
RuoYi、Vue CLI 和 uni-app 结合构建跨端全家桶方案
javascript·vue.js·低代码
lyj16899712 小时前
vue-i18n+vscode+vue 多语言使用
前端·vue.js·vscode
我在北京coding15 小时前
TypeError: Cannot read properties of undefined (reading ‘queryComponents‘)
前端·javascript·vue.js