js 导出word详解

首先了解下整个思路:

1、创建导出dom节点

2、由于页面不能直接导出且样式只支持行内样式,所以得手动写导出dom 节点

3、如有echar图表得先转成静态图片,el 表格先转行内表格

4、图片大小转换

创建dom 节点
<div id="wordModel">

    <div style="text-align: center;font-family: '宋体';">
        <div>
            <strong
            ><span style="font-size: 26.5pt;">测试</span></strong
            >
        </div>
      <br/>
  </div> 
</div>

需要一个内库 file-saver 下载安装下就好

导出核心代码如下

function exportWord(dom: Node, fileName: string, imgMinwidth?: number) {
    imgMinwidth = imgMinwidth ? imgMinwidth : 1024;
    setTimeout(() => {
        const randomStr = Math.random()
            .toString(36)
            .slice(-8)
            .toUpperCase();
        const header = {
            top: `MIME-Version: 1.0
Content-Type: multipart/related; boundary="----=_NextPart_01D59F91.${randomStr}"

------=_NextPart_01D59F91.${randomStr}
Content-Location: ${randomStr}.htm
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"

        `,
            head: `
        <html xmlns:v=3D"urn:schemas-microsoft-com:vml"
xmlns:o=3D"urn:schemas-microsoft-com:office:office"
xmlns:w=3D"urn:schemas-microsoft-com:office:word"
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
xmlns=3D"http://www.w3.org/TR/REC-html40">
        <head>
<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
<meta name=3DProgId content=3DWord.Document>
<meta name=3DGenerator content=3D"Microsoft Word 15">
<meta name=3DOriginator content=3D"Microsoft Word 15">
</head>
        `, body: `<body lang=3DZH-CN style=3D'tab-interval:21.0pt'>
_body_
</body>

</html>`
        };

        // Clone selected element before manipulating it
        const images = Array();
        const img = dom.find('img');
        for (let i = 0; i < img.length; i++) {
            // Calculate dimensions of output image
            let w = Math.min(img[i].width, imgMinwidth);
            let h = img[i].height * (w / img[i].width);
            // Create canvas for converting image to data URL
            const ramssP = Math.random()
                .toString(36)
                .slice(-8)
                .toUpperCase();
            // Save encoded image to array
            const uri = $(img[i]).attr('src');
            var canvas = document.createElement('CANVAS');
            canvas.width = w;
            canvas.height = h;
            // Draw image to canvas
            var context = canvas.getContext('2d');
            context.drawImage(img[i], 0, 0, w, h);
            // Get data URL encoding of image
            var dataUrl = canvas.toDataURL('image/png/jpg');
            images[i] = {
                type: uri.substring(uri.indexOf(':') + 1, uri.indexOf(';')),
                encoding: 'base64',
                location: ramssP + '.png',
                data: dataUrl.substring(dataUrl.indexOf(',') + 1)
            };
            // $(img[i]).attr('src', '' + ramssP + '.png'); //已路径形式熏染
            $(img[i]).attr('src', dataUrl);

        }
        let mhtmlBottom = '\n\n';
        for (var i = 0; i < images.length; i++) {
            mhtmlBottom += `------=_NextPart_01D59F91.${randomStr}\n`;
            mhtmlBottom += 'Content-Location: ' + images[i].location + '\n';
            mhtmlBottom += 'Content-Type: ' + images[i].type + '\n';
            mhtmlBottom +=
                'Content-Transfer-Encoding: ' + images[i].encoding + '\n\n';
            mhtmlBottom += images[i].data + '\n\n';
        }
        mhtmlBottom += `------=_NextPart_01D59F91.${randomStr}--`;
        const jdoc = dom
            .html()
            .replace(/data-v-([\w|\d]+)=""/g, '')
            .replace(/rowspan=/g, 'rowspan=3D')
            .replace(/colspan=/g, 'colspan=3D')
            .replace(/style=/g, 'style=3D')
            .replace(/src=/g, 'src=3D')
            .replace(/href=/g, 'href=3D')
            .replace(/height=/g, 'height=3D')
            .replace(/width=/g, 'width=3D')
            .replace(/name=/g, 'name=3D');
        const sourceHTML =
            header.top +
            header.head +
            header.body.replace('_body_', jdoc) +
            mhtmlBottom;

        const blob = new Blob([sourceHTML], {
            type: 'application/vnd.ms-word;charset=utf-8'
        });
        
        saveAs(blob, fileName);

    }, 200);
}

哦了, 就这么点

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值