前端把页面用PDF导出

使用场景:

把展示的页面内容,导出PDF方便查看

主要使用的是 jspdf-html2canvas 组件

安装

javascript 复制代码
npm install jspdf-html2canvas --save   
//^1.6.0  如果使用不行,再尝试控制版本使用
//npm install jspdf-html2canvas@1.6.0 --save

使用

javascript 复制代码
import html2PDF from 'jspdf-html2canvas';

// 绑定元素
const reportNewRef = React.useRef<HTMLDivElement>(null);

//下载函数
 const testDownload = async () => {
    try {
      const dom = reportNewRef.current;
      if (!dom) {
        return;
      }

      await html2PDF(dom, {
        jsPDF: {
          format: 'a4',
          unit: 'mm',
          orientation: 'portrait',
          hotfixes: ['px_scaling'], // 解决 px 单位在高分屏上的缩放问题
        },
        html2canvas: {
          scale: 2, // 放大比例,解决高分辨率屏幕下图像模糊问题
          useCORS: true,
          logging: false,
          backgroundColor: '#fff', // 背景颜色设置为白色
          scrollX: 0,
          scrollY: 0, // 禁止纵向滚动
          windowWidth: dom.scrollWidth, // 设置为内容的实际宽度,确保完整渲染
        },
        margin: { top: 0, right: 12, bottom: 0, left: 12 },
        imageType: 'image/jpeg', // 使用 JPEG 格式,通常比 PNG 更小
        imageQuality: 1, // 设置为 1,表示最高质量的 JPEG 图片
        output: '下载文件.pdf', // 输出文件名
      });
      message.success('PDF下载成功');
    } catch (err) {
      console.error('导出失败', err);
      message.error('PDF导出失败');
    }
};





// 点击下载按钮
<Button key="download" type="primary" icon={<DownloadOutlined />}
    onClick={() => {
         //这里触发下载函数 
         testDownload()
    }}
>
 下载PDF
</Button>


//需要下载的页面
<div ref={reportNewRef}>

这里是下载内容,里面就正常写,怎么展示在页面上就怎么写。

</div>

隐藏页面来下载

主要是利用元素控制下载页面的显隐并且把下载内容定位到用户看不到的地方。

监听是否显示和页面是否存在,延时下载,考虑数据加载需要时间,这一块也可以考虑到数据请求完成,页面加载完成后,再做下载操。

javascript 复制代码
 const [open, setOpen] = useState(false);
 const reportNewRef = React.useRef<HTMLDivElement>(null);
 const testDownload = async () => {
    try {
      const dom = reportNewRef.current;
      if (!dom) {
        return;
      }

      await html2PDF(dom, {
        jsPDF: {
          format: 'a4',
          unit: 'mm',
          orientation: 'portrait',
          hotfixes: ['px_scaling'], // 解决 px 单位在高分屏上的缩放问题
        },
        html2canvas: {
          scale: 2, // 放大比例,解决高分辨率屏幕下图像模糊问题
          useCORS: true,
          logging: false,
          backgroundColor: '#fff', // 背景颜色设置为白色
          scrollX: 0,
          scrollY: 0, // 禁止纵向滚动
          windowWidth: dom.scrollWidth, // 设置为内容的实际宽度,确保完整渲染
        },
        margin: { top: 0, right: 12, bottom: 0, left: 12 },
        imageType: 'image/jpeg', // 使用 JPEG 格式,通常比 PNG 更小
        imageQuality: 1, // 设置为 1,表示最高质量的 JPEG 图片
        output: '下载文件.pdf', // 输出文件名
      });
      message.success('PDF下载成功');
    } catch (err) {
      console.error('导出失败', err);
      message.error('PDF导出失败');
    } finally {
      setOpen(false);
    }
  };

  useEffect(() => {
  let timeoutId: NodeJS.Timeout;

  if (open === true && reportNewRef.current) {
    // 清理之前的定时器
    timeoutId = setTimeout(() => {
      testDownload();
    }, 1000);
  }

  // 清理函数
  return () => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
  };
}, [open, reportNewRef]); // 只有最后一次触发会执行


// 点击下载按钮
<Button key="download" type="primary" icon={<DownloadOutlined />}
    onClick={() => {
         //这里触发下载函数 
       setOpen(true)
    }}
>
 下载PDF
</Button>


//下载内容  通过控制元素显隐和绝对定位使其元素位置隐藏显示元素
 {open && (
   <div className="absolute top-[-200vh] w-[1000px] z-50 bg-white">
      <div>下载内容</div>
   </div>
)}
相关推荐
徐小夕17 分钟前
花了3天,我写了一款开源AI公众号编辑器
前端·vue.js·github
PBitW25 分钟前
git 中容易遗忘的点 (二) ⚡⚡⚡
前端·git·面试
Hilaku33 分钟前
2026 年前端大洗牌:React 服务端到 Vite 的底层重构
前端·javascript·程序员
PBitW1 小时前
git 中容易遗忘的点 (三) 🚀🚀🚀
前端·git·面试
名字还没想好☜1 小时前
React setState 连续调用「丢更新」排查:批量更新与函数式更新
前端·javascript·react.js·react·usestate
sugar__salt1 小时前
DeepSeek-R1 WebGPU (1):在浏览器里跑大模型
react.js·reactjs·react·端模型
come112341 小时前
Vue 2 与 Vue 3 语法区别及使用技巧
前端·javascript·vue.js
腻害兔1 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:ERP 企业资源模块,一个轻量级进销存的完整实现?
前端·javascript·vue.js·人工智能·前端框架·产品经理·ai编程
虹科网络安全1 小时前
艾体宝新闻|从 SQL 注入到服务器接管:CVE-2026-57517 暴露 Web 管理面板的供应链与安全编码风险
服务器·前端·sql
糖果店的幽灵2 小时前
langgraph的四种state解析
java·前端·javascript·langgraph