前言
網上查了很多jquery.wordexport的文章都是隻支援單獨導出word,不符合業務需求。是以修改了jquery.wordexport、利用jszip、file-saver批量導出word。
前提準備
包的版本分别為[email protected]、[email protected]。jquery版本随意,本文使用的為@3.2.1
npm i [email protected] -D
npm i [email protected] -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)');
}
}