通过js将html转换为word文档

3,381 阅读1分钟

安装依赖包

  • npm i html-docx-js -S
    • 对html进行编码格式转换,这样word才能识别html结构的内容
    • 没有转码就进行保存,对于word来说是不能识别的,但是wps能够识别
  • npm i file-saver -S
    • 将html内容保存为word文档

案例

<template>
  <div class="app">
    <button @click="exportFile">导出</button>
    <div class="box" ref="box">
      <div class="acticle">
        <h1>{{ article.title }}</h1>
        <div class="content">
          <template v-for="(i, idx) in article.content">
            <template v-if="i.type === 'content'">
              <p :key="idx" v-html="i.text"></p>
            </template>
            <template v-else-if="i.type === 'img'">
              <!-- 通过测试,发现通过css设置img的大小无效,只能通过属性的方式 -->
              <img width="300" :src="i.text" alt="" :key="idx" />
            </template>
          </template>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import htmlDocx from "html-docx-js/dist/html-docx";
import saveAs from "file-saver";
export default {
  name: "APP",
  data() {
    return {
      article: {
        title: "失业后像个晕头转向的废物",
        content: [
          {
            type: "content",
            text: "<span class='xiaoshi'>失业后</span>,我的发条断裂,<span class='bold'>周一到周五</span>,找不到目的地,为了不让自己像个晕头转向的废物,我打算至少让自己穿得像模像样一点。周一的早晨,我衣冠整洁,着皮衣,穿得像个杀手,然后出门。",
          },
          {
            type: "content",
            text: "出门不是为了寻找猎物,出门只是一种仪式,如果我待在家里,我就会下陷,随着沙发一路陷下去,陷进一个地狱之中。",
          },
          {
            type: "img",
            text: "http://img.99wenzhangwang.com/d/file/202112/meocuvkvcrm.jpg",
          },
          { type: "content", text: "失业记" },
          {
            type: "content",
            text: "早晨我来到肯德基,并不是为了进食,他们的东西太难吃了,连饲料也算不上,我每次都来得过分的晚,于是只好为了所剩无几的早晨与人争抢。",
          },
          { type: "content", text: "我先来的。" },
          { type: "content", text: "我先来的。" },
          { type: "content", text: "你没有排队。" },
          {
            type: "img",
            text: "http://img.99wenzhangwang.com/d/file/202112/aaol0vab5hg.jpg",
          },
          { type: "content", text: "失业记" },
          {
            type: "content",
            text: "中年妇女霸道的横在前头,向我投递一个原子弹般的眼神,这让我怀疑自己还身处于地铁之中,坐地铁上班这件事让人充分领悟到了丛林社会的残酷性,大家你争我抢,为了不迟到,为了不扣绩效,而去做一些失去做人底线的事情。",
          },
          {
            type: "img",
            text: "http://img.99wenzhangwang.com/d/file/202112/miymotiiz53.jpg",
          },
          { type: "content", text: "失业记" },
          {
            type: "content",
            text: "终于,我端着盘子坐下来,和其他无所事事的几十个人坐在一起,它们有的人和我一样,假模假样的拿起书本,装成好好学习的样子,而有些人则一直坐着,眼神空茫,好像在设想一些不确定的未来,而有的人则一直百无聊赖的玩弄手机,像阿乙笔下无处可去的犯罪分子,总之,我们这样,一坐一上午,要是没有中午饭的发号施令,我们简直可以坐到天荒地老。",
          },
          {
            type: "content",
            text: "这和上班的时候没有两样,我们都听命于午饭的指挥,只要午饭站起来,撩撩裙摆,告诉我们,同志们,你们可以出发去吃午饭了,我们就找到了一天中第一个热情洋溢的兴奋点,吃什么的苦恼只是余兴节目。",
          },
          {
            type: "img",
            text: "http://img.99wenzhangwang.com/d/file/202112/emkh11brtu5.jpg",
          },
        ],
      },
    };
  },
  methods: {
    exportFile() {
      // 内容样式
      const cssStyle = `
            <style>
                .content p {
                    text-indent: 2em;
                }
                .content p .bold {
                    font-weight: bold;
                    color: red;
                }
                .content p .xiaoshi {
                    /* 小四字体样式 */
                    /* 由于px单位,是一个相对单位,在不同屏幕中大小会有差别,所以在设置字体样式采用固定单位*/
                    font-size: 12pt;
                }
                .content img {
                    border-radius: 5px;
                    margin-left: 2em;
                }
            </style>
        `;
      // 获取内容的html结构
      const boxHtml = this.$refs["box"].innerHTML;
      //构建一个word文档
      const articleContent = `
        <!doctype html>
        <html>
            <head>${cssStyle}</head>
            <body>${boxHtml}</body>
        </html>
      `;
      //将html内容进行转码
      const converted = htmlDocx.asBlob(articleContent);
      //导出html形成word文档
      saveAs(converted, `${Date.now()}.docx`);
    },
  },
};
</script>

//通过css设置标签样式,能够方便的在导出html内容时直接复制粘贴使用
<style lang="css">
.content p {
  text-indent: 2em;
}
.content p .bold {
  font-weight: bold;
  color: red;
}
.content p .xiaoshi {
  /* 小四字体样式 */
  font-size: 12pt;
}
.content img {
  border-radius: 5px;
  margin-left: 2em;
}
</style>

效果

image.png