前端将页面保存为PDF

html页面保存为PDF

  1. 准备插件

    html2canvas  // 保证html清晰的转为图片数据
    jsPDF // 将图片数据转为PDF
    
  2. 代码

import React, { useRef, useState } from 'react';
import { Button } from 'antd';
import { Image as AntImage } from 'antd';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import img1 from '../../img/1.png'

const ScreenShot = () => {
    // 目标元素
    const targetRef = useRef(null)
    // 找到当然dom的区域,生成图片的数据
    const createCanvas = () => {
        return new Promise((resolve) => {
            html2canvas(targetRef.current).
                then(function (canvas) {
                    resolve(canvas)
                })
        })
    }
    // 下载图片
    const createImg = async () => {
        const canvas = await createCanvas()
        const imageUrl = canvas.toDataURL("image/png"); // 可配置图片类型
        const file = document.createElement("a");
        file.style.display = "none";
        file.href = imageUrl;
        file.download = decodeURI('图');// 可配置下载图片名称
        file.click();
    }
	// 下载PDF(单页)
    const createPDF = async () => {
        const canvas = await createCanvas()
        const imageUrl = canvas.toDataURL("image/png"); // 可配置图片类型
        const pdf = new jsPDF('p', 'mm', 'a4'); // 创建一个新的PDF文档,页面格式为A4,纵向
        const MARGIN = 15;// 控制PDF内容在首页的间距
        const imgWidth = 180; // 图片在PDF中的宽度,单位mm
        const imgHeight = (canvas.height / canvas.width) * imgWidth; // 根据原始宽高比计算图片在PDF中的高度
        // pdf.addImage(图片素材, 格式, 距离左侧间距, 距离顶部侧间距(为负数则可制作多页面,但要简单计算), pdf内容宽度, pdf内容高度);
        pdf.addImage(imageUrl, 'PNG', MARGIN, MARGIN, imgWidth, imgHeight); // 将图片添加到PDF中,并指定位置和大小(单位mm),左上角坐标(15, 15)
        pdf.save('one.pdf'); // 可配置下载PDF名称
    }
	// 下载PDF(可多页)
    const createPDFS = async () => {
        const canvas = await createCanvas()
        const imageUrl = canvas.toDataURL("image/png"); // 可配置图片类型

        const MARGIN = 15;// 控制PDF内容在首页的间距

        const pdf = new jsPDF('p', 'mm', 'a4'); // 创建一个新的PDF文档,页面格式为A4,纵向
        const pdfPageHeight = pdf.internal.pageSize.height; // 一页PDF文档的高度

        const imgWidth = 180; // 图片在PDF中的宽度(可视),单位mm  pdf真实宽度为210,但是现实区域应该-15-15的间距,大致估摸为180
        const imgHeight = (canvas.height / canvas.width) * imgWidth; // 根据图片素材的原始宽高比计算图片在PDF中的高度(图片完整大小)

        // 可能存在一页PDF放不下,所以要分页
        let page = 1
        let x = MARGIN
        let y = MARGIN
        // 制作首页PDF

        pdf.addImage(imageUrl, 'PNG', x, y, imgWidth, imgHeight);
        // 如果大于一页,则分页打印
        while (imgHeight > pdfPageHeight * page) {
            // 新增一页
            pdf.addPage();
            // x 值越大,左侧间距越大,显示图片越向右移动
            // y 值越大,顶部间距越大,显示图片越向下移动,但如果值是负数,显示图片反向移动(向上移动)
            // 比如:图片可占3页,第一页可正常显示,第二页则显示图片的中部,第三页则显示图片的底部
            // 第二页,则必须计算出显示图片中部的坐标(图片应该向上移动,应该为负值,刚好负上一页显示的区域大小,但是要保证有一个间距的值)
            // 第三页,同理,只是要负上两页的区域大小
            y = -pdfPageHeight * page + MARGIN
            pdf.addImage(imageUrl, 'PNG', x, y, imgWidth, imgHeight);
            page++
        }
        // 保存PDF
        pdf.save('more.pdf');
    }
	// 将图片插入网页
    const [imageUrl, setImgUrl] = useState('')
    const insertPage = async () => {
        const canvas = await createCanvas()
        const imageUrl = canvas.toDataURL("image/png"); // 可配置图片类型
        // imageRef.current.src = imageUrl;
        setImgUrl(imageUrl)
    }
    return (
        <div>
            <Button type="primary" onClick={createImg}>生成jpg</Button>
            <Button type="primary" onClick={createPDF}>生成PDF(一页)</Button>
            <Button type="primary" onClick={createPDFS}>生成PDF(多页)</Button>
            <Button type="primary" onClick={insertPage}>插入页面</Button>
            <div ref={targetRef}>
                <img src={img1} />
                <img src={img1} />
                <img src={img1} />
                <img src={img1} />
                <img src={img1} />
                <img src={img1} />
            </div>
            <AntImage width={200} src={imageUrl} />
        </div>
    );
};
export default ScreenShot;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值