当前位置: 首页 > article >正文

【插件】前端生成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地址

http://www.kler.cn/a/553732.html

相关文章:

  • EasyRTC:开启智能硬件与全平台互动新时代
  • CentOS建立ssh免密连接(含流程剖析)
  • 在Unity中用简单工厂模式模拟原神中的元素反应
  • TypeScript学习:初学
  • hbuilderx 小程序分包_微信小程序关于分包【收藏版】
  • 【Java】Enum类的常用方法、实现接口及其实际应用
  • 小胡说技书博客分类(部分目录):服务治理、数据治理与安全治理对比表格
  • DeepSeek与ChatGPT:AI语言模型的全面技术解析与对比
  • Matlab离线安装硬件支持包的方法
  • 68页PDF | 数据安全总体解决方案:从数据管理方法论到落地实践的全方位指南(附下载)
  • LLaVA-CoT: Let Vision Language Models Reason Step-by-Step论文解读
  • 基于知识图谱的问答系统:后端Python+Flask,数据库Neo4j,前端Vue3(提供源码)
  • AI赋能传统系统:Spring AI Alibaba如何用大模型重构机票预订系统?
  • SpringBoot启动java.nio.charset.MalformedInputException: Input length = 1报错的解决方案
  • Function.prototype.__proto__==Object.prototype
  • 文心一言,下一代模型开源
  • Android Hal AIDL 简介 (一)
  • 什么是Ajax
  • AI 安全时代:SDL与大模型结合的“王炸组合”——技术落地与实战指南
  • 动静态链接与加载