vue使用jquery.wordexport导出word文档(批量导出为zip)

前言

网上查了很多jquery.wordexport的文章都是只支持单独导出word,不符合业务需求。因此修改了jquery.wordexport、利用jszip、file-saver批量导出word。

前提准备

包的版本分别为jszip@3.10.1、file-saver@2.0.5。jquery版本随意,本文使用的为@3.2.1

npm i jszip@3.10.1 -D
npm i file-saver@2.0.5 -D

正文

html部分

注意:导出word文档识别不了css中的样式,只能将样式写为行内样式或者添加在wordExport()方法的第二个参数中。jquery.wordexport无法使用flex布局,position等

<div class="wordForm-box">
      <div class="wordForm"
           v-for="(item,index) in exportWordList"
           :key="index"
           :id="'word'+index">
           <p align="center"
           style="font-size:32px;line-height: 40px;font-weight: 900;">{{ item.formTitle }}</p>
           <table style="margin-top:20px">
          <thead>
            <th>操作时间</th>
            <th>操作人员</th>
            <th>操作节点</th>
            <th>操作类型</th>
            <th>操作结果</th>
            <th>反馈详情</th>
          </thead>
          <tbody>
            <tr v-for="(record) in item.records"
                :key="record.id">

              <td>{{ record.create_time | dateFormat}}</td>
              <td>{{ record.operator.nickname}}</td>
              <td>{{ record.level_from | formatAuditNode}}</td>
              <td>{{ record.type | formatState}}</td>
              <td>{{ record | formatResult}}</td>
              <td>{{ record.remark}}</td>
            </tr>
          </tbody>
        </table>
      </div>
 </div>

script部分

jquery的引用应放在wordexport前
注意:批量压缩时 同名文件将只会存在一个,请注意命名

  <script>
	import JSZip from 'jszip';
	import FileSaver from 'file-saver';
	import $ from '../../../libs/jquery-3.2.1/jquery.min.js';
	import '../../../libs/jquery.wordexport';
	export default {
	data() {
        return {
        exportWordList: [],//需导出word表格列表
        }
        }
	methods: {
	async handleWordExport() {
		this.exportWordList = [];//初始化
	//...数据处理
	// 导出
	//本文数据处理有异步操作,nextTick处理保证页面已更新
  		this.$nextTick(() => {
  					let wordFiles = [];
                    let wordList = []; // 由于批量压缩时 同名文件将只会存在一个 这里我们采用[[],[]]包裹同名文件
                    this.exportWordList.forEach(async (wordItem, index) => {
                        let tmpIndex = wordList.findIndex((tmpWordItem) => {
                            return tmpWordItem[0].formTitle == wordItem.formTitle;
                        });
                        if (tmpIndex == -1) {
                            wordList.push([wordItem]);
                        } else {
                            wordList[tmpIndex].push(wordItem);
                            // wordList[tmpIndex][wordList[tmpIndex].length - 1].formTitle += '' + (wordList[tmpIndex].length - 1);
                            wordItem.formTitle += '(' + (wordList[tmpIndex].length - 1) + ')';
                        }
                        let rules =
                            'table{' +
                            '	border-collapse:collapse;' +
                            '	margin:0 auto;' +
                            '	text-align:center;' +
                            '	width: 100%;' +
                            '}' +
                            'table td,table th{' +
                            '   text-align:center;' +
                            '   border:1px solid #000000;' +
                            '	height:25pt;' +
                            '	width:15%;' +
                            '}' +
                            'table thead th{' +
                            ' 	width:15%' +
                            '}' +
                            'table tr{' +
                            '	background:#fff;' +
                            '}';
                            //可以通过修改wordExport()方法的第二个参数,添加样式
                        let wordFile = await $('#word' + index).wordExport(wordItem.formTitle, rules);
                        wordFiles.push(wordFile);

                        if (wordFiles.length == this.exportWordList.length) {
                            this.zipWordExport(wordFiles);
                           
                        }
                    });
  }

	},
	//导出zip
	zipWordExport(promises) {
            const zip = new JSZip();
            const _this = this;
            promises.forEach(async (item, index) => {
            //word为blob数据
                const { word, fileName } = item;
                if (promises.length === 1) {
                    FileSaver.saveAs(word, `${fileName}.doc`);
                } else {
                
                    await zip.file(`${fileName}.doc`, word);
                }
                if (promises.length > 1 && promises.length - 1 == index) {
                    _this.$message.warning('正在压缩请稍后');
                    zip.generateAsync({ type: 'blob' }).then((content) => {
                        FileSaver.saveAs(content, '表单记录合集' + '.zip');
                    });
                }
            });
        },
	}
	}
</script>

jquery.wordexport代码

注意:jquery.wordexport中导入的jquery文件应与正文代码为同一文件

// 导入js文件
import $ from './jquery-3.2.1/jquery.min.js';
let jQuery = $;
if (typeof jQuery !== 'undefined') {
    (function () {
        $.fn.wordExport = function (fileName, rules) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    fileName = typeof fileName !== 'undefined' ? fileName : 'jQuery-Word-Export';
                    var static_ = {
                        mhtml: {
                            top: 'Mime-Version: 1.0\nContent-Base: ' + location.href + '\nContent-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset="utf-8"\nContent-Location: ' + location.href + '\n\n<!DOCTYPE html>\n<html>\n_html_</html>',
                            head: '<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n<style>\n_styles_\n</style>\n</head>\n',
                            body: '<body>_body_</body>'
                        }
                    };
                    var options = {
                        maxWidth: 624
                    };
                    // Clone selected element before manipulating it
                    var markup = $(this).clone();
                    // Remove hidden elements from the output
                    markup.each(function () {
                        var self = $(this);
                        if (self.is(':hidden')) {
                            self.remove();
                        }
                    });

                    // Embed all images using Data URLs
                    var images = Array();
                    var img = markup.find('img');
                    for (var i = 0; i < img.length; i++) {
                        // 如果导出的word文件里面包含线上的图片
                        // Calculate dimensions of output image
                        var width = Math.min(img[i].width, options.maxWidth);
                        var height = img[i].height * (width / img[i].width);
                        // Create canvas for converting image to data URL
                        // 这是添加的代码--------------------------------------------
                        var img_id = '#' + img[i].id;
                        $('<canvas>').attr('id', 'test_word_img_' + i).width(width).height(height).insertAfter(img_id);


                        // 如果导出的word文件里面包含本地图片用这一段,如果都包含,要另外研究一下
                        // Calculate dimensions of output image
                        var w = Math.min(img[i].width, options.maxWidth);
                        var h = img[i].height * (w / img[i].width);
                        // Create canvas for converting image to data URL
                        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 uri = canvas.toDataURL('image/png');
                        $(img[i]).attr('src', img[i].src);
                        img[i].width = w;
                        img[i].height = h;
                        // Save encoded image to array
                        images[i] = {
                            type: uri.substring(uri.indexOf(':') + 1, uri.indexOf(';')),
                            encoding: uri.substring(uri.indexOf(';') + 1, uri.indexOf(',')),
                            location: $(img[i]).attr('src'),
                            data: uri.substring(uri.indexOf(',') + 1)
                        };

                    }

                    // Prepare bottom of mhtml file with image data
                    var mhtmlBottom = '\n';
                    for (var i = 0; i < images.length; i++) {
                        mhtmlBottom += '--NEXT.ITEM-BOUNDARY\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 += '--NEXT.ITEM-BOUNDARY--';

                    // TODO: load css from included stylesheet
                    var styles = rules;

                    // Aggregate parts of the file together
                    var fileContent = static_.mhtml.top.replace('_html_', static_.mhtml.head.replace('_styles_', styles) + static_.mhtml.body.replace('_body_', markup.html())) + mhtmlBottom;

                    // Create a Blob with the file contents
                    var blob = new Blob([fileContent], {
                        type: 'application/msword;charset=utf-8'
                    });

                    resolve({ word: blob, fileName: fileName });
                }, 10);
            });

        };
    })(jQuery);
} else {
    if (typeof jQuery === 'undefined') {
        console.error('jQuery Word Export: missing dependency (jQuery)');
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值