关于html导出word总结一

news/2024/2/25 12:22:13/文章来源:https://blog.csdn.net/oiooooio/article/details/135574885

总结

测试结果不理想,html-to-docx 和   html-docx-js 最终导出的结果 都 差强人意,效果可以见末尾的附图

环境

 "electron": "24.3.0"

依赖库

html-docx-js

html-docx-js - npm

html-to-docx

html-to-docx - npm

file-saver

file-saver - npm

测试结果

 html-docx-js 

这个库在前端  【我】 无法使用,在用的时候,库本身的代码里需要全局变量 __dirname, 这个在前端浏览器环境好像是没有的,是属于node环境的变量

html-to-docx

这个可以用,但效果不好,最终效果见下方附图,这里附上使用代码,下面的代码文件可以直接使用。


import { saveAs } from 'file-saver'
import HTMLtoDOCX from 'html-to-docx'const printStyles = `@media print {body, html {margin: 0;padding: 0;}}`function getHtmlContent(ctrlId) {// 获取整个页面的 HTMLconst pageHTML = document.documentElement.outerHTML// 使用 DOMParser 解析 HTMLconst parser = new DOMParser()const doc = parser.parseFromString(pageHTML, 'text/html')// 找到 #printableAreaconst printableArea = doc.querySelector(ctrlId)if (!printableArea) return ''// 隐藏 #printableArea 以外的所有元素doc.body.childNodes.forEach(node => {if (node !== printableArea) {if (node.style) node.style.visibility = 'hidden'}})// 删除所有 .no-print 元素const noPrintElements = printableArea.querySelectorAll('.no-print')noPrintElements.forEach(el => el.remove())// 获取所有的 style 和 link 标签const styles = doc.querySelectorAll('style, link[rel="stylesheet"]')return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>Document</title><style>${Array.from(styles).map(style => style.outerHTML).join('\n')}</style><style>${printStyles}</style></head><body>${printableArea.outerHTML}</body></html>`
}/*** 这个接口可以把一个 HTML 字符串转成 docx 文件* 但经过测试,在某些html页面下,存在导出的 docx 文件无法打开的问题,比如整个页面都是table套table...* 通过HTMLtoDOCX导出的word,word内容版式是非常不理想的* 先保留这个代码万一以后用得到~* @param {*} ctrlId #abc*/
export const exportWord = async function(ctrlId) {const htmlString = getHtmlContent(ctrlId)const fileBuffer = await HTMLtoDOCX(htmlString, null, {table: { row: { cantSplit: true }},footer: true,pageNumber: true})// console.log('fileBuffer', fileBuffer)saveAs(fileBuffer, 'html-to-docx.docx')
}

附注

用python把html导出docx

格式错乱,没用

原生table标签导出为xlsx

原网页效果

导出的xlsx效果

效果还行

代码

import FileSaver from 'file-saver'
import * as XLSX from 'xlsx'function getHtmlContent(ctrlId) {// 获取整个页面的 HTMLconst pageHTML = document.documentElement.outerHTML// 使用 DOMParser 解析 HTMLconst parser = new DOMParser()const doc = parser.parseFromString(pageHTML, 'text/html')// 找到 #printableAreaconst printableArea = doc.querySelector(ctrlId)if (!printableArea) return ''// 隐藏 #printableArea 以外的所有元素doc.body.childNodes.forEach(node => {if (node !== printableArea) {if (node.style) node.style.visibility = 'hidden'}})// 删除所有 .no-print 元素const noPrintElements = printableArea.querySelectorAll('.no-print')noPrintElements.forEach(el => el.remove())return printableArea
}export const exportExcel = async function(ctrlId) {const exportContent = getHtmlContent(ctrlId)// console.log(XLSX)/* generate workbook object from table */// var wb = XLSX.utils.table_to_book(document.querySelector(ctrlId))var wb = XLSX.utils.table_to_book(exportContent)/* get binary string as output */var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })try {FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), 'sheetjs.xlsx')} catch (e) {if (typeof console !== 'undefined') { console.log(e, wbout) }}// return wbout
}

通过pdf转word

导出pdf,通过pdf转word,确实还不错 , 但是pdf里的文字都被截取成图片放到word里了。。

附图

原网页

下图是上面的代码中函数getHtmlContent返回的html保存到html文件后,打开的样子,后面的导出都以   getHtmlContent返回的html  为准

html-to-docx 库导出的docx

第二页就不放了~

导出为pdf

pdf的效果是完美的~

pdf转word

效果非常不错,但其中的每一段文字都是图片,无法编辑

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

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

相关文章

基于DNA的密码学和隐写术综述

摘要 本文全面调研了不同的脱氧核糖核酸(DNA)-基于密码学和隐写术技术。基于DNA的密码学是一个新兴领域,利用DNA分子的大规模并行性和巨大的存储容量来编码和解码信息。近年来,由于其相对传统密码学方法的潜在优势,如高存储容量、低错误率和对环境因素的抗性,该领域引起…

JDK8-JDK17版本升级

局部变量类型推断 switch表达式 文本块 Records 记录Records是添加到 Java 14 的一项新功能。它允许你创建用于存储数据的类。它类似于 POJO 类&#xff0c;但代码少得多&#xff1b;大多数开发人员使用 Lombok 生成 POJO 类&#xff0c;但是有了记录&#xff0c;你就不需要使…

第 2 章 数据结构和算法概述

文章目录 2.1 数据结构和算法的关系2.2 看几个实际编程中遇到的问题2.2.1 问题一-字符串替换问题2.2.2 一个五子棋程序2.2.3 约瑟夫(Josephu)问题(丢手帕问题)2.2.4 其它常见算法问题: 2.3 线性结构和非线性结构2.3.1 线性结构2.3.2 非线性结构 2.1 数据结构和算法的关系 数据 …

使用Qt连接scrcpy-server控制手机

Qt连接scrcpy-server 测试环境如何启动scrcpy-server1. 连接设备2. 推送scrcpy-server到手机上3. 建立Adb隧道连接4. 启动服务5. 关闭服务 使用QTcpServer与scrcpy-server建立连接建立连接并视频推流完整流程1. 开启视频推流过程2. 关闭视频推流过程 视频流的解码1. 数据包协议…

【STM32】HAL库的STOP低功耗模式UART串口唤醒,第一个接收字节出错的问题(已解决)

【STM32】HAL库的STOP低功耗模式UART串口唤醒&#xff0c;第一个接收字节出错的问题&#xff08;已解决&#xff09; 文章目录 BUG复现调试代码推测原因及改进方案尝试中断时钟供电外设唤醒方式校验码硬件问题 切换到STOP0模式尝试结论和猜想解决方案附录&#xff1a;Cortex-M…

js动态设置关键侦@keyframes

js动态设置关键侦keyframes 1.前置知识 关键侦keyframes规则通过在动画序列中定义关键侦的样式来控制CSS动画序列的中间步骤 keyframes slidein {from {transform: translateX(0%);}to {transform: translateX(100%);} } // from 等价于 0%&#xff1b;to 等价与 100% // 或…

【已解决】C语言进行多线程数据切割查找数据

第一次听到多线程切割&#xff0c;笔者也没听的太懂&#xff0c;但发现多线程数据切割其实就是分出多个线程&#xff0c;进行处理查找数据的事情。而为什么切割呢&#xff0c;就是因为数据不够线程数分的&#xff0c;假如1k个数据&#xff0c;7个线程&#xff0c;这里不能够整除…

RabbitMQ的安装使用

RabbitMQ是什么&#xff1f; MQ全称为Message Queue&#xff0c;消息队列&#xff0c;在程序之间发送消息来通信&#xff0c;而不是通过彼此调用通信。 RabbitMQ 主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时&#xff0c;消费者无法快速消费&#xff0c;…

蓝桥杯备赛 | 洛谷做题打卡day5

蓝桥杯备赛 | 洛谷做题打卡day5 图论起航&#xff0c;一起来看看深&#xff08;广&#xff09;度优先吧 ~ 文章目录 蓝桥杯备赛 | 洛谷做题打卡day5图论起航&#xff0c;一起来看看深&#xff08;广&#xff09;度优先吧 ~【深基18.例3】查找文献题目描述 输入格式输出格式样例…

vue知识-04

计算属性computed 注意&#xff1a; 1、计算属性是基于它们的依赖进行缓存的 2、计算属性只有在它的相关依赖发生改变时才会重新求值 3、计算属性就像Python中的property&#xff0c;可以把方法/函数伪装成属性 4、computed: { ... } 5、计算属性必须要有…

MySQl Mybatis

一、MySQL 1.1 概述 1.1.1 MySQL安装 1.1.2 数据模型 1.1.3 SQL简介 1.2 DDL 1.2.1 数据库操作 1.2.2 图形化工具 1.2.3 表结构操作 &#xff08;一&#xff09;创建 &#xff08;二&#xff09;数据类型 &#xff08;1&#xff09;数值类型 age tinyint unsigned——加上…

Kubernetes 集群管理—日志架构

日志架构 应用日志可以让你了解应用内部的运行状况。日志对调试问题和监控集群活动非常有用。 大部分现代化应用都有某种日志记录机制。同样地&#xff0c;容器引擎也被设计成支持日志记录。 针对容器化应用&#xff0c;最简单且最广泛采用的日志记录方式就是写入标准输出和标…

书生·浦语大模型--第三节课笔记--基于 InternLM 和 LangChain 搭建你的知识库

文章目录 大模型开发范式RAGLangChain框架&#xff1a;构建向量数据库构建检索问答链优化建议web 部署 实践部分环境配置 大模型开发范式 LLM的局限性&#xff1a;时效性&#xff08;最新知识&#xff09;、专业能力有限&#xff08;垂直领域&#xff09;、定制化成本高&#…

测试平台出问题?看我20分钟快速定位!

今天遇到一个问题&#xff0c;感觉挺有意思&#xff0c;处理过程也非常有意义&#xff0c;希望能给大家一个借鉴吧。今天一位小姐姐找到了我们大组长&#xff0c;说测试平台添加自动化测试用例失败&#xff0c;之后我们组长把我拉到了一个群里让我去看一下&#xff0c;硬着头皮…

C++面试宝典第19题:最长公共前缀

题目 编写一个函数来查找字符串数组中的最长公共前缀,如果不存在公共前缀,返回空字符串""。说明:所有输入只包含小写字母a-z。 示例1: 输入: ["flower", "flow", "flight"]输出: "fl" 示例2: 输入: ["dog",…

如何在Windows 10/11的防火墙中禁止和允许某个应用程序,这里提供详细步骤

想阻止应用程序访问互联网吗&#xff1f;以下是如何通过简单的步骤阻止和允许Windows防火墙中的程序。​ 一般来说&#xff0c;大多数用户永远不需要担心应用程序访问互联网。然而&#xff0c;在某些情况下&#xff0c;你需要限制应用程序访问互联网。 例如&#xff0c;有问题…

vue知识-03

购物车案例 要实现的功能&#xff1a; 1、计算商品总价格 2、全选框和取消全选框 3、商品数量的增加和减少 <body> <div id"app"><div class"row"><div class"col-md-6 col-md-offset-3"><h1 class"text-center…

TinyLog iOS v3.0接入文档

1.背景 为在线教育部提供高效、安全、易用的日志组件。 2.功能介绍 2.1 日志格式化 目前输出的日志格式如下&#xff1a; 日志级别/[YYYY-MM-DD HH:MM:SS MS] TinyLog-Tag: |线程| 代码文件名:行数|函数名|日志输出内容触发flush到文件的时机&#xff1a; 每15分钟定时触发…

【Spring 篇】走进SpringMVC的世界:舞动Web的激情

嗨&#xff0c;亲爱的小白们&#xff01;欢迎来到这篇关于SpringMVC的博客&#xff0c;让我们一起探索这个舞动Web的框架&#xff0c;感受它带来的激情和便利。在这个世界里&#xff0c;我们将学到SpringMVC的概述、开发步骤以及如何快速入门&#xff0c;一切都是如此的令人兴奋…

C# Winform翻牌子记忆小游戏

效果 源码 新建一个winform项目命名为Matching Game&#xff0c;选用.net core 6框架 并把Form1.cs代码修改为 using Timer System.Windows.Forms.Timer;namespace Matching_Game {public partial class Form1 : Form{private const int row 4;private const int col 4;p…