【插件】前端生成word 文件

文章目录

    • 1、背景
    • 2、方式一:html-docx-js
      • 2.1 具体代码
      • 2.2 前端生成word文件的样式
      • 2.3 总结
    • 3、方式二:pizzip + docxtemplater
      • 3.1 具体代码
      • 3.2 前端生成word文件的样式
      • 3.3 总结
    • 4、参考链接

1、背景

在实际开发中,业务需要,需要把数据进行组合生成一个 word 文件

2、方式一:html-docx-js

在这里插入图片描述

注意,这个插件 最近的更新日期 八年之前了

2.1 具体代码

核心逻辑

  1. 画出 Word 文件内容样子
  2. 把 word文件内容样子的DOM 。传入 html-docx-jsasBlob 方法
  3. 处理 blob 格式的数据,配合 a 标签,直接在界面弹出文件

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>HTML to Word</title>
  <script src="https://cdn.jsdelivr.net/npm/html-docx-js@0.3.1/dist/html-docx.min.js"></script>
  <style>
    .abc {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      font-weight: bold;
    }

    .title {
      font-weight: bold;
      text-align: center;
      vertical-align: middle;
    }

    .textCenter {
      text-align: center;
    }

    tr,
    td {
      font-size: 12px;
    }

    * {
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>

  <div id="content">
    <div style="font-size: 48px; font-weight: bold; text-align: center">质量反馈单</div>
    <div>反馈单单号: WLYD202412250049</div>
    <table style="width: 100%;" border="1" cellspacing="0" cellpadding="0" class="textCenter">
      <tr>
        <td class="title">质量问题主题</th>
        <td colspan="3" class="textCenter">
          你还是是大家看会玩空间的哈授课计划的卡号夸奖哈首府卡迪夫好看就好的夸奖哈库文件很大看见你是法务会计贺卡就是饭卡文化按时付款计划啊空间未婚夫你还是是大家看玩空间的哈授课计划的卡号夸奖哈首府卡迪夫好看就好的夸奖哈库文件很大看见你是法务会计贺卡就是饭卡文化按时付款计划啊空间未婚夫你还是是大家看会玩空间的哈授课计划的卡号夸奖哈首府卡迪夫好看就好的夸奖哈库文件很大看见你是法务会计贺卡就是饭卡文化按时付款计划啊空间未婚夫
        </td>

      </tr>
      <tr>
        <td style="width: 15%;" class="title">反馈日期</td>
        <td style="width: 35%;">2024-11-23</td>
        <td style="width: 15%;" class="title">质量问题等级</td>
        <td style="width: 35%;">严重</td>
      </tr>
      <tr>
        <td class="title">电站名称</td>
        <td>北京市超级充电站</td>
        <td class="title">电站运营时间</td>
        <td>2024-11-23</td>
      </tr>
      <tr>
        <td class="title">项目类型</td>
        <td>头肩</td>
        <td class="title">反馈公司</td>
        <td>特来电新能源</td>
      </tr>
      <tr>
        <td class="title">反馈人</td>
        <td>呆呆狗</td>
        <td class="title">反馈人电话</td>
        <td>18856491536</td>
      </tr>
      <tr>
        <td class="title">父级设备</td>
        <td>箱变</td>
        <td class="title">设备生产日期</td>
        <td>2024-11-23</td>
      </tr>
      <tr>
        <td class="title">子型号</td>
        <td>子星号</td>
        <td class="title">故障设备</td>
        <td>故障设备</td>
      </tr>
    </table>
    <!-- 现场问题描述 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td rowspan="2" style="width: 15%;" class="title">现场问题描述</td>
        <td style="width: 85%;height: 100px;vertical-align:top">edddd</td>
      </tr>
      <tr style="height: 40px;">
        <td>填写人: 呆呆狗</td>
      </tr>
    </table>
    <!-- 纠正 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td rowspan="7" style="width: 15%;text-align: center;" class="title">纠正</td>
        <td colspan="2" style="width: 17%;text-align: center;" class="title">分类</td>
        <td class="title" style="width: 10%;">数量</td>
        <td class="title">措施</td>
        <td class="title" style="width: 15%;">日期</td>
      </tr>
      <tr>
        <td style="text-align: center;" colspan="2">现场故障设备</td>
        <td class="textCenter">12345.00</td>
        <td>3</td>
        <td class="textCenter">2024-01-01</td>
      </tr>
      <tr>
        <td rowspan="3" style="text-align: center;">在库</td>
        <td style="text-align: center;">供应商在库</td>
        <td class="textCenter">3</td>
        <td>4</td>
        <td class="textCenter">2024-01-01</td>
      </tr>
      <tr>
        <td style="text-align: center;">XXX在库</td>
        <td class="textCenter">3</td>
        <td>4</td>
        <td class="textCenter">2024-01-01</td>
      </tr>
      <tr>
        <td style="text-align: center;">区域仓在库</td>
        <td class="textCenter">3</td>
        <td>4</td>
        <td class="textCenter">2024-01-01</td>
      </tr>
      <tr>
        <td style="text-align: center;" colspan="2">在市</td>
        <td class="textCenter">2</td>
        <td>3</td>
        <td class="textCenter">2024-01-01</td>
      </tr>
      <tr>
        <td style="text-align: center;" colspan="2">其他</td>
        <td class="textCenter">2</td>
        <td>3</td>
        <td class="textCenter">2024-01-01</td>
      </tr>
    </table>
    <!-- 具体原因分析 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td rowspan="3" style="width: 15%;" class="title">原因分析</td>
        <td style="width: 10%;" class="title">发生原因</td>
        <td>2</td>
      </tr>
      <tr>
        <td style="width: 10%;" class="title">流出原因</td>
        <td>2</td>
      </tr>
      <tr>
        <td style="width: 10%;" class="title">其他</td>
        <td>2</td>
      </tr>
    </table>
    <!-- 纠正措施 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td rowspan="4" style="width: 15%;" class="title">纠正措施</td>
        <td style="width: 10%;" class="title"></td>
        <td class="title">措施</td>
        <td style="width: 15%;" class="textCenter title">日期</td>
      </tr>
      <tr>
        <td style="width: 10%;" class="title">发生</td>
        <td>2</td>
        <td style="width: 15%;" class="textCenter">2024-11-23</td>
      </tr>
      <tr>
        <td style="width: 10%;" class="title">流出</td>
        <td>2</td>
        <td style="width: 15%;" class="textCenter">2024-11-23</td>
      </tr>
      <tr>
        <td style="width: 10%;" class="title">举一反三</td>
        <td>2</td>
        <td style="width: 15%;" class="textCenter">2024-11-23</td>
      </tr>
    </table>
    <!-- 标准化 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td rowspan="3" style="width: 15%;" class="title">标准化</td>
        <td class="title">文件名称</td>
        <td style="width: 10%;" class="title">文件类型</td>
        <td style="width: 15%;" class="title">日期</td>
      </tr>
      <tr>
        <td>流出</td>
        <td style="width: 10%;" class="textCenter">新增</td>
        <td style="width: 15%;" class="textCenter">2024-11-23</td>
      </tr>
      <tr>
        <td>举一反三</td>
        <td style="width: 10%;" class="textCenter">修改</td>
        <td style="width: 15%;" class="textCenter">2024-11-23</td>
      </tr>
    </table>
    <!-- 责任部门 和 责任部门领导审批 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td style="width: 15%;" class="title">责任部门</td>
        <td class="textCenter">总裁办</td>
        <td style="width: 10%;" class="title">负责人</td>
        <td style="width: 15%;" class="textCenter">呆呆狗</td>
        <td style="width: 10%;" class="title">日期</td>
        <td style="width: 15%;" class="textCenter">2024-01-01</td>
      </tr>
      <tr>
        <td style="width: 15%;" class="title">责任部门领导审批</td>
        <td colspan="3" class="textCenter">总裁办</td>
        <td style="width: 10%;" class="title">日期</td>
        <td style="width: 15%;" class="textCenter">2024-01-01</td>
      </tr>
    </table>
    <!-- 跟踪验证结果 -->
    <table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td rowspan="3" style="width: 15%;" class="title">跟踪验证确认</td>
        <td style="width: 85%;height: 100px;vertical-align:top">
          缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结缺陷反酷点总结
        </td>
      </tr>
      <tr style="height: 40px;">
        <td>验证结果: 关闭 无效</td>
      </tr>
      <tr style="height: 40px;">
        <td>负责人: 呆呆狗 日期:2024-12-30 </td>
      </tr>
      <tr>
        <td style="width: 15%;font-family: '宋体';font-size: 12pt;" class="title">备注</td>
        <td style="font-family: '宋体';font-size: 12pt"></td>
      </tr>
    </table>
  </div>

  <button id="downloadButton">Download as Word</button>

  <script>
    document.getElementById("downloadButton").onclick = function () {
      var content = document.getElementById("content").outerHTML;

      var fullHtml = `
          <!DOCTYPE html>
          <html>
          <head>
            <meta charset="UTF-8">
            <style>
            * {
              margin: 0;
              padding: 0;
            }
            .title { font-weight: bold;text-align: center; vertical-align: middle;}
            tr,
            td {
              font-size: 14px;
            }
            .textCenter {
              text-align: center;
            }
            </style>
          </head>
          <body>
            ${content}
          </body>
          </html>
        `;
      var converted = htmlDocx.asBlob(fullHtml);
      var link = document.createElement("a");
      link.href = URL.createObjectURL(converted);
      link.download = "document.docx";
      link.click();
    };
  </script>
</body>

</html>

其实主要核心代码就是下面这几行

    var converted = htmlDocx.asBlob(fullHtml);
      var link = document.createElement("a");
      link.href = URL.createObjectURL(converted);
      link.download = "document.docx";
      link.click();

html-docx-jsasBlob 方法,传入前端的DOM ,然后,用 URL.createObjectURL 创建一个blob 格式的链接,配合 a标签 就可以了

2.2 前端生成word文件的样式

在这里插入图片描述
在这里插入图片描述

2.3 总结

优点

  1. 代码简单,上手速度快
  2. 不需要依赖于 后端,前端可以独自处理

缺点

  1. 支持的 html、css 比较简单,比如 flex、grid 不支持
  2. 这个库已经很久不维护
  3. 图片需要转成 base64 才能放进去
  4. word的 行高字体字号 支持性较差

如果对于 word 文件的样子要求不是很高,可以使用这个 方法,开发过程也相对比较简单

3、方式二:pizzip + docxtemplater

3.1 具体代码

在这里插入图片描述
核心思路

  1. 读取预先设置好的 word 文件
  2. 解析word ,解析成二进制
  3. 创建docxtemplater实例
  4. 填充word 里面的数据
  5. 渲染word
  6. 获取渲染后word的 blob 地址
  7. 下载 word

前提需要准备一个这样的word 文件 ,下面的代码是演示 插入循环 table,具体的文件在文章最顶部可以下载

这个word 里面的 语法可以参考这个链接 docxtemplater 语法演示

{Code} 在前端设置数据的时候,按照这个名字 和 要设置的值,组成 keyvalue 格式即可

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Docxtemplater Example</title>
  <script src="https://cdn.jsdelivr.net/npm/pizzip@3.0.1/dist/pizzip.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/docxtemplater@3.29.0/build/docxtemplater.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js"></script>
  <script
    src="https://unpkg.com/docxtemplater-image-module-free@3.0.0/dist/docxtemplater-image-module-free.js"></script>
</head>

<body>
  <h1>Generate Word Document</h1>
  <button id="generate">Download Word</button>

  <script>
    document.getElementById('generate').addEventListener('click', function () {
      // 1、读取word 文件
      fetch('./template.docx')
        .then(response => response.arrayBuffer())
        .then(arrayBuffer => {
          console.log('第一步', arrayBuffer);

          // 2、解析word
          const zip = new PizZip(arrayBuffer);

          // 3、创建docxtemplater实例
          const doc = new window.docxtemplater(zip, {
            paragraphLoop: true,
            linebreaks: true,
          });

          // 4、设置数据
          doc.setData({
            Code: "ZLFX202412280001",
            name: "你好啊啊John Doe阿斯顿我是具体措施111你是你好啊啊John Doe阿斯顿我是具体措施111你是你好啊啊John Doe阿斯顿我是具体措施111你是你好啊啊John Doe阿斯顿我是具体措施111你是",
            arr: [
              { name: "第一行", type: "新增", time: "2024-12-23" },
              { name: "第二行", type: "修改", time: "2024-12-23" },
              { name: "第三行", type: "新增", time: "2024-12-23" },
              { name: "第四行", type: "新增", time: "2024-12-23" },
              { name: "第五行", type: "新增", time: "2024-12-23" },
              { name: "第六行", type: "新增", time: "2024-12-23" },
              { name: "第七行", type: "删除", time: "2099-12-23" },
            ],

          });

          try {
            // 5、渲染word
            doc.render();
          } catch (error) {
            console.error('Error rendering the document:', error);
            return;
          }

          // 6、获取渲染后的word
          const output = doc.getZip().generate({ type: 'blob' });

          // 7、下载word
          saveAs(output, 'output.docx');
        })
        .catch(error => console.error('Error loading template:', error));
    });
  </script>
</body>

</html>

3.2 前端生成word文件的样式

生成后的文件样式如下。 图片插入这个地方 官方说是可以,其他的文章也有实现的,但这个地方我没实现。 据说是要用docxtemplater-image-module 这个库

在这里插入图片描述

3.3 总结

优点

  1. 样式可控制

缺点
2. 需要预先设置 word 文件的样式

4、参考链接

  • docxtemplater 语法官方文档
  • html-docx-js GitHub地址

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

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

相关文章

4. grafana(7.5.17)功能菜单简介

点击可以返回home页面 搜索Dashboard 新建按钮&#xff1a;用户创建Dashboard、文件夹。以及导入外部&#xff08;社区&#xff09;Dashboard 用于查看活管理Dashboard&#xff0c;包括home、Manage、playlists、snapshots功能 explore&#xff08;探索&#xff09;&#x…

QT之改变鼠标样式

QT改变鼠标图片 资源路径如下 代码实现 QPixmap customCursorPixmap(":/images/mouse.png");QCursor customCursor(customCursorPixmap);QWidget::setCursor(customCursor); // 可以设置为整个窗口或特定控件QWidget::setCursor(); // 设置为透明光标&#xff0c…

ctfshow web入门 web11-web24

web11 web12 进来浏览网站&#xff0c;底部有一串数字&#xff0c;根据提示可能有用&#xff0c;访问robots.txt&#xff0c;发现禁止访问/admin/&#xff0c;进去看看发现需要输入用户名和密码&#xff0c;刚想爆破就猜对了&#xff0c;用户名是admin&#xff0c;密码是页面下…

大模型开发实战篇7:语音识别-语音转文字

语音识别大模型&#xff0c;是人工智能领域的一项重要技术&#xff0c;它能够将人类的语音转换为文本。近年来&#xff0c;随着深度学习技术的不断发展&#xff0c;语音识别大模型取得了显著的进展&#xff0c;并在各个领域得到了广泛应用。 主流语音识别大模型 目前&#xf…

基于Flask的租房信息可视化系统的设计与实现

【Flask】基于Flask的租房信息可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网的快速发展&#xff0c;租房市场日益繁荣&#xff0c;信息量急剧增加&#xff…

记一次一波三折的众测SRC经历

视频教程和更多福利在我主页简介或专栏里 &#xff08;不懂都可以来问我 专栏找我哦&#xff09; 目录&#xff1a; 前言 波折一&#xff1a;RCE漏洞利用失败 波折二&#xff1a;SQL时间盲注 波折三&#xff1a;寻找管理后台 总结 前言 先谈个人SRC心得体会吧&#xff0c;我虽…

java每日精进 2.13 MySql迁移人大金仓

1.迁移数据库 1. 数据库创建语句 MySQL&#xff1a; CREATE DATABASE dbname; 人大金仓&#xff08;Kingbase&#xff09;&#xff1a; 在人大金仓中&#xff0c;CREATE DATABASE 的语法通常相同&#xff0c;但可能需要特别注意字符集的指定&#xff08;如果涉及到多语言支持…

【单臂路由配置】

【单臂路由配置】 设备接口IP子网网关vlanR1G0/0/1.1192.168.1.254255.255.255.0NAvlan10R1G0/0/1.2192.168.2.254255.255.255.0NAvlan20R1G0/0/1.3192.168.3.254255.255.255.0NAvlan30PC1e0/0/1192.168.1.1255.255.255.0192.168.1.254vlan10PC2e0/0/1192.168.2.1255.255.255.0…

NutUI内网离线部署

文章目录 官网拉取源代码到本地仓库修改源代码打包构建nginx反向代理部署访问内网离线地址 在网上找了一圈没有写NutUI内网离线部署的文档&#xff0c;花了1天时间研究下&#xff0c;终于解决了。 对于有在内网离线使用的小伙伴就可以参考使用了 如果还是不会联系UP主:QQ:10927…

【Linux AnolisOS】关于Docker的一系列问题。尤其是拉取东西时的网络问题,镜像源问题。

AnolisOS 8中使用Docker部署&#xff08;全&#xff09;_anolis安装docker-CSDN博客 从在虚拟机安装龙蜥到安装docker上面这篇文章写的很清晰了&#xff0c;我重点讲述我解决文章里面问题一些的方法。 问题1&#xff1a; docker: Get https://registry-1.docker.io/v2/: net/h…

免费体验,在阿里云平台零门槛调用满血版DeepSeek-R1模型

一、引言 随着人工智能技术的飞速发展&#xff0c;各类AI模型层出不穷。其中&#xff0c;DeepSeek作为一款新兴的推理模型&#xff0c;凭借其强大的技术实力和广泛的应用场景&#xff0c;逐渐在市场中崭露头角。本文将基于阿里云提供的零门槛解决方案&#xff0c;对DeepSeek模…

ARM Linux平台下 OpenCV Camera 实验

一、硬件原理 1. OV2640 1.1 基本功能 OV2640 是一款低功耗、高性能的图像传感器&#xff0c;支持以下功能&#xff1a; 最高分辨率&#xff1a;200 万像素&#xff08;1600x1200&#xff09;。 输出格式&#xff1a;JPEG、YUV、RGB。 内置图像处理功能&#xff1a;自动曝…

论文笔记-WSDM2025-ColdLLM

论文笔记-WSDM2025-Large Language Model Simulator for Cold-Start Recommendation ColdLLM&#xff1a;用于冷启动推荐的大语言模型模拟器摘要1.引言2.前言3.方法3.1整体框架3.1.1行为模拟3.1.2嵌入优化 3.2耦合漏斗ColdLLM3.2.1过滤模拟3.2.2精炼模拟 3.3模拟器训练3.3.1LLM…

后端开发:开启技术世界的新大门

在互联网的广阔天地中&#xff0c;后端开发宛如一座大厦的基石&#xff0c;虽不直接与用户 “面对面” 交流&#xff0c;却默默地支撑着整个互联网产品的稳定运行。它是服务器端编程的核心领域&#xff0c;负责处理数据、执行业务逻辑以及与数据库和其他后端服务进行交互。在当…

如何查看java的字节码文件?javap?能用IDEA吗?

编译指令&#xff1a; javac YourProject.java 查看字节码文件的指令&#xff1a; javap -c -l YourProject.class 不添加-c指令就不会显示字节码文件&#xff1a; 不添加 -l 就不会显示源代码和字节码文件的对应关系&#xff1a; 添加-l之后多出来这些&#xff1a; IDEA不太…

Linux-GlusterFS配置

文章目录 GlusterFS配置 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Linux专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年02月18日19点21分 GlusterFS配置 1、分区操作 fdisk -l #查看本地磁盘 fdisk /dev/vdb #对/dev/vdb进…

[C语言]指针进阶压轴题

下面代码打印结果是什么&#xff1f; #include<stdio.h> int main() {char* c[] { "ENTER","NEW","POINT","FIRST" };char** cp[] { c 3,c 2,c 1,c };char*** cpp cp;printf("%s\n", **cpp);printf("%s\n…

DeepSeek 助力 Vue 开发:打造丝滑的点击动画(Click Animations)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

SpringBoot论坛网站 – 功能详解与部署教程

项目概述 《SpringBoot的论坛网站》是一个基于SpringBoot框架开发的现代化论坛平台&#xff0c;旨在为用户提供一个便捷的交流空间。该项目不仅功能丰富&#xff0c;还具备良好的扩展性和易用性&#xff0c;适合用于学习、分享和讨论各类话题。以下是项目的核心功能模块和部署…

SpringSecurity初始化的本质

一、对SpringSecurity初始化的几个疑问 通过前面第一次请求访问的分析我们明白了一个请求就来后的具体处理流程 对于一个请求到来后会通过FilterChainProxy来匹配一个对应的过滤器链来处理该请求。那么这里我们就有几个疑惑。 FilterChainProxy什么时候创建的?过滤器链和对应的…