import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
export function useHtml2Canvas() {
/**
* 捕获元素并转换为Canvas
* @param {HTMLElement|string} target - 目标元素或选择器
* @param {number} scale - 图片清晰度
* @param {object} options - html2canvas选项
* @returns {Promise<HTMLCanvasElement>}
*/
const captureToCanvas = async (target, scale?: number, options = {}) => {
const targetEl = typeof target === 'string' ? document.querySelector(target) : target;
if (!targetEl) throw new Error('未找到目标元素');
return await html2canvas(targetEl, {
scale: scale ? scale : 4,
useCORS: true,
...options
});
};
/**
* 捕获元素并下载为图片
* @param {HTMLElement|string} target - 目标元素或选择器
* @param {string} filename - 文件名
* @param {string} scale - 提高清晰度 (默认是4)
* @param {object} options - html2canvas选项
*/
const captureToImage = async (target, filename = 'screenshot', scale = 4, options = {}) => {
const canvas = await captureToCanvas(target, scale, options);
const link = document.createElement('a');
link.download = `${filename}.png`;
link.href = canvas.toDataURL('image/png');
link.click();
};
/**
* 捕获元素并下载为PDF(支持A3/A4等格式)
* @param {HTMLElement|string} target - 目标元素或选择器
* @param {string} filename - 文件名
* @param {string} format - 纸张格式 (A3/A4等)
* @param {string} scale - 提高清晰度 (默认是4)
* @param {string} orientation - 方向 ('portrait' 纵向, 'landscape' 横向)
*/
const captureToPDF = async (
target: HTMLElement | string,
filename = 'document',
format = 'A4',
scale?: number,
orientation = 'portrait'
) => {
const canvas = await captureToCanvas(target, scale ? scale : 4);
// 创建PDF实例
const pdf = new jsPDF(orientation as any, 'mm', format);
// 计算图片尺寸以适应纸张
// pdf的宽高
const pdfWidth = format === 'A3' ? 297 : 210;
const pdfHeight = format === 'A3' ? 420 : 297;
// 画布宽高
const canvasWidth = canvas.width;
const canvasheight = (pdfHeight * canvas.width) / pdfWidth;
// 生成图片的高度
const imgHeight = (canvas.height * pdfWidth) / canvas.width;
// 得到pdf页数向上取整
const totalNumber = Math.ceil(imgHeight / pdfHeight);
for (let i = 0; i < totalNumber; i++) {
// 创建临时canvas,用于储存切分的初始canvas
const tempCanvas = document.createElement('canvas');
tempCanvas.width = canvasWidth;
tempCanvas.height = canvasheight;
// 将最初canvas分成多份,计算每份的高度
const canvasHeightPerPage = i < totalNumber - 1 ? canvasheight : canvas.height - canvasheight * i;
const ctx = tempCanvas.getContext('2d');
if (!ctx) continue;
// 填充背景颜色防止出现黑边
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvasWidth, canvasheight);
// 在原始canvas中截取正确位置绘制在新画布中
ctx.drawImage(
canvas,
0,
i * canvasheight,
canvas.width,
canvasHeightPerPage,
0,
0,
tempCanvas.width,
canvasHeightPerPage
);
if (i > 0) pdf.addPage();
// 添加到PDF
const imgData = tempCanvas.toDataURL('image/jpeg');
pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight);
}
// 保存PDF
pdf.save(`${filename}.pdf`);
// 获取 PDF 的Blob二进制对象
// const pdfArrayBlob = pdf.output('blob');
// return pdfArrayBlob
// 获取 PDF 的原始二进制数据
// const pdfArraybuffer = pdf.output('arraybuffer');
// return pdfArraybuffer
};
return {
captureToCanvas,
captureToImage,
captureToPDF
};
}
02-08
3154
