记录-html-docs-js避坑指南

这篇具有很好参考价值的文章主要介绍了记录-html-docs-js避坑指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录-html-docs-js避坑指南

前言

我们公司目前在做基于tiptap的在线协同文档,最近需要做导出 pdf、word 需求。

导出 word 文档使用的是html-docx-js-typescript,是用 typescript 重写了一下html-docx-js,可以看到最近的提交记录是 2016 年,貌似已经不维护了,很多 Issues 没人管。

记录-html-docs-js避坑指南

实在找不到其他的 html 转 word 的插件,最后只能使用它来处理,我把我在使用过程中遇到的问题一一列出来,就有了这篇避坑指南。

使用说明

  • 安装

    安装html-docx-js-typescript,同时安装FileSaver用于浏览器端保存文件。

npm install html-docx-js-typescript file-saver --save-dev
npm install @types/html-docx-js @types/file-saver --dev
  • 使用方法

    参考官方示例

使用过程遇到的问题及处理方案

字体加粗不生效、字体背景颜色不生效处理

字体加粗<strong>和标记文本元素<mark>标签需要替换为<b><span>标签

const innerHtml = cloneEle.innerHTML
  // strong在word中不生效问题
  .replace(/<strong>/g, '<b>')
  .replace(/<\/strong>/g, '</b>')
  // 背景色不生效问题
  .replace(/<mark/g, '<span')
  .replace(/<\/mark>/g, '</span>')

h1 - h6 标题高度优化及未同步 word 文档标题

我们文档中的标题对应的 HTML 内容长这样

记录-html-docs-js避坑指南

 

 

 需要将内容转换为类似<h1>xxx</h1>这样,不然 word 中编辑时不能对应标题,修改如下:

// 标题高度和字体失效 需要设置lineHeight和fontWeight
const handleLevelStyle = (cloneEle: HTMLElement) => {
  Array.from({ length: 6 }).forEach((_, index) =>
    (cloneEle.querySelectorAll(`h${index + 1}`) as unknown as HTMLElement[]).forEach((h) => {
      h.innerText = (h.children[0] as HTMLElement).innerText
      h.style.fontSize = ''
    })
  )
}

图片下多出一个白框

Prosemiror-images上传图片后,会在图片后面生成.ProseMirror-separator这个标签,我们在导出时只需要删除它即可。

const removeWhiteBox = (cloneEle: HTMLElement) => {
  const separators: NodeListOf<Element> = cloneEle.querySelectorAll(
    '.ProseMirror-separator'
  )
  separators.forEach((separator) =>
    separator.parentElement?.removeChild(separator)
  )
}

列表 ul、ol

在开始处理之前,先介绍一个插入 DOM 的 API insertAdjacentElement。

在 vue、react 这些框架的盛行,基本上我们已经不会再用到 DOM 操作,不过可以了解一下,万一以后用得到呢。

// 将给定元素element插入到调用的元素的某个位置
element.insertAdjacentElement(position, element)

参数position可以是以下位置

  • 'beforebegin': 插入元素之前,类似 insertBefore
  • 'afterbegin': 插入元素第一个 children 之前,类似 prepend
  • 'beforeend': 插入元素最后一个 children 之后,类似 appendChild
  • 'afterend': 插入元素之后,类似 insertAfter

接着我们看一下列表这部分的修改,由于我们项目功能上的需求,列表是使用 div 标签来改造的,所以需要将 div 标签转为 ul/ol,下面是我的实现

const changeDiv2Ul = (div: HTMLElement | Element, parent?: HTMLElement | Element) => {
  const kind = div.getAttribute('data-list-kind')
  const ul = kind === 'ordered' ? document.createElement('ol') : document.createElement('ul')
  const li = document.createElement('li')
  // 去除margin 不然在word中会偏移
  !parent && (ul.style.margin = '0')
  li.innerHTML = div.innerHTML
  ul.appendChild(li)
  parent ? parent.insertAdjacentElement('afterend', ul) : div.insertAdjacentElement('afterend', ul)
  div.parentElement?.removeChild(div)

  li.querySelectorAll('.list-marker').forEach((marker) => marker.parentElement?.removeChild(marker))

  // 内容区域
  li.querySelectorAll('.list-content').forEach((content) => {
    const span = document.createElement('span')
    span.innerHTML = (content.firstChild as HTMLElement).innerHTML
    content.insertAdjacentElement('beforebegin', span)
    if (content.querySelectorAll('.prosemirror-flat-list').length) {
      content.querySelectorAll('.prosemirror-flat-list').forEach((div) => changeDiv2Ul(div, content))
    }
    content.parentElement?.removeChild(content)
  })
}
cloneEle.querySelectorAll('.prosemirror-flat-list').forEach((div) => changeDiv2Ul(div))

复选框 checkbox

复选框 checkbox 的处理,首先考虑的是转为<input type='checkbox' />来处理,结果转完后并没有显示复选框;

接着又想着用 span 标签生成一个方框,<span style='width: 16px;height: 16px...' />,这样总能显示了吧!结果依然不行。

正当我想不到办法的时候,突然灵机一动,可不可以把 word 转成 html 后看看 checkbox 最终会显示成啥样呢?

于是通过在线 word 转 html将 word 转为 html 后,看到复选框对应的 html 内容为<span style="color:#333333; font-family:'Wingdings 2'; font-size:11pt"></span>,改一下吧。

const span = document.createElement('span')
span.innerHTML = `<span style="color:#333333; font-family:'Wingdings 2'; font-size:11pt"></span>`
marker.insertAdjacentElement('beforebegin', span)
marker.parentElement?.removeChild(marker)

转成 word 后,复选框的选中和取消功能也能正常使用。

附件导出、多维表等 iframe 内容

参考了一下钉钉文档

记录-html-docs-js避坑指南

这样就很好改了,只需要把附件对应的节点内容,改为链接即可。

cloneEle.querySelectorAll('.attachment-node-wrap').forEach((attach) => {
  const title = `请至One文档查看附件《${attach.getAttribute('name')}》`
  const anchorId = attach.parentElement?.getAttribute('data-id')
  const a = document.createElement('a')
  a.target = '_blank'
  a.href = `${location.href}&anchor=${anchorId}`
  a.innerHTML = `<span>${title}</span>`

  attach.insertAdjacentElement('beforebegin', a)
  attach.parentElement?.removeChild(attach)
})

未解决的部分

  • 表情无法导出,这个我看了下其他在线协作文档,也有同样的问题。

小结

其实,处理这些问题的方式也是很简单,因为html-docs-js是用html字符串来作为导出文档的输入。如果导出后发现样式不对的情况时,我们只需要去修改html内容即可。

如果有遇到像复选框checkbox这类不知道怎么解决的问题,也可以采用反推,先通过word转html,然后看转为html后的内容,再去修改需要导出的html内容,这也不失为一种解决问题的方式。

以上是我在使用html-docs-js插件时遇到的一些问题及处理方式,如果有遇到同样问题的小伙伴,可以说下你们的处理方式。或者这里没有提到的问题,也欢迎大家补充。

本文转载于:

https://juejin.cn/post/7220244579671916604

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录-html-docs-js避坑指南文章来源地址https://www.toymoban.com/news/detail-409685.html

到了这里,关于记录-html-docs-js避坑指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ES避坑指南

    分片是一个功能完整的搜索引擎,它拥有使用一个节点上的所有资源的能力。 索引一旦创建分片数量就已经确定,且不可更改,默认为5个分片,每个分片有1个副本 _index: 索引名,这个名字必须小写,不能以下划线开头,不能包含逗号 _type: 索引下的逻辑分区 一个 _type 命名可

    2023年04月09日
    浏览(39)
  • Prisma 避坑指南!

    环境变量问题 npx prisma db push 默认取 .env 配置文件,那多环境怎么处理? 增加 .env.test .env.prod 等文件, 安装 dotenv-cli ,执行 dotenv -e .env.test -- npx prisma db push 来指定 prisma 的运行环境 实际项目中与 nodejs (koa、egg、midway、nest)等框架结合使用时,如 midway.js ,包含内置配置文件为

    2024年02月11日
    浏览(32)
  • MSELoss详解+避坑指南

    loss(xi,yi)=(xi−yi)2 loss(xi,yi)=(xi−yi)2 这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标。 很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数。因为一般损失函数都是直接计算 batch 的数据,因此返回的 loss 结果都是维度为 (batch_size, ) 的向量。 (1)如果 red

    2024年02月05日
    浏览(47)
  • 数据结构入门指南:链表(新手避坑指南)

    目录 前言 1.链表 1.1链表的概念  1.2链表的分类 1.2.1单向或双向 1.2.2.带头或者不带头 1.2.33. 循环或者非循环 1.3链表的实现  定义链表 总结         前边我们学习了顺序表,顺序表是数据结构中最简单的一种线性数据结构,今天我们来学习链表,难度相较于顺序表会大幅增

    2024年02月15日
    浏览(52)
  • 项目管理软件选择指南:最佳实践与避坑指南

    当今企业中,协作工具是必不可少的,每个企业都会寻找最适合自己的协作工具来提高工作效率。在这些协作工具中,Zoho Projects项目协作工具是最常用的一种,因为它能够为团队提供一个集任务、项目、文档、IM、目标、日历、甘特图、工时、审批等多个功能于一体的协作环

    2024年02月16日
    浏览(42)
  • WebSocket后端搭建,避坑指南

    网上有很多写WebSocket搭建的案例,我这里也是主要记录一下,我在部署WebSocket上踩到的坑。案例主要是给自己记录一下 我这里是用SpringBoot 搭建的WebSocket 首先就是配置类的代码 在之后就是WebSocket的核心代码,消息的接收和连接的建立都是基于这个类 因为我们在@ServerEndpoint这

    2023年04月20日
    浏览(26)
  • 分布式性能测试避坑指南

    当进行分布式性能测试时,以下是一些避坑的指南: 1.定义明确的测试目标 在开始测试之前,确保清楚地定义测试的目标和需求。确定要测试的关键指标和阈值,以便能够准确评估系统的性能。 2.设计合适的测试场景 根据实际使用情况和预期负载,设计具有代表性的测试场

    2024年02月12日
    浏览(45)
  • RabbitMq-发布确认高级(避坑指南版)

    在初学rabbitMq的时候,伙伴们肯定已经接触到了“发布确认”的概念,但是到了后期学习中,会接触到“springboot”中使用“发布确认”高级的概念。后者主要是解决什么问题呢?或者是什么样的场景引出这样的概念呢? 废话不说直接开始撸代码!!!在代码中解决实际问题

    2024年02月11日
    浏览(42)
  • Android 14 刷机指南 & 避坑指导

    Android 14已经进入Beta阶段,提前布局的小伙伴,可以刷机适配了。 Android 14 Beta images are available for the following Google Pixel devices: Pixel 4a (5G) Pixel 5 and 5a Pixel 6 and 6 Pro Pixel 6a Pixel 7 and 7 Pro Android 14链接 一般Android 都是支持4代以内的设备,我手里之前有一台Pixel 4x,已经不满足需求,

    2024年02月10日
    浏览(53)
  • Android SeekBar使用避坑指南

    SeekBar是Android原生UI组件,可以用来调节进度,广泛应用于音乐、视频进度展示调控、音量、亮度调节等功能里。 SeekBar的使用很简单,这里就不再介绍了,本文着重介绍一下作者最近在使用SeekBar遇到的几个坑,希望大家以后可以避免。 如图,如何去实现这样一个可拖动进度

    2024年02月07日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包