Vue中前端导出word文件

这篇具有很好参考价值的文章主要介绍了Vue中前端导出word文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

很多时候在工作中会碰到完全由前端导出word文件的需求,因此特地记录一下比较常用的几种方式。

一、提供一个word模板

该方法提供一个word模板文件,数据通过参数替换的方式传入word文件中,灵活性较差,适用于简单的文件导出。需要依赖:docxtemplater、file-saver、jszip-utils、pizzip

vue导出word,前端,vue.js,word,前端开发,免费源码

javascript
复制代码
import Docxtemplater from "docxtemplater";
import { saveAs } from "file-saver";
import JSZipUtils from "jszip-utils";
import PizZip from "pizzip";

export function downloadWithTemplate(path, data, fileName) {
  JSZipUtils.getBinaryContent(path, (error, content) => {
    if (error) throw error;

    const zip = new PizZip(content);
    const doc = new Docxtemplater().loadZip(zip);
    doc.setData({
      ...data.form,
      // 循环项参数
      list: data.list,
      outsideList: data.outsideList,
    });

    try {
      doc.render();
    } catch (error) {
      const e = {
        message: error.message,
        name: error.name,
        stack: error.stack,
        properties: error.properties,
      };
      ElMessage.error("文件格式有误!");
      throw error;
    }
    const out = doc.getZip().generate({
      type: "blob",
      mimeType:
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    });
    saveAs(out, fileName);
  });
}

let data = {
    form: {
      title: "这是word标题",
      test: "这是表单1的数据",
      test1: "111",
      test2: 222,
      test3: 333,
    },
    outsideList: [
      {
        list: [
          {
            index: 0,
            table: "表格第一项",
            table1: "表格第二项",
            table2: "表格第三项",
          },
          {
            index: 1,
            table: "表格第一项",
            table1: "表格第二项",
            table2: "表格第三项",
          },
        ],
      },
      {
        list: [
          {
            index: 0,
            table: "表格第一项",
            table1: "表格第二项",
            table2: "表格第三项",
          },
          {
            index: 1,
            table: "表格第一项",
            table1: "表格第二项",
            table2: "表格第三项",
          },
        ],
      },
    ],
  };
  
  downloadWithTemplate("template.docx", data, "模板word.docx")
  

调用downloadWithTemplate方法即可导出如下文件: vue导出word,前端,vue.js,word,前端开发,免费源码
注: 上述方法中的path参数为你在vue项目中存放公共文件的位置,在vue2中为static文件夹下,在vue3中为public文件夹下。

二、根据html代码转换为word文件(推荐)

顾名思义,这个方法就是将我们在页面上书写的html代码直接转换成word文件,这也是我最推荐的一种方法,因为大部分的样式可控,且毕竟是我们较为熟悉的方式。需要插件: html-docx-js-typescript、file-saver。

xml
复制代码
import { saveAs } from "file-saver";
import { asBlob } from "html-docx-js-typescript";

 export function downloadWordWithHtmlString(html, name) {
  let htmlString = `
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head>
  <body>
    ${html}
  </body>
  </html>
  `;
  asBlob(htmlString).then((data) => {
    saveAs(data, `${name}.docx`);
  });
}
  `

使用案例:

ini
复制代码
<div ref="word">
  <h3 style="text-align: center">word标题</h3>
  <table
    border="1"
    cellspacing="0"
    width="600"
    style="font-size: 12px; color: #000; text-align: center"
  >
    <tr height="50">
      <td width="100">1111</td>
      <td widt="200" colspan="2">合并单元格</td>
      <td width="300">最长的一项</td>
    </tr>
    <tr height="100">
      <td width="100">222</td>
      <td width="100">222</td>
      <td width="100">222</td>
      <td width="100">222</td>
    </tr>
  </table>
  <table width="600" border="1" cellspacing="0">
    <tr height="50">
      <td width="100">1111</td>
      <td rowspan="3">合并包括此行在内的下面三行</td>
    </tr>
    <tr height="100">
      <td>222</td>
    </tr>
    <tr height="300">
      <td>3333</td>
    </tr>
    <tr>
      <td>50</td>
    </tr>
  </table>
</div>

let word = ref(null);
downloadWordWithHtmlString(word.value.innerHTML, 'html字符串word.docx');

生成的word文件可以看到效果和在网页中的html代码一样:

vue导出word,前端,vue.js,word,前端开发,免费源码
另外需要注意的是,若是需要在word中添加分页符,在需要分页的内容处添加CSS属性page-break-before即可。此时在浏览器上打印出innerHTML值会发现:

vue导出word,前端,vue.js,word,前端开发,免费源码

mdn上介绍page-break-before属性已经被break-before属性替代,但是经过我实际测试发现当html字符串是page-break: always时生成的word文件没有分页效果,反而是将其替换回page-break-before后实现了分页效果。若有大神知道这是什么问题还望不吝赐教。 因此需要在downloadWordWithHtmlString方法中添加一句正则: htmlString = htmlString.replace( /break-(after|before): page/g, "page-break-$1: always;" );,此时就能实现分页效果。

三、使用docx插件

第二种方法有个很致命的问题就是它无法在生成的word文件中添加图片页眉,我搜遍了npm也只找到一个能添加文字页眉的插件: html-docx-ts要想实现这个需求,就需要用到docx插件。 docx官网的介绍是"Easily generate and modify .docx files with JS/TS. Works for Node and on the Browser.",意味着是一个专门用于生成word和修改word的文件。该插件就需要一个一个去配置你要生成的项,然后组合成一个word。一个简单的案例是:

css
复制代码
import {
  Document,
  Paragraph,
  Header,
  TextRun,
  Table,
  TableRow,
  TableCell,
  WidthType,
  Packer,
} from "docx";
import { saveAs } from "file-saver";

const document = new Document({
    sections: [
      {
        headers: {
          default: new Header({
            children: [new Paragraph("我是页眉")],
          }),
        },
        children: [
          new Paragraph({
            children: [
              new TextRun({
                text: "我是文字内容",
                size: 16,
                bold: true,
              }),
            ],
          }),
          new Table({
            columnWidths: [1500, 7500],
            rows: [
              new TableRow({
                children: [
                  new TableCell({
                    width: {
                      size: 1500,
                      type: WidthType.DXA,
                    },
                    children: [
                      new Paragraph({
                        alignment: "center",
                        children: [
                          new TextRun({
                            text: "测试",
                            size: 24,
                            font: {
                              name: "楷体",
                            },
                          }),
                        ],
                      }),
                    ],
                  }),
                ],
              }),
            ],
          }),
        ],
      },
    ],
  });
  
  Packer.toBlob(document).then((blob) => {
    saveAs(blob, "test.docx");
  });

导出的word文件形式为:

vue导出word,前端,vue.js,word,前端开发,免费源码
下面是我个人总结的比较常见能用到的功能和配置项:

css
复制代码
// 导出文字
1.new Paragraph(text) -> 默认字体样式: 宋体,五号字
2.new Paragraph({
    children: [
      new TextRun({
        text: "我是文字内容",
        size: 16, // 对应word中的字体大小8
        bold: true, // 是否加粗
        underline: {
          type: UnderlineType.SINGLE,
          color: "#2e32ee",
        }, // 下划线类型及颜色
        font: {
          name: "仿宋", // 只要是word中有的字体类型都可以生效
        },
      }),
    ],
    indent: {
      left: 100,
    }, // 离左边距离 类似于margin-left
    spacing: {
      before: 150,
      after: 200,
    }, // 离上边和下边的距离 类似于margin-top/bottom
    alignment: "center", // 对齐方式
    pageBreakBefore: true, // 是否在这段文字前加入分页符
  })
  
 // 导出表格
new Table({
  columnWidths: [1500, 7500], // 表示单行有几项,总宽度是9000,对应宽度;
  rows: [
    new TableRow({
      children: [
        new TableCell({
          width: {
            size: 1500, // 需与columnWidths的第一项对应
            type: WidthType.DXA, // 官网的介绍是Value is in twentieths of a point
            // 因为表格的总宽度是以twips(每英寸的1/20)为单位进行计算的
          },
          children: [
            new Paragraph({
              alignment: "center",
              children: [
                new TextRun({
                  text: "测试",
                  size: 24,
                  font: {
                    name: "楷体",
                  },
                }),
              ],
            }),
          ],
        }),
        new TableCell({
          width: {
            size: 7500,
            type: WidthType.DXA,
          },
          children: [
            new Paragraph('ccc'),
          ],
          margins: {
            top: 500,
            bottom: 500,
            left: 500
          } // 类似于单元格内容的padding
        }),
      ],
    }),
  ],
})

// 导出图片
new Paragraph({
  children: [
    new ImageRun({
      data: "base64", // 图片需转成base64的形式
      transformation: {
        width: 100,
        height: 30,
      }, // 图片宽高
    }),
  ],
})

// 设置页眉页脚
headers: {
  default: new Header({
    children: [new Paragraph("我是页眉")],
  }),
},
footers: {
  default: new Footer({
    children: [new Paragraph("我是页脚")],
  }),
}

下面是一个完整的使用案例:

css
复制代码
const document = new Document({
  sections: [
    {
      headers: {
        default: new Header({
          children: [
            new Paragraph({
              children: [
                new ImageRun({
                  data: "data:image/jpeg;base64,...",
                  transformation: {
                    width: 150,
                    height: 150,
                  },
                }),
              ],
            }),
          ],
        }),
      },
      footers: {
        default: new Footer({
          children: [new Paragraph("我是页脚")],
        }),
      },
      children: [
         new Paragraph("第一行直接默认形式"),
         new Paragraph({
           children: [
             new TextRun({
               text: "下一页",
             }),
           ],
           pageBreakBefore: true,
         }),
         new Table({
           columnWidths: [1500, 7500],
           rows: [
             new TableRow({
               children: [
                 new TableCell({
                   width: {
                     size: 1500,
                     type: WidthType.DXA,
                   },
                   children: [
                     new Paragraph({
                       alignment: "center",
                       children: [
                         new TextRun({
                           text: "测试",
                           size: 24,
                           font: {
                             name: "楷体",
                           },
                         }),
                       ],
                     }),
                   ],
                 }),
                 new TableCell({
                   width: {
                     size: 7500,
                     type: WidthType.DXA,
                   },
                   children: [
                     new Paragraph({
                       children: [
                         new ImageRun({
                           data: "data:image/jpeg;base64,...",
                           transformation: {
                             width: 150,
                             height: 150,
                           },
                         }),
                       ],
                     }),
                   ],
                   margins: {
                     top: 500,
                     bottom: 500,
                    left: 500,
                  },
                }),
              ],
            }),
          ],
        }),
      ],
    },
  ],
});

Packer.toBlob(document).then((blob) => {
  saveAs(blob, "test.docx");
});

此时导出的word文件如下:

vue导出word,前端,vue.js,word,前端开发,免费源码
学习更多vue开发知识请下载​​CRMEB开源商城​​附件学习文章来源地址https://www.toymoban.com/news/detail-752407.html

到了这里,关于Vue中前端导出word文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue若依导出word文件,简单的实现

    首先前端导包,注意exportDocx的导包位置要修改成你自己的 然后新建一个测试按钮 接下来是js文件 然后将下面这个docutil.js文件复制到项目中,我是复制在utils/docUtil中 最后新建一个word模板文件,保存的格式要是docx才行哦 例如: 只要数据是集合,就得是{#list} 开头{/list}结尾 如果还有

    2024年02月11日
    浏览(33)
  • vue element ui 导出word文件方法

    1首先安装导出word需要的依赖 -- 安装 docxtemplater npm install docxtemplater pizzip  --save   -- 安装 jszip-utils npm install jszip-utils --save   -- 安装 jszip npm install jszip --save   -- 安装 FileSaver npm install file-saver --save 2.然后在需要导入的页面引入 import docxtemplater from \\\'docxtemplater\\\' import PizZip from \\\'p

    2024年02月10日
    浏览(31)
  • 前端导出文件 | fileSaver.js源码阅读

    了解fileSaver.js核心实现 自己动手实现简易导出功能 在Vue中如何使用文件 1、fileSave.js库地址:https://github.com/eligrey/FileSaver.js 2、src目录结构 3、在浏览器打开test.html,点击下载按钮,进行代码调试 进入saveAs函数后可按下一步进行调试,查看代码执行过程。 fileSaver.js核心代码实

    2024年02月05日
    浏览(49)
  • vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法

    由于vue为单页面项目,通过控制组件局部渲染,main.js是整个项目唯一的入口,整个项目都在一个index.html外壳中。 若项目过大,会造成单页面负载过重;同时,多页面利于模块独立部署。 如果项目中不同的页面需要不同的main.js和App.vue这样就需要配置多个入口了。 要单独将页

    2024年01月22日
    浏览(90)
  • Vue3——html-doc-ja(html导出为word的js库)

    官方地址  html-doc-js - npm 在 exportWord 方法执行时,将页面中mjx-assistive-mml 节点清除即可,如下图所示

    2024年04月14日
    浏览(41)
  • Vue前端表格导出Excel文件

    分享一个Vue前端导出Excel文件的方法。记录学习! 功能需求 :将表格的全部数据导出Excel格式的文件 前端 :Vue3+Element-Plus 这个导出方法全部为前端操作,后端只需要传入表格数据到前端即可(基础的多表查询,用的内连接) 2.1 核心方法 将这个导出方法单独封装出来,带一

    2023年04月24日
    浏览(91)
  • 前端结合xlsx.js+xlsx-style.js源码实现自定义excel文件导出

          js-xlsx是一款非常方便的只需要纯JS即可读取和导出excel的工具库,功能强大,支持格式众多,支持xls、xlsx、ods(一种OpenOffice专有表格文件格式)等十几种格式。本文全部都是以xlsx格式为例。 创建一个excel会经历以下过程: 创建一个工作薄 创建一个sheet 创建表格行列等

    2024年03月10日
    浏览(73)
  • 前端导出word文件的多种方式、前端导出excel文件

    先看效果: 这是页面中的table 这是导出后的效果: 需要的依赖: npm 自行安装,需要看官网的具体参数自行去github上面找对应的参数 具体代码:(先看word模板,在看代码,word中的变量和代码中 doc.setData() 是一一对应的) 包依赖: 代码 导出效果: 需要的依赖: node-xlsx 代码

    2024年03月24日
    浏览(100)
  • VUE前端导出文件之file-saver插件

    如果需要保存大于 blob 大小限制的非常大的文件,或者没有 足够的 RAM,然后看看更高级的 StreamSaver.js,它可以通过新的流 API 的强大功能将数据直接异步保存到硬盘驱动器。那将有 支持进度、取消和知道何时完成编写; FileSaver.js 是在客户端保存文件的解决方案,非常适合在

    2024年04月10日
    浏览(39)
  • vue+xlsx实现前端模版下载、导入和导出excel文件

    产品需求:后端不想写下载,导入和导出的接口,让我们前端自己实现。 这里我们就可以用xlsx插件来实现,我们不多说了,先放一下实现的图片,下面我们分别把模版下载、导入和导出的代码放上来,想用的话,直接复制粘贴即可! 模版下载图片 导出图片: 好了,下面我

    2024年02月13日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包