前端实现 word 转 png

由于 java 后端的 itext 库是收费版,公司安全部门发出安全警告,要求整改。

所以采用前端实现 word 文档转图片功能。

一、需求

上传 docx 文件,并生成 png 图片作为缩略图

二、分析

前端无法直接把 docx 文档转成图片格式

三、解决方案

既然直接转无法实现,那就采用迂回战术

  1. 先转成 html(用到库 docx-preview
  2. 再将 html 转成 canvas(用到库 html2canvas
  3. 最后将 canvas 转成 png

四、实现步骤:

  1. docx 文件转成 html 格式,并插入目标节点中

    安装 docx-preview 依赖: pnpm add docx-preview --save

jsx 复制代码
import { useEffect } from 'react';
import * as docx from 'docx-preview';

export default ({ file }) => {
  useEffect(() => {
    // file 为上传好的 docx 格式文件
    docx2Html(file);
  }, [file]);

  /**
   * @description: docx 文件转 html
   * @param {*} file: docx 格式文件
   * @return {*}
   */
  const docx2Html = file => {
    if (!file) {
      return;
    }
    // 只处理 docx 文件
    const suffix = file.name?.substr(file.name.lastIndexOf('.') + 1).toLowerCase();
    if (suffix !== 'docx') {
      return;
    }
    const htmlContentDom = document.querySelector('#htmlContent'); // 生成 html 后挂载的 dom 节点
    const docxOptions = Object.assign(docx.defaultOptions, {
      debug: true,
      experimental: true,
    });
    docx.renderAsync(file, htmlContentDom, null, docxOptions).then(() => {
      console.log('docx 转 html 完成');
    });
  };

  return <div id='htmlContent' />;
};

此时,在 idhtmlContent 的节点下,就可以看到转换后的 html 内容了

  1. html 转成 canvas

    安装 html2canvas 依赖: pnpm add html2canvas --save

jsx 复制代码
import html2canvas from 'html2canvas';

/**
 * @description: dom 元素转为图片
 * @return {*}
 */
const handleDom2Img = async () => {
  const htmlContentDom = document.querySelector('#htmlContent'); // 生成 html 后挂载的 dom 节点
  // 获取刚刚生成的 dom 元素
  const htmlContent = htmlContentDom.querySelectorAll('.docx-wrapper>section')[0]; // 需要生成图片的 html 内容
  // 创建 canvas 元素
  const canvasDom = document.createElement('canvas');

  // 获取 dom 宽高
  const w = parseInt(window.getComputedStyle(htmlContent).width, 10);
  // const h = parseInt(window.getComputedStyle(htmlContent).height, 10);

  // 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
  const scale = window.devicePixelRatio; // 缩放比例
  canvasDom.width = w * scale; // 取文档宽度
  canvasDom.height = w * scale; // 缩略图是正方形,所以高度跟宽度保持一致

  // 按比例增加分辨率,将绘制内容放大对应比例
  const canvas = await html2canvas(htmlContent, {
    canvas: canvasDom,
    scale,
    useCORS: true,
  });
  return canvas;
};
  1. 将生成好的 canvas 转成 png 文件,并下载
jsx 复制代码
// 将 canvas 转为 base64 图片
const base64Str = canvas.toDataURL();

// 下载图片
const imgName = `图片_${new Date().valueOf()}`;
const aElement = document.createElement('a');
aElement.href = base64Str;
aElement.download = `${imgName}.png`;
document.body.appendChild(aElement);
aElement.click();
document.body.removeChild(aElement);
window.URL.revokeObjectURL(base64Str);
相关推荐
shmily麻瓜小菜鸡6 分钟前
前端“伪防盗链”方案
前端·javascript·vue.js·bootstrap·echarts
mayaairi6 分钟前
JS数组完全指南(含十大操作详解)
开发语言·前端·javascript
IT_陈寒27 分钟前
Python的线程池把我CPU跑满了,原来少传了个参数
前端·人工智能·后端
喜欢的名字被抢了35 分钟前
写-Chrome-扩展时踩过的那些-MV3-的坑
前端·chrome
网安老伯1 小时前
网络安全基础要点知识介绍(非常详细),零基础入门到精通,看这一篇就够了
运维·前端·网络协议·web安全·网络安全·职场和发展
wuqingshun3141591 小时前
springBoot是如何通过main方法启动web项目的?
前端·spring boot·后端
xxwl5851 小时前
HTML 小总结:从骨架到枝叶,系统掌握网页结构
前端·html
●VON1 小时前
鸿蒙 PC Markdown 编辑器 Bridge 协议:原生外壳与 Web 内核的状态同步
前端·华为·编辑器·harmonyos·鸿蒙
MrDJun1 小时前
分享一款免费实用的网页变动监控工具:PageWatch.tech
前端·javascript·vue.js
米码收割机1 小时前
【web】邻里悦站—社区便民服务平【独一无二】(源码+说明文档)
前端