前端玩Word:Word文档解析成浏览器认识的HTML

前言

领导跟富文本编辑器杠上啦,领导有一个类似于某雀导入Word文档,解析内容后渲染到编辑器编辑的需求。某雀功能效果如下:

怎么搞定呢?自己写一个解析器?

本文分享Word文件转换成浏览器认识的HTML实战经验。

什么是Word文档

Word是微软公司开发的一个文字处理器应用程序,它是Office软件中的一个组件。使用Microsoft Office Word可创建和编辑信件、报告、网页或电子邮件中的文本和图形。相比于写字板和记事本功能更强大,性能更全面,可以插入图片、多媒体、艺术效果等

Word 支持的文件格式

列举一下Word常用的几种文件模式:

Word支持的文档格式蛮多,想了解的读者移步Word、Excel 和 PowerPoint 的文件格式参考。

docx、doc有什么区别

Word文档格式相信读者跟我一样见过最多的是docx、doc格式。

有了doc为啥又带出个docx?

网上流传一个故事:从某一时期开始微软办公文件名的小尾巴多了一个“x”。原来word、PowerPoint还有excel,后缀名分别是doc、ppt、xls。后来,就突然涌现出了docx、pptx、xlsx。

原来的doc格式是加密的,只有微软自己家的软件才能打开。

后来微软觉得,这样并没有让自己很神圣,反而限制了自己的发展。

比如,金山WPS也是搞办公软件的,它的发展很快,积累了很多用户。不少人开始用wps了,word的用户面临被瓜分。于是,微软就基于Office Open XML标准,把文档家族做了兼容。

因为新标准是采用的xml格式记录信息的,所以就在.doc后面加了个x。新标准之后,即便是微软创建的文档,WPS也能打开。这样,用户只关心文档就行,不用在意用哪个软件,这就实现了用户共享。

当然我不能验证是否是真的,听说而已。

简单总结两者区别:

  • docx和doc相比文件体积更小,对复杂对象的处理也更好
  • docx是为了替代doc:Microsoft Word 2007版本开始,docx已经替代了doc,doc也不再进行开发
  • doc是二进制文件,docx是xml文件。docx扩展名可修改为zip、rar等压缩包格式,使用压缩软件打开,查看内部各类文件,实现批量替换图片等

Word文档转HTML实战

市面上实现该功能方案有两种:

  • 前端把Word文档上传给后端,由后端来解析,然后在通过接口把解析的内容返回给前端
  • 前端解析,直接把解析后的内容渲染出来或传递给后端

两种方案,说不上谁好谁坏,只有视业务场景来决定。

本文仅分享方案二的实现。想了解后端解析请移步Word转换HTML(Java实用版)。

怎么来解析

docx看起来是一个文件,其实是一个压缩包,它的文件结构是这样的:

位于word下的document.xml文件docx的主文件。可以说,文档中你能看到的所有内容,在这里都有直接或者间接的记录。

document.xml内容都被XML标签进行了包裹,把XML标签转化成HTML标签即达成Word转HTML的目的。

前提是对XML标签熟悉,总不能瞎转吧!!!

不用担心,不熟悉也没关系,我们站在前人的肩膀上做这一步。

Mammoth是什么

Mammoth是一个专注于转换 .docx 文档的工具库,它能将Microsoft Word、Google Docs 和 LibreOffice 创建的文档转换成HTML,Mammoth会利用文档的XML语义信息,忽略其他细节,从而生成简单明了的 HTML。比如Mammoth会将任何带有标题 1 样式的段落转换为 h1 元素,但不会把标题的样式(字体、文字大小、颜色等)全部复制过去。

Mammoth支持以下功能:

  • 标题
  • 列表
  • 标题
  • 列表
  • 可定制的 docx 样式到 HTML 的映射。例如,您可以通过提供适当的样式映射,将 WarningHeading 转换为 h1.warning
  • 表格:表格格式(如边框)会被忽略
  • 脚注和尾注
  • 图片
  • 粗体、斜体、下划线、删除线、上标和下标。
  • 链接
  • 换行
  • 文本框:文本框的内容被视为一个单独的段落,出现在包含文本框的段落之后。
  • 注释

Mammoth提供了支持将docx转换成Markdown、HTML、纯文本的方法。

Mammoth实战

Mammoth官方demo:

const mammoth = require("mammoth");

mammoth.convertToHtml({path: "path/to/document.docx"})
    .then(function(result){
        const html = result.value; // 转换的HTML
        const messages = result.messages; 
    })
    .catch(function(error) {
        console.error(error);
    });

这是在Node.js环境中的案例,浏览器环境是无法通过{path: "path/to/document.docx"}来读取到docx文件。

如果是要在浏览器环境中执行它,需要docx文件转化为arrayBuffer数组再作为参数传递给convertToHtml

const  updateWord = {
	handleFileSelect(event) {
			const self = this
			this.readFileInputEventAsArrayBuffer(event, function (arrayBuffer) {
			    mammoth.convertToHtml({ arrayBuffer: arrayBuffer }, {
							//...
					})
			}
  },
	//文件转化成arrayBuffer数据类型
	readFileInputEventAsArrayBuffer(event, callback) {
      const file = event.target.files[0];
      const reader = new FileReader();
      reader.onload = function (loadEvent) {
          const arrayBuffer = loadEvent.target.result;
          callback(arrayBuffer);
      };
      reader.readAsArrayBuffer(file);
  }
}

//获取文件file后,传递给handleFileSelect函数
updateWord.handleFileSelect(file)

Word文档也许存在图片,Mammoth默认会把图片转成base64格式,这样我们得到的HTML内容会特殊的大。正常情况我们肯定是想要把图片上传到我们自己的服务器,HTML内容保留图片链接即可。

Mammoth也提供了相应方法:

const  updateWord = {
 //base64格式转blob
	base64ToBlob(base64, mimeType) {
        let bytes = window.atob(base64);
        let ab = new ArrayBuffer(bytes.length);
        let ia = new Uint8Array(ab);
        for (let i = 0; i < bytes.length; i++) {
            ia[i] = bytes.charCodeAt(i);
        }
        return new Blob([ia], { type: mimeType });
  },

	handleFileSelect(event,{success, fail}) {
			const self = this
			this.readFileInputEventAsArrayBuffer(event, function (arrayBuffer) {
			   mammoth.convertToHtml({ arrayBuffer: arrayBuffer }, {
                //处理图片
                convertImage: mammoth.images.imgElement(function (image) {
                    return image.read("base64").then(async (imageBuffer) => {
                        //base64转blob
                        const blob = self.base64ToBlob(imageBuffer, 'image/png')
                        blob.name = Date.now() + '.png'
                        const result = await new Promise((resolve, reject) => {
	                            //图片上传逻辑,可以自定义
															upImage({ file: blob }, {
                                resolve,
                                reject
                            })
                        })
                        const url = result.default
                        return {
                            src: url
                        }
                    });
                })
            }).then(success, fail);
			}
  },
//...
}

upImage是上传图片到我们自己服务器的逻辑,这个逻辑大家自定义发挥,只要最后把图片链接返回return {src: url},它会把base64替换掉。

至此,完成Word文档转换HTML,又能摸鱼了。

更高级的摸鱼

平常的学习、工作中,经常性出现某个项目开发上线某个功能,另外一个项目也提出相同的功能需求。历史总是惊人的相似。

为了以后再遇到类似需求,我把docx文件转换HTML这段代码保存在CodeGist中,方便下次直接引用。

CodeGist是一款代码管理工具,详细介绍请移步【工具推荐】代码管理工具 CodeGist

参考资源

  • Word、Excel 和 PowerPoint 的文件格式参考
  • DOC跟DOCX有什么不同?

推荐阅读

  • 盘点2023前端技术,谁才是当红炸子鸡
  • 人人都能用的AI编程助手 CodeGeeX
  • 三分钟搞懂Serverless,互联网个人创业者必备

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/366721.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot项目引入redis数据库的简单使用案例

springboot项目引入redis数据库的简单使用案例&#xff01;很多项目都需要使用到redis数据库&#xff0c;这是一个内存型的&#xff0c;非关系型数据库。它的读取速度非常快。因为存在了内存中。不是在硬盘中。而且它可以解决很多棘手的问题&#xff0c;比如&#xff1a;解决一…

Django的web框架Django Rest_Framework精讲(二)

文章目录 1.自定义校验功能&#xff08;1&#xff09;validators&#xff08;2&#xff09;局部钩子&#xff1a;单字段校验&#xff08;3&#xff09;全局钩子&#xff1a;多字段校验 2.raise_exception 参数3.context参数4.反序列化校验后保存&#xff0c;新增和更新数据&…

项目开发 多行编辑

问题 项目开发中&#xff0c;如何进行多行编辑 详细问题 笔者使用IDEA&#xff0c;Android Studio进行项目开发时&#xff0c;由于代码冗余&#xff0c;修改过程中若是逐一删除或编辑&#xff0c;效率相对低&#xff0c;如何进行多行删除或编辑 本文将提供IDEA&#xff0c;A…

152基于matlab的GUI滚动轴承特征频率计算

基于matlab的GUI滚动轴承特征频率计算&#xff0c;输入轴承参数&#xff0c;包括转速&#xff0c;节圆直径、滚子直径、滚子数、接触角&#xff0c;就可得滚动特征频率结果&#xff0c;程序已调通&#xff0c;可直接运行。 152 matlab 轴承特征频率 GUI (xiaohongshu.com)

MongoDB的分片集群(一) : 基础知识

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 目录导读 1. 什么是MongoDB分片 2. MongoDB分片集群介绍 2.1 MongoDB分片集群架构 2.2 MongoDB分片集群优势 3. 分片键…

排序(5)——归并排序

六、归并排序 1.简介 归并排序也是一种很经典的排序算法&#xff0c;采用分治的思想方法进行数据的处理。归并讲究的是先拆后合&#xff0c;也就是分治中的分而治之。在拿到一组数据后&#xff0c;程序会将整个数据进行不断拆分直至有序&#xff0c;因为单个元素必然有序&…

【类和对象】4

日期类的拓展 c语言中的printf函数只能打印内置类型&#xff0c;为了弥补这一不足&#xff0c;c利用运算符重载可以打印自定义类型。 void operator<<(ostream&out);//声明在date.h中void Date::operator<<(ostream& out)//定义在date.cpp中 {out<<…

Flutter解析后台发来的jwt字段数据,了解jwt是否过期

前言 了解JWT是什么可以看这一篇博文 JWT&#xff08;JSON Web Token&#xff09;详解以及在go-zero中配置的方法-CSDN博客 流程 采用jwt_decoder库 添加至pubspec.yaml jwt_decoder: ^2.0.1 解析字段 查看是否过期 获取过期时间和token颁发的年龄

PythonStudio 控件使用常用方式(五)TListBox

PythonStudio是一个极强的开发Python的IDE工具&#xff0c;它使用的是Delphi的控件&#xff0c;常用的内容是与Delphi一致的。但是相关文档并一定完整。现在我试试能否逐步把它的控件常用用法写一点点&#xff0c;也作为PythonStudio的参考。 TListBox是列表框 常用属性 col…

【操作系统·考研】I/O管理概述

1.I/O设备 1.1 块设备 信息交换以数据块为单位&#xff0c;它属于有结构设备。 块设备传输速率较高&#xff0c;可寻址&#xff0c;且可对该设备随机地的读写。 栗子&#x1f330;&#xff1a;磁盘。 1.2 字符设备 信息交换以字符为单位&#xff0c;属于无结构类型。 字符…

LabVIEW叶片厚度远程监控

LabVIEW叶片厚度远程监控 随着网络技术的高速发展&#xff0c;远程监控广泛应用在各个领域。本文介绍了一种基于LabVIEW的植物叶片厚度远程监控系统&#xff0c;旨在实现对植物生长状况的精准监测和分析。 该系统利用LabVIEW软件开发工具&#xff0c;通过TCP网络协议实现数据…

关于反爬虫的的概述

目录 前言 一、验证码验证 二、IP限制 三、User-Agent限制 四、动态页面加载 总结 前言 反爬虫是一种防止网站被自动程序&#xff08;爬虫&#xff09;访问和抓取数据的技术手段。在网络爬虫的发展和使用过程中&#xff0c;有一部分爬虫是用于非法获取网站数据、侵犯隐私…

删除有序数组中的重复项 II[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个有序数组nums&#xff0c;请你原地删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须在原地修改输入数组并在使用O(1)额…

Java基于SpringBoot+Vue的美容院管理系统,附源码,文档

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

20240202在Ubuntu20.04.6下使用whisper.cpp的显卡模式

20240202在Ubuntu20.04.6下使用whisper.cpp的显卡模式 2024/2/2 19:43 【结论&#xff1a;在Ubuntu20.04.6下&#xff0c;确认large模式识别7分钟中文视频&#xff0c;需要356447.78 ms&#xff0c;也就是356.5秒&#xff0c;需要大概5分钟&#xff01;效率太差&#xff01;】 …

electron项目在内网环境的linux环境下进行打包

Linux需要的文件: electron-v13.0.0-linux-x64.zip appimage-12.0.1.7z snap-template-electron-4.0-1-amd64.tar.7z 下载慢或者下载失败的情况可以手动下载以上electron文件复制到指定文件夹下&#xff1a; 1.electron-v13.0.0-linux-x64.zip 复制到~/.cache/electron/目录下…

web前端--------渐变和过渡

线性渐变&#xff0c;是指颜色沿一条直线进行渐变&#xff0c;例如从上到下、从左到右。 当然&#xff0c;CSS中也支持使用角度来设置渐变的方向&#xff0c;角度单位为deg。 0deg&#xff0c;为12点钟方向&#xff0c;表示从下到上渐变。 90deg&#xff0c;为3点钟方向&…

海外社媒营销平台及运营规则,如何降低封号率?

社交媒体已经成为人们生活和日常习惯不可或缺的一部分&#xff0c;在跨境电商出海过程中&#xff0c;海外社媒营销平台可以起到非凡的助力&#xff1b;而平台的选择以及平台的运营技巧、规则都各有不同。很多海外社媒工作者经常会被封号&#xff0c;这也是难度之一&#xff0c;…

吸猫毛空气净化器哪个好?推荐除猫毛效果好的宠物空气净化器品牌

如今&#xff0c;越来越多的家庭选择养宠物&#xff0c;使家庭变得更加温馨。然而&#xff0c;养宠物可能会带来异味和空气中的毛发增多&#xff0c;这可能会成为一大困扰&#xff0c;并对健康造成问题。 为了不让家里充斥着异味&#xff0c;特别是来自宠物便便的味道&#xf…

无人零售模式下,“IoT+鸿蒙”实现零代码搭建自动售货机监控大屏的可能性摸索

前言 新零售模式下&#xff0c;对loT的探索与应用还在继续。 而数字时代&#xff0c;数字化转型在零售行业中蔓延&#xff0c;而对于新的消费方式的探索&#xff0c;也在如火如荼的进行中。于是&#xff0c;一种新零售的形式——无人零售逐渐形成概念。 如果说&#xff0c;人…
最新文章