当前位置: 首页 > news >正文

vue项目使用html2canvas和jspdf将页面导出成PDF文件

一、需求:

页面上某一部分内容需要生成pdf并下载

二、技术方案:

使用html2canvas和jsPDF插件
 

三、js代码

// 页面导出为pdf格式
import html2Canvas from "html2canvas";
import jsPDF from "jspdf";
import { uploadImg } from '@/api/public';

const htmlToPdf = {
    getPdf(title, id) {
        html2Canvas(document.querySelector(id), {
            allowTaint: false,
            taintTest: false,
            logging: false,
            useCORS: true,
            dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
            scale: 4, //按比例增加分辨率
        }).then((canvas) => {
            var pdf = new jsPDF("p", "mm", "a4"); //A4纸,纵向
            var ctx = canvas.getContext("2d"),
                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");
                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;
            }

            console.log(pdf)
            // pdf.save(title + ".pdf"); // PDF.save() 此方法可以将pdf直接保存本地
            let pdfData = pdf.output('datauristring') // 获取base64Pdf
            let files = dataURLtoFile(pdfData, '封面.pdf') // 将base64文件转化为流,上传oss
            uploadFiles(files)
        });
    },
};

function dataURLtoFile(dataurl, filename) {
    let arr = dataurl.split(',')
    let mime = arr[0].match(/:(.*?);/)[1]
    let bstr = atob(arr[1])
    let n = bstr.length
    let u8arr = new Uint8Array(n)
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    return new File([u8arr], filename, { type: mime })
}

function uploadFiles(files) {
    let data = new FormData()
    data.append('file', files)
    uploadImg(data).then(res => {
        console.log(res)
        if (res.data.code == 0) {
            // formData.value.qrcode = res.data.data.res.url
        }
    })
}

export default htmlToPdf;

四、使用步骤:

1. 使用之前需要先按照2个npm包

npm install html2canvas -S --registry=https://registry.npmmirror.com/
npm install jspdf -S --registry=https://registry.npmmirror.com/

2. 在页面引用

import htmlToPdf from "@/utils/htmlToPDF";

3. 调用方法

const printReport = () => {
    htmlToPdf.getPdf('测试pdf',"#db-test-report");
}

4. 记得给指定容器加id

五:注意事项:

1. 如果要打印的内容是iframe里面的,因为无法直接拿到dom元素,需要跟iframe通讯,拿到dom元素,放到当前页面;如果样式没带过来,特殊处理一下

const iframe = document.getElementById("myIframe");
// 向iframe发送消息
iframe.contentWindow.postMessage("getElement", tooltipUrl.value);


// 收到iframe的回复才能生成pdf
window.addEventListener("message", function (e) {
  console.log("iframe回复的消息");
  console.log(e);
  if (e.origin === iframeOrigin.value && e.data.type === "element") {
    // 处理获取到的元素
    var container = document.getElementById("pdf-iframe");
    container.innerHTML = e.data.html;
    hasIframePdf = true
    getPdf("xxx下载", "#pdf-xxx-xxx");
  }
});

相关文章:

  • springboot新增调度任务
  • 当当平台商品详情接口设计与调用指南
  • PostgreSQL 的 COPY 命令
  • 算法思想之位运算(一)
  • Model Context Protocol (MCP) 模型上下文协议
  • U盘引导盘制作Rufus v4.7.2231
  • 第十六届蓝桥杯 省赛C/C++ 大学B组
  • 大模型开发:源码分析 Qwen 2.5-VL 视频抽帧模块(附加FFmpeg 性能对比测试)
  • 软考day03
  • THM Billing
  • Win10 开机自动开启手动代理 “手动设置代理”,如何关闭 “使用代理服务器” 如何开机时保持关闭VPN
  • C++初阶-inline的使用
  • Linux xorg-server 解析(一)- 编译安装Debug版本的xorg-server
  • Java基础知识
  • SQL 语句基础(增删改查)
  • 电流互感器的两相星形接线的建模与仿真
  • 撰写学位论文Word图表目录的自动生成
  • 基于单片机的病房呼叫系统设计
  • 【MCAL】AUTOSAR架构下基于SPI通信的驱动模块详解-以TJA1145为例
  • [网鼎杯 2022 青龙组]fakeshell
  • 网站跳转到另外一个网站怎么做/好网站制作公司
  • 动态网站开发是什么/青岛seo推广专员
  • 青岛品牌网站制作/厦门网站建设
  • 找建网站公司/关键词排名查询工具有哪些
  • 永康网站建设/游戏推广员上班靠谱吗
  • 郑州做网站茂睿科技/河北百度竞价优化