React jsPdf+html2canvas 前端生成pdf(分页截断 + 图片质量)

本文介绍了使用React、jsPdf和html2canvas在前端生成PDF的解决方案,包括如何处理分页截断和图片质量。作者通过封装组件实现了一个可复用的PDF生成组件,支持传入页眉、内容和页脚。虽然存在内容超页会被截断的问题,但能满足基本的定制需求,如导出表格和文档。
摘要由CSDN通过智能技术生成

前言

记录一下最近实现的前端生成pdf的功能,以及遇到的坑和解决方式
由于笔者1年多没碰过react了,之前也比较少使用hooks,实现这个功能也是想复习一下之前的知识,如果有什么写得不好的请指出交流。

正文

安装lib

npm install -S jspdf html2canvas

jspdf+html2canvas, 基本的实现逻辑使用html2canvas将html放入canvas,然后将canvas转成base64的图片,再用jspdf.addImage()将图片放入pdf。
我们的目标实现是将这个功能封装成一个可复用的component,后续使用只需要传入header,content,footer, 就可以生成一份带有页眉页尾的pdf。

index.js
import React, { Component, useState, useMemo, useRef, useEffect } from 'react';
import PdfComponent from '@/components/PdfComponent';
import img from '@/asset/img/三姐妹泉中的西印度海牛,佛罗里达州克里斯特尔里弗国家野生动物保护区.jpg'
import logo from '@/asset/logo/dog.jpg'
import './index.css';
import moment from 'moment';
import mockData from './mockData';


function HeaderComponent(props) {
    return <div style={
  { padding: '10px 0' }}>
        <img src={logo} />
        <span>
            Header
        </span>
        <hr />
    </div>
}

function Pdf() {
    const pdfRef = useRef(null);
    const downloadPdf = () => {
        pdfRef.current.downloadPdf();
    }


    const Content = [
        <img id='img' key='img' style={
  { maxHeight: '200px', width: 'auto' }} src={img} />,
        ...mockData.map((data, ind) => {
            return (
                <div key={data.id}>
                    <h3>{data.title}</h3>
                    {
                        (ind % 8 === 0) && <img key={'img' + ind} style={
  { maxHeight: '100px', width: 'auto' }} src={img} />
                    }
                    <div style={
  {
                        color: 'grey',
                    }}>
                        {
                            data.content.map((content, ind) => (
                                <p key={ind}>{content}</p>
                            ))
                        }
                    </div>
                </div>
            )
        })
    ]

    return (
        <>
            <h3>
                Pdf
            </h3>
            {/* 按钮 */}
            <button onClick={downloadPdf}>Download</button>


            <PdfComponent
                ref={pdfRef} // 组件ref
                plr={23} // 左右边距
                keepImgQuality={true} // 是否保持图片质量
                scale={4} // 用于让html放大n倍后再转为canvas 用于修改生成pdf的清晰度,越清晰pdf大小会越大
                decoratePdf={(pdf, pageTotal, headerSize, footerSize) => { // 装饰pdf,导出pdf对象,用于生成页数之类的修饰信息
                    pdf.setFontSize(9); // 设置字体大小
                    const lineHeight = pdf.getLineHeight(); // 获取行高
                    
                    new Array(pageTotal).fill(0).forEach((item, i) => { // 根据总页数循环添加页码
                        // set page & date
                        pdf.setPage(i + 1);

                        const pageText = (i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值