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

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

相关文章:

  • 引用是什么?在不同语言中的应用?尤其是Java中的应用?
  • Q - learning 算法是什么
  • Comsol 二维Voronoi泰森多边形结构振动传输特性
  • C语言进阶——6-C语言文件操作
  • 【算法精练】背包问题(01背包问题)
  • Git使用[同一电脑多个账户ssh-key的管理]
  • C++17 中的 std::uncaught_exceptions:异常处理的新利器
  • MVCC(多版本并发控制)机制讲解
  • 单细胞转录组画小提琴VlnPlot只显示需要类型细胞
  • llama.cpp将sensor格式的大模型转化为gguf格式
  • 「新」AI Coding(Agent) 的一点总结和看法
  • VisionTransformer(ViT)与CNN卷积神经网络的对比
  • 【Linux】多线程 -> 线程互斥与死锁
  • java.2.19
  • [STM32 - 野火] - - - 固件库学习笔记 - - - 十六.在SRAM中调试代码
  • GITHUB的若干操作
  • C# 背景 透明 抗锯齿 (效果完美)
  • 蓝桥杯备赛1-2合法日期
  • 深入浅出Spring Security:从入门到实战
  • 2.19学习记录
  • 第78届戛纳电影节开幕,罗伯特·德尼罗领取终身成就奖
  • 颜福庆与顾临的争论:1930年代在中国维持一家医学院要花多少钱
  • 横跨万里穿越百年,《受到召唤·敦煌》中张艺兴一人分饰两角
  • 足球少年郎7月试锋芒,明日之星冠军杯构建顶级青少年赛事
  • 三亚通报救护车省外拉警报器开道旅游:违规违法,责令公司停业整顿
  • 外国游客“在华扫货”热:“带空箱子到中国!”