vue实现打印PDF文档

npm i jspdf@3.0.1 html2canvas@1.4.1

/utils/htmlToPDF.ts

复制代码
// 页面导出为pdf格式
import html2Canvas from "html2canvas";
import jsPDF from "jspdf";

const htmlToPdf = (title: any, id: any) => {
  html2Canvas(document.querySelector(id), {
    allowTaint: false,
    taintTest: false,
    logging: false,
    useCORS: true,
    dpi: window.devicePixelRatio * 3, //将分辨率提高到特定的DPI 提高四倍
    scale: 3, //按比例增加分辨率
  } as any).then((canvas) => {
    var pdf = new jsPDF("p", "mm", "a4"); //A4纸,纵向
    var ctx = canvas.getContext("2d") as any,
      a4w = 190,
      a4h = 272, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
      imgHeight = Math.floor((a4h * canvas.width) / a4w), //按A4显示比例换算一页图像的像素高度
      renderedHeight = 0;

    while (renderedHeight < canvas.height) {
      var page = document.createElement("canvas") as any;
      page.width = canvas.width;
      page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页

      //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
      page
        .getContext("2d")
        .putImageData(
          ctx.getImageData(
            0,
            renderedHeight,
            canvas.width,
            Math.min(imgHeight, canvas.height - renderedHeight)
          ),
          0,
          0
        );
      pdf.addImage(
        page.toDataURL("image/jpeg", 1.0),
        "JPEG",
        10,
        10,
        a4w,
        Math.min(a4h, (a4w * page.height) / page.width)
      ); //添加图像到页面,保留10mm边距

      renderedHeight += imgHeight;
      if (renderedHeight < canvas.height) {
        pdf.addPage(); //如果后面还有内容,添加一个空页
      }
      // delete page;
    }
    pdf.save(title + ".pdf");
  });
};

export default htmlToPdf;

定义打印PDF模板

复制代码
<template>
    <div class="print-container" id="PdfContainer" style="width:800px;height: 800px;">
        123456789
        <div class="btn-print">
            <el-button type="success" @click="onDownload()">打印PDF</el-button>
        </div>
    </div>
</template>
<script lang='ts'>
import { reactive, getCurrentInstance, toRefs, onMounted, nextTick, defineComponent, computed } from 'vue';
import htmlToPdf from "/@/utils/htmlToPDF";
export default defineComponent({
    setup(props: any, { emit }: any) {
        onMounted(() => {
            nextTick(() => {
            });
        });
        const { proxy } = getCurrentInstance() as any;
        const data = reactive({});

        const onDownload = () => {
            htmlToPdf("合同信息", "#PdfContainer");
        };

        return {
            ...toRefs(data), onDownload,
        }
    }
})
</script>
<style scoped lang='scss'>
.print-container {
    position: relative;
    display: flex;
    justify-content: center;
    padding: 30px;
    margin: 0 auto;
    margin-top: 20px;
    width: 850px;
    background-color: #fff;


    &:hover {
        box-shadow: 2px 0px 3px 3px #ddd;
    }

    .btn-print {
        position: absolute;
        right: -100px;
        top: 0px;
    }
}
</style>

效果图

相关推荐
默_笙16 小时前
🚦 请三个 AI 考官给 RAG 打分:量化评估实战(下)
前端·javascript
阿坨16 小时前
灵感闪存卡:一款 Tampermonkey用户脚本
javascript·tampermonkey
朝朝辞暮i18 小时前
C++ 第 25 课:getter / setter + this
java·javascript·c++
蜗牛互联网18 小时前
Python接入Gemini 3.8 Flash实现票据视觉抽取与规则校验
java·javascript·网络·人工智能·python
易朵朵19 小时前
CSS 格式化上下文
css·vue.js
xieter19 小时前
【技术精选】深入浅出现代前端渲染与性能优化实践指南 (2026-10-04)
前端·javascript
xieter19 小时前
【硬核实战】TypeScript Compiler API: Preserving Child Node Narrowing in Reusable Type Guards 🔧 (2026-10-03)
前端·javascript
xieter19 小时前
【硬核实战】React 19 useFormStatus Returning False? I Built a SubmitButton That Fixes It (2026-10-03)
前端·javascript
雪芽蓝域zzs21 小时前
第6节:远程搜索弹窗(remote 模式),弹窗滚动加载分页
vue.js·elementui
paopaokaka_luck21 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis