html页面保存为PDF
-
准备插件
html2canvas // 保证html清晰的转为图片数据 jsPDF // 将图片数据转为PDF
-
代码
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;