本文主要参考了:
博主:芊赋予翔

https://blog.csdn.net/weixin_44956861/article/details/105029161
https://blog.csdn.net/weixin_44956861/article/details/101765177

两篇文章,十分感谢,也希望,这样实质有用能够解决问题的文章能够帮助到更多人。

先看看效果:

网页部分:在这里插入图片描述

复杂的多级表格

导出结果:
在这里插入图片描述

方法内容主要分为一下几点:

1.(这里是我对docxtemplater的吐槽,不想看可以跳过1,直接去2.被折磨了好久,实在是忍不住,包容一下)不需要像其他方法如 docxtemplater 需要弄复杂的word模板,关于docxtemplater方法的主要使用方法相关链接如下:

vue导出Word文件(模板导出)
该方法使用依赖的主页
该方法的word模板的demo主页
还有这个方法不用考虑下载 docxtemplater-html-module 这个包了,当你

npm install --save docxtemplater-html-module

会显示

npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.com/docxtemplater-html-module - Not found

因为这个 docxtemplater-html-module付费下载的,就是要钱的 所以,这条路遇见了复杂的页面导出基本上是走不通,像上面这种表格。至少我研究了很久没有研究透怎么写它的word模板和相关的js函数。

2.说回mhtml-to-word这个方法的需要的第三方依赖不多,主要是:

npm install mhtml-to-word
npm install file-saver

3.使用方法也很简单:

import { exportWord } from 'mhtml-to-word'
import { saveAs } from 'file-saver'

4.当然你还需要将当前页面的html代码转换成字符串,主要靠三个函数:

函数一:

export function getModelHtml(mhtml,style){
			return `
				Content-Type: text/html; charset="utf-8"
					<!DOCTYPE html>
					<html>
					<head>
					<style>
						${style}
					</style>
					</head>
					<body>
						${mhtml}
					</body>
					</html>
				`
		},

函数二:

export function getHtml(dom) {
    let _dom = dom || document;

    var canvass = _dom.querySelectorAll('canvas');
    var imgRepalce = _dom.querySelectorAll('.imgRepalce');
    let imageList = [];
    //canvass echars图表转为图片
    for(let k4 = 0; k4 < canvass.length; k4++) {
        let imageURL = canvass[k4].toDataURL("image/png");
        let img = document.createElement("img");
        img.src = imageURL;
        imageList.push(img.outerHTML);
    }
    //做分页
    //style="page-break-after: always"
    let pages = _dom.querySelectorAll('.result');
    for(let k5 = 0; k5 < pages.length; k5++) {
        pages[k5].setAttribute('style', 'page-break-after: always');
    }
    let result = _dom.outerHTML;
    //result = result.replace(/<colgroup>(.*?)<\/colgroup>/gi, '')
    //result = result.replace(/<canvas (.*?)><\/canvas>/gi, '')
    for(let i = 0; i < imgRepalce.length; i++) {
        result = result.replace(imgRepalce[i].outerHTML,
            '<div class="imgRepalce">' + imageList[i] + '</div>')
    }
    result = result.replace(/<img (.*?)>/gi, '<img $1></img>')
    result = result.replace(/<br>/gi, '<br></br>');
    result = result.replace(/<hr>/gi, '<hr></hr>');
    return "<body printmarginleft='72' printmarginright='72' printmargintop='56' printmarginbottom='56'>" + result + "</body>";
}

这里注意传参数,当前页面的话使用的参数为:

getHtml(this.$refs.print)

函数三:

export function getStyle(notPrint) {
    var str = '<head><meta charset="utf-8"></meta>',
        styles = document.querySelectorAll('style');
    for(var i = 0; i < styles.length; i++) {
        str += styles[i].outerHTML;
    }
    str += "<style>" + (notPrint ? notPrint : '.no-print') + "{display:none;}</style>";
    str += "<style>.results{width:100%!important;} .result .title{width:100%;}</style>";
    str += "<style>table{border-collapse: collapse;table-layout: fixed}</style>"
    str += "<style>table thead tr{ background-color: #f3f4f9;}</style>"
    str += "<style>table td,th{ font-size: 14px;padding: 1px 1px;border-width: 1px;border-style: solid;border-color: #d0d0d0;word-break: keep-all;white-space: nowrap;}</style>"
    str += "<style>h5{font-color: #2fb89e;}</style>"
    str += "</head>"
    return str;
}

这三个函数缺一不可。

5.将所有的东西准备好了之后,就可以开始使用了:

exportWord(){
			// 把当前 vue 所展示的页面对应的 html 转换成一个字符串,这里用到了上面的三个函数,所以,如果是写在外面的话要引用进来
			let html  = this.getModelHtml(getHtml(this.$refs.print),getStyle());
			// 使用我们刚刚准备好的html模板并创建Blob对象
			let blob = new Blob([html],{type:"application/msword;charset=utf-8"});
			// 调用FileSaver.saveAs导出下载word
			saveAs(blob, "导出word的名字.doc");
		}

把这个函数的调用给一个按钮就行了。

最终效果:

在这里插入图片描述
在这里插入图片描述
就这么简单!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐