前端HTML转word文档,绝对有效!!!

2024.4.19 更新日志:有小伙伴私信我element-ui等ui插件等复杂样式无法转换生成,考虑到

html-docx-js本身不支持大多c3样式及标签,先提供解决方法将dom转成图片插入文档中,只需要用标签盒子 包裹住 你需要生成的dom模块,给标签盒子添加类目标识,配置项中传入 drawCanvas:[' .btn' ] ,就可以生成 具体效果图结尾有。


2024.3.11 更新日志 :允许使用class标签在html模版中使用 此前只支持行内标签修改样式 过于繁琐与不便 ,配置项中加入 className: "xxx", 当前模版的class类明即可识别使用


公司有业务需求 需要将前端页面一键导出word模版

后来找了半天只找到一个16年的插件html-docx-js(膜拜大神,但是已经无人维护了) ,使用后踩了许多坑,因为js版本兼容问题,运行都报错使用了with() 先版本不兼容,使用也比较繁琐,

最无法容忍的是如果是使用的在线图片还有跨域问题导致图片无法导出!!!

所以直接做了些优化处理 主要是对超时 错误图片处理 可以传入导出图片超时时间等等系列问题坑!!!已封装成傻瓜式一键导出插件,小伙伴可以放心食用,目前已投入公司项目中使用。

xh-htmlword

使用方法

npm install xh-htmlword

<template>
  <div class="export-box" style="width: 565pt">
    <div id="main1"></div>
    <p style="text-align: center">
      <span
        style="
          font-family: 宋体;
          font-weight: bold;
          color: rgb(0, 0, 0);
          min-height: 16pt;
          font-size: 16pt;
        "
        >深水汴北配套管网运维日报表</span
      >
    </p>
    <table
      style="width: 565pt; border-collapse: collapse; border: 1px solid #dddddd"
    >
      <colgroup>
        <col style="width: 89.65pt" />
        <col style="width: 44.05pt" />
        <col style="width: 121.5pt" />
        <col style="width: 103.85pt" />
        <col style="width: 73.3pt" />
        <col style="width: 106.3pt" />
      </colgroup>
      <!-- 头部 -->
      <tr
        v-for="(item, index) in data.head"
        :key="index"
        style="border: 1px solid #cccccc; height: 25.5pt"
      >
        <td
          v-for="(item2, index) in item"
          :key="index"
          style="padding-left: 5.4pt; border: 1px solid #cccccc"
          :style="{ width: item2.width }"
          :colspan="index % 2 == 0 ? 2 : 1"
        >
          <span
            style="
              font-weight: bold;
              color: #595959;
              font-size: 9pt;
              margin-right: 3pt;
            "
          >
            {{ item2.title }}</span
          >
          <span style="color: #595959; font-size: 9pt">
            {{ item2.label }}
          </span>
        </td>
      </tr>
      <!-- 到岗人员 -->
      <tr style="border: 1px solid #cccccc; height: 25.5pt">
        <td colspan="6" style="padding-left: 5.4pt; border: 1px solid #cccccc">
          <span
            style="
              font-weight: bold;
              color: #595959;
              font-size: 9pt;
              margin-right: 3pt;
            "
          >
            到岗人员:</span
          >
 
          <span
            v-for="(item, index) in data.personnel"
            :key="index"
            style="color: #595959; font-size: 9pt"
          >
            <span v-if="index !== 0"> &nbsp;</span>
            <span>{{ item.title }}</span>
            <span>
              {{ item.label }}
            </span>
          </span>
        </td>
      </tr>
      <!-- 标准化执行情况 -->
      <tr style="border: 1px solid #cccccc; height: 25.5pt">
        <td colspan="6" style="padding-left: 5.4pt; border: 1px solid #cccccc">
          <span
            style="
              font-weight: bold;
              color: #595959;
              font-size: 9pt;
              margin-right: 3pt;
            "
          >
            标准化执行情况:</span
          >
          <span
            v-for="(item, index) in executionList"
            :key="index"
            style="color: #595959; font-size: 9pt"
          >
            <span v-if="index !== 0">&nbsp;&nbsp;&nbsp;</span>
            <span>{{ data.execution == index ? "√" : "□" }}</span>
            <span>
              {{ item }}
            </span>
          </span>
        </td>
      </tr>
      <!-- 巡检记录 -->
      <tr style="border: 1px solid #cccccc; height: 36pt">
        <td
          colspan="6"
          style="
            text-align: center;
            border: 1px solid #cccccc;
            background-color: #f1f1f1;
            color: rgb(89, 89, 89);
            font-size: 14pt;
            letter-spacing: 1pt;
          "
        >
          巡检记录
        </td>
      </tr>
      <tr>
        <td
          colspan="6"
          style="
            text-align: center;
            border: 1px solid #cccccc;
            background-color: #f1f1f1;
            color: rgb(89, 89, 89);
            font-size: 14pt;
            letter-spacing: 1pt;
          "
        >
          <img
            src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage109.360doc.com%2FDownloadImg%2F2021%2F04%2F0713%2F219519055_1_20210407012803425&refer=http%3A%2F%2Fimage109.360doc.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1716081866&t=af941e4f60f743e1081f7cda8fcfb299"
            width="565pt"
            height="200pt"
          />
        </td>
      </tr>
    </table>
 
    <div class="btn">
      <el-progress :percentage="50" />
      <el-progress :percentage="100" :format="format" />
      <el-progress :percentage="100" status="success" />
      <el-progress :percentage="100" status="warning" />
      <el-progress :percentage="50" status="exception" />
 
      <el-steps style="max-width: 600px" :active="0" finish-status="success">
        <el-step title="Step 1" />
        <el-step title="Step 2" />
        <el-step title="Step 3" />
      </el-steps>
    </div>
  </div>
 
  <button @click="handleExport">导出</button>
</template>
 
<script setup>
import { onMounted, nextTick } from "vue";
import handleExportWord from "xh-htmlword";
 
// 标准化执行情况
const executionList = ["优秀", "良好", "中等", "差"];
 
// 巡检记录
const data = {
  head: [
    [
      { title: "作业日期:", label: "2024年01月25日", width: "150pt" },
      { title: "填表人:", label: "吴宇、白阳", width: "110pt" },
      {
        title: "运维单位:",
        label: "安徽中益达管道疏通有限公司",
        width: "200pt",
      },
      { title: "天气:", label: "多云(24°C)", width: "120pt" },
    ],
    [
      {
        title: "现场负责人:",
        label: "吴宇",
        width: "150pt",
      },
      {
        title: "手机号码:",
        label: "13112345678",
        width: "110pt",
      },
      {
        title: "项目负责人:",
        label: "吴宇",
        width: "205pt",
      },
      {
        title: "手机号码:",
        label: "13198765432",
        width: "120pt",
      },
    ],
  ],
  personnel: [
    {
      title: "安全员:",
      label: "1人",
    },
    {
      title: "监护人员:",
      label: "1人",
    },
    {
      title: "施工人员:",
      label: "3人",
    },
    {
      title: "巡查人员:",
      label: "2人",
    },
    {
      title: "潜水员:",
      label: "1人",
    },
    {
      title: "有限空间作业人员:",
      label: "1人",
    },
  ],
  execution: 1,
};
 
const handleExport = () => {
  // dom:需要渲染的html父盒子标签 , 类型:string 例如 id/class
  //  fileName:文件名称 类型:string
  //  timeOut:设置导出图片加载 超时时间 默认值 5000  (5s)
  //  callBack:导出成功回调函数
  //  options:配置项  类型:object 例如可传 {left:1440,right:1440} 控制页边距
  //  defultImg: 错误或者超时图片 默认图片地址 类型:string
  //  className:当前组件的class属性名标识 类型:string  配置此项后可以在标签写入class样式
  //  drawCanvas:当当前页面有比较复杂的样式或组件(element-ui等) 页面中可以用样式标签将它包裹起来然后将标签 传入drawCanvas数组中 开启转换
  handleExportWord({
    dom: ".export-box",
    fileName: "托尔斯泰222",
    drawCanvas: [".btn"],
  });
};
</script>

导出效果如下:

可以看到了element UI的组件也一起导出在最下方,项目是采用的vue3+vite,实际中vue2我试了也是没问题的,插件注意事项和使用方法可以去xh-htmlword查看,如果有使用疑惑或问题可以加我QQ:1031945252 交流联系,共同进步

注意:如果是使用的vue2版本,报了以下错误:

一定要在vue.config.js中加上配置项:

会转译node_modules中的包,解决报错!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
前端HTML换为Word文档可以使用JavaScript库docx.js。这个库可以让你在前端创建Word文档,支持添加文本、表格、图像、列表等元素,并将其导出为.docx文件。 以下是使用docx.js将HTML换为Word文档的步骤: 1. 安装docx.js库 ``` npm install docx ``` 2. 在HTML里创建文本、表格、图像等元素 ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>HTML to Word</title> </head> <body> <h1>HTML to Word</h1> <p>This is a paragraph.</p> <ul> <li>List item 1</li> <li>List item 2</li> <li>List item 3</li> </ul> <table> <tr> <th>Header 1</th> <th>Header 2</th> </tr> <tr> <td>Row 1, Column 1</td> <td>Row 1, Column 2</td> </tr> <tr> <td>Row 2, Column 1</td> <td>Row 2, Column 2</td> </tr> </table> <img src="image.jpg" alt="Image"> </body> </html> ``` 3. 使用docx.js创建文档并添加元素 ``` const docx = require('docx'); const doc = new docx.Document(); const paragraph = new docx.Paragraph('This is a paragraph.'); const list = new docx.NumberedAbstract({ levels: [ { level: 0, format: 'decimal', text: '%1.', alignment: docx.AlignmentType.LEFT, }, ], }); list.addItem('List item 1'); list.addItem('List item 2'); list.addItem('List item 3'); const table = new docx.Table({ rows: [ new docx.TableRow({ children: [ new docx.TableCell({ children: [new docx.Paragraph('Header 1')] }), new docx.TableCell({ children: [new docx.Paragraph('Header 2')] }), ], }), new docx.TableRow({ children: [ new docx.TableCell({ children: [new docx.Paragraph('Row 1, Column 1')] }), new docx.TableCell({ children: [new docx.Paragraph('Row 1, Column 2')] }), ], }), new docx.TableRow({ children: [ new docx.TableCell({ children: [new docx.Paragraph('Row 2, Column 1')] }), new docx.TableCell({ children: [new docx.Paragraph('Row 2, Column 2')] }), ], }), ], }); const image = docx.Media.addImage(doc, fs.readFileSync('image.jpg')); doc.addParagraph(new docx.Paragraph('HTML to Word')); doc.addParagraph(paragraph); doc.addParagraph(new docx.Paragraph(list)); doc.addParagraph(new docx.Paragraph(table)); doc.addParagraph(new docx.Paragraph(image)); ``` 4. 将文档导出为.docx文件 ``` const fs = require('fs'); const packer = new docx.Packer(); packer.toBuffer(doc).then((buffer) => { fs.writeFileSync('document.docx', buffer); }); ``` 以上是使用docx.js将HTML换为Word文档的步骤。需要注意的是,docx.js库还有其他的功能和选项,可以根据具体需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值