背景

项目中常常需要将页面图表导出到word下载,这个时候一般都是直接用html2canvas,将echart或非常规的页面(比如海报之类)直接转换成图片下载。

  new html2canvas(document.getElementById('pageForWord'), {
    allowTaint: true,
    useCORS: true
  }).then(function(canvas){
		var $oImg = $('#WODE-DIV').find('img');
		var src = canvas.toDataURL();
    $oImg.attr('src', src ); // 导出图片
  });

但随着网页越来越复杂,它的性能问题也逐渐暴露,速度慢占资源,用户体验不尽如人意。

AI调研替代方案

Deepseek:

1. dom-to-image:轻量级,性能好,支持 PNG、JPEG 和 SVG 格式

domtoimage.toPng(document.getElementById('element'))
    .then(function (dataUrl) {
        var img = new Image();
        img.src = dataUrl;
        document.body.appendChild(img);
    });

2、rasterizeHTML.js

将 HTML/CSS 渲染到 canvas,支持外部css和js

3、html-to-image

TypeScript 支持

import { toPng } from 'html-to-image';

const element = document.getElementById('element');
toPng(element)
  .then(dataUrl => {
    // 处理生成的图片
  });

4、浏览器原生api

CanvasRenderingContext2D.drawWindow()

根据不同需求的选型建议

纯前端需求:优先考虑 html-to-image 或 dom-to-image

复杂布局:尝试 rasterizeHTML.js

高保真需求:使用 Puppeteer/Playwright 服务端渲染

需要字体支持:服务端方案通常更可靠

文心快码

html2canvas的替代方案有多种,包括snapDOM、dom-to-image、wkhtmltoimage等‌。

snapDOM:

性能优越‌:据官方基准测试,snapDOM在多种场景下比html2canvas快数倍至数十倍。

功能全面‌:支持捕获所有CSS样式、伪元素、Shadow DOM等,并提供多种输出格式(SVG、PNG、JPG、WebP等)。

使用简单‌:一行代码即可实现截图功能,且支持高级配置和批量处理。

wkhtmltoimage‌:

命令行工具‌:无需编写JavaScript代码,通过命令行即可将HTML页面转换为图片。

功能强大‌:支持多种输出格式和选项,如页面宽度、高度、裁剪等。

环境依赖‌:需要在服务器上安装wkhtmltopdf工具包,且可能存在跨平台兼容性问题。

Puppeteer‌:

Node.js库‌:提供了一个高级的API来控制无头Chrome浏览器,实现网页截图。

自动化能力强‌:除了截图外,还支持页面渲染、表单提交、点击等操作,适用于自动化测试和爬虫等场景。

资源消耗大‌:由于需要启动无头浏览器,因此资源消耗较大,且启动速度较慢。

甄选→snapDOM

在对具体需求、性能要求、环境限制等因素进行权衡后,根据对性能和前端库体积的要求,选择了体量小、功能全且实现简单的snapDOM

大体上的对比是酱紫的:

性能:

功能:

使用简单


const card = document.querySelector('.user-card');
const image = await snapdom.toPng(card);

document.body.appendChild(image);

snapDOM概述

SnapDOM 就是一个专门用来给网页元素截图的工具。

它能把 HTML 元素快速又准确地存成各种图片格式,像 SVGPNGJPGWebP 等等,还支持导出为 Canvas 元素。并把网页上的各种复杂元素,比如 CSS 样式、伪元素Shadow DOM内嵌字体背景图片,甚至是动态效果的当前状态,都原原本本地截下来,跟直接看网页没啥两样。

SnapDOM 优势

1、最大的优势——快!

尤其在超大元素(4000×2000)截图时,速度是 html2canvas 的 93.31 倍,比 dom-to-image 快了 133.12 倍。

2、高清晰度还原

各种复杂的 CSS 样式、伪元素Shadow DOM内嵌字体背景图片,还有动态效果的当前状态,都能精准还原。

3、svg、 PNGJPG、webp等多种格式任选

SnapDOM实操

1、安装

npm install @zumer/snapdom

import { snapdom } from '@zumer/snapdom

或者直接cdn模式引入

<script src="https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.min.js"></script>

2、一键截图

将empResume保存为图片插入到页面:

const empResume = document.getElementById("empResume");
const image = await snapdom.toPng(empResume);
document.body.appendChild(image);

配置参数:清晰度、背景色、字体、压缩比例等

const element = document.querySelector('.chart-container');
const capture = await snapdom(element, {
    scale: 2,
    backgroundColor: '#fff',
    embedFonts: true,
    compress: true
});
const png = await capture.toPng();
const jpg = await capture.toJpg({ quality: 0.9 });
await capture.download({
    format: 'png',
    filename: 'chart-report-2024'
});

应用

对于复杂渲染的页面(员工履历海报、招聘信息),还可以转成blob下载或保存。

async function generatePoster(hbData) {
    document.querySelector('.hb-title').textContent = hb.name;
    document.querySelector('.hb-desc').textContent = hb.desc;
    document.querySelector('.hb-image').src = hb.photo;
    await new Promise((resolve) => setTimeout(resolve, 100));
    const elementObj = document.querySelector('.hb-container');
    const blob = await snapdom.toBlob(elementObj, { scale: 2 });
    return blob;
}

报表下载

async function exportReport() {
    const reportSummary = document.getElementById('report');
// 预加载资源以优化性能
    await preCache(reportSummary);
 // 生成报表图片
    await snapdom.download(reportSummary, {
        format: 'png',
        scale: 2,
        filename: `report-${new Date().toISOString().split('T')[0]}`
    });
}

其他应用backup

1、性能优化

import { preCache } from '@zumer/snapdom';

// 方案1:页面加载时预缓存
window.addEventListener('load', async () => {
    await preCache(document.body, { embedFonts: true });
   
});

// 方案2:按需预缓存
async function captureWithCache(element) {
    // 页面截图前预缓存
    if (!element.dataset.cached) {
        await preCache(element);
        element.dataset.cached = 'true';
    }

    return snapdom.toPng(element);
}

2、批处理

async function batchExport(selector) {
    const elements = document.querySelectorAll(selector);
    const images = [];

    
    const promises = Array.from(elements).map(async (el, index) => {
        const blob = await snapdom.toBlob(el);
        return {
            name: `export-${index + 1}.png`,
            blob
        };
    });

    return Promise.all(promises);
}

注意事项

1、外部图片必须支持 CORS,否则无法捕获

2、超大页面建议分区域截图,避免内存溢出

3、iframe内资源无法捕获

3、WebP 格式在 Safari 上会降级为 PNG

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐