前端-导出png,jpg,pptx,svg

发布于:2025-02-12 ⋅ 阅读:(13) ⋅ 点赞:(0)

两款比较主流的截图工具 

特性 dom-to-image html2canvas
体积 几 KB 几十 KB
速度 非常快 较慢
浏览器兼容性 与所有现代浏览器兼容 与部分浏览器兼容性较差
跨域截图 不支持 支持
自定义截图区域 不支持 支持
CSS 属性支持 不支持某些 CSS 属性 支持所有 CSS 属性

dom-to-image该库自 2020 年后基本处于维护状态,更新频率较低。这意味着它可能不会再添加新的功能,更多是对现有问题进行修复。 html-to-image:html-to-image是dom-to-image的一个分支,它继承了dom-to-image的核心功能,并且持续保持更新。开发者会不断添加新特性、优化性能和修复已知问题,社区活跃度相对较高。 

安装与引用

//安装

npm install html2canvas

//引入

import html2canvas from 'html2canvas'; 

 //安装

npm install html-to-image

//引入

import * as htmlToImage from 'html-to-image';

import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image';

htmlToImage主要的方法有:

htmlToImage.toPng(…);将节点转化为png格式的图片

htmlToImage.toJpeg(…);将节点转化为jpg格式的图片

htmlToImage.toSvg(…);将节点转化为svg格式的图片,生成的图片的格式都是base64格式 htmlToImage.toBlob(…);将节点转化为二进制格式,这个可以直接将图片下载 htmlToImage.toPixelData(…);获取原始像素值,以Uint8Array 数组的形式返回,每4个数组元素表示一个像素点,即rgba值。这个方法也是挺实用的,可以用于WebGL中编写着色器颜色。

htmlToImage主要的属性有:

filter : 过滤器节点中默写不需要的节点;

bgcolor : 图片背景颜色;

height, width : 图片宽高;

style :传入节点的样式,可以是任何有效的样式;

quality : 图片的质量,也就是清晰度;//jpeg

cacheBust : 将时间戳加入到图片的url中,相当于添加新的图片;

imagePlaceholder : 图片生成失败时,在图片上面的提示,相当于img标签的alt; 

1.img-(png,jpg)

  • JPG:其完整名称是 Joint Photographic Experts Group,它实际上指的是由该专家小组制定的一种图像压缩标准。不过在日常生活和技术领域中,人们习惯用 “JPEG” 来表示采用此标准压缩的图像文件,并且文件扩展名常写成 “.jpg” 或者 “.jpeg”。该标准非常适合用于存储照片和色彩丰富的图像,因为它能在一定程度上平衡图像质量和文件大小。
  • PNG:全称为 Portable Network Graphics,即便携式网络图形。它是作为替代 GIF 格式而开发的一种图像文件格式,支持无损数据压缩。PNG 格式在网页设计、图形设计以及需要透明背景效果的场景中应用广泛,因为它不仅能保证图像质量,还能实现良好的透明效果。

示例(react+ant-design):

  const menuProps = {

    items: exportFormat.map(item => ({

      ...item,

      onClick: () => handleClick(item)

    }))

  }

①利用html2canvas

png,jpg核心:使用 html2canvas 将 <div> 渲染为 Canvas,然后导出为图片。

利用html2canvas转换: 

JavaScript 库,可以将 DOM 元素渲染为 Canvas。它通过遍历 DOM 树,将每个元素的样式和内容绘制到 Canvas 上。

if (['jpg', 'png'].includes(item.label)) {
        let canvas=await  html2canvas(post.current)
        //将 Canvas 的内容转换为 Base64 编码的图像数据 URL。
        const image = canvas.toDataURL(`img/${item.label}`)
        //创建一个 <a> 标签,设置其 href 为图像数据 URL,并触发点击事件来实现文件下载。
        const link = document.createElement('a')
        link.href = image
        link.download = `post.${item.label}`
        link.click()
    }
②利用dom-to-image
    if (['jpg', 'png'].includes(item.label)) {
        const image = item.label === 'png' ? await htmlToImage.toPng(post.current, { bgcolor: 'white' }) : await htmlToImage.toJpeg(post.current, { quality: 0.95, bgcolor: 'white' });
        const link = document.createElement('a');
        link.href = image;
        link.download = `post.${item.label}`;
        link.click();
    }

 2.pptx

//安装

npm install pptxgenjs

//引用

import PptxGenJS from 'pptxgenjs';

if (['pptx'].includes(item.label)) {
      console.log(222);
      //利用html2canvas
      const canvas = await html2canvas(post.current);
      //将 Canvas 的内容转换为 Base64 编码的图像数据 URL。
      const image = canvas.toDataURL('image/png');//方法1
      //利用dom-to-image
      const image=await htmlToImage.toPng(post.current)//方法2
      const pptx = new PptxGenJS();
      // 添加一张幻灯片
      const slide = pptx.addSlide();
      //x/y:距离幻灯片左边/右边的距离
      //w/h:图片的大小 单位都为英寸
      slide.addImage({ data: image, x: 1, y: 1, w: 4.5, h: 3 });
      pptx.writeFile({ fileName: 'post.pptx' });

    }

3.svg

html-to-image 的核心技术是利用SVG的 <foreignObject> 标签,将DOM节点嵌入到SVG中,然后将其转换为图像格式。

    if (item.label === 'svg') {
      // 获取 SVG 字符串-DataUrl形式
      const svgString = await htmlToImage.toSvg(post.current);
      // 提取并解码 URL 编码的 SVG 内容
      const svgContent = decodeURIComponent(svgString.split(',')[1]);
      // 创建 Blob 对象
      const blob = new Blob([svgContent], { type: 'image/svg+xml' });
      const url = URL.createObjectURL(blob);
      // 创建下载链接
      const link = document.createElement('a');
      link.href = url;
      link.download = 'post.svg';
      link.click();
      // 释放 URL 对象
      URL.revokeObjectURL(url);
    }

如果直接就是svg而不是dom元素:

 const svgElement = post.current.querySelector('svg');
 const serializer = new XMLSerializer();
 const svgString = serializer.serializeToString(svgElement);
 const blob = new Blob([svgString], { type: 'image/svg+xml' });
 const url = URL.createObjectURL(blob);
 const link = document.createElement('a');
 link.href = url;
 link.download = 'post.svg';
 link.click();
 URL.revokeObjectURL(url);

无论是哪种方式,需要注意的是:

在将DOM元素导出为SVG时,直接使用XMLSerializerdom-to-image等工具通常不会保留CSS样式,因为这些工具主要关注的是DOM结构和内联样式。为了确保导出的SVG包含CSS样式,您可以采取以下方法:

  function inlineStyles(element) {
            const computedStyle = window.getComputedStyle(element);
            console.log(computedStyle);
            for (let i = 0; i < computedStyle.length; i++) {
              const property = computedStyle[i];
              element.style.setProperty(property, computedStyle.getPropertyValue(property));
            }
            // 递归处理子元素
            element.childNodes.forEach(child => {
              if (child.nodeType === Node.ELEMENT_NODE) {
                inlineStyles(child);
              }
            });
          }
          // 对内联 SVG 元素及其 <foreignObject> 内的元素应用内联样式
          inlineStyles(svgElement);