1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > vue 导出word和Excel两种文件 附带多张图片导出(超详细教程)

vue 导出word和Excel两种文件 附带多张图片导出(超详细教程)

时间:2021-10-24 12:52:03

相关推荐

vue 导出word和Excel两种文件 附带多张图片导出(超详细教程)

编程综合网:天梦星科技官网

小编:张贵顺

在此之前先下载依赖:

npm install -S file-saver xlsxnpm install -D script-loadernpm install js-table2excel

-- 安装 docxtemplaternpm install docxtemplater pizzip --save-- 安装 jszip-utilsnpm install jszip-utils --save -- 安装 jszipnpm install jszip --save-- 安装 FileSavernpm install file-saver --save-- 安装 angular-expressionsnpm install angular-expressions --save-- 安装 image-sizenpm install image-size --save

接下来上代码:

导出Word表格,支持多张图片 ,人狠话不多说,直接上代码

文件名:exportWordImage.js

/*** 导出word文档(带图片)**/import Docxtemplater from 'docxtemplater'import PizZip from 'pizzip'import JSZipUtils from 'jszip-utils'import { saveAs } from 'file-saver'/*** 将base64格式的数据转为ArrayBuffer* @param {Object} dataURL base64格式的数据*/function base64DataURLToArrayBuffer(dataURL) {const base64Regex = /^data:image\/(png|jpg|jpeg|svg|svg\+xml);base64,/;if (!base64Regex.test(dataURL)) {return false;}const stringBase64 = dataURL.replace(base64Regex, "");let binaryString;if (typeof window !== "undefined") {binaryString = window.atob(stringBase64);} else {binaryString = Buffer.from(stringBase64, "base64").toString("binary");}const len = binaryString.length;const bytes = new Uint8Array(len);for (let i = 0; i < len; i++) {const ascii = binaryString.charCodeAt(i);bytes[i] = ascii;}return bytes.buffer;}export const ExportBriefDataDocx = (tempDocxPath, data, fileName, imgSize) => {//这里要引入处理图片的插件var ImageModule = require('docxtemplater-image-module-free');var expressions = require('angular-expressions')var assign = require('lodash/assign')var last = require("lodash/last")expressions.filters.lower = function (input) {if (!input) return inputreturn input.toLowerCase()}function angularParser(tag) {tag = tag.replace(/^\.$/, 'this').replace(/(’|‘)/g, "'").replace(/(“|”)/g, '"')const expr = pile(tag)return {get: function (scope, context) {let obj = {}const index = last(context.scopePathItem)const scopeList = context.scopeListconst num = context.numfor (let i = 0, len = num + 1; i < len; i++) {obj = assign(obj, scopeList[i])}//word模板中使用 $index+1 创建递增序号obj = assign(obj, { $index: index })return expr(scope, obj)}}}JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {if (error) {console.log(error)}expressions.filters.size = function (input, width, height) {return {data: input,size: [width, height],};};let opts = {}opts = {//图像是否居中centered: false};opts.getImage = (chartId) => {//将base64的数据转为ArrayBufferreturn base64DataURLToArrayBuffer(chartId);}opts.getSize = function (img, tagValue, tagName) {//自定义指定图像大小if (imgSize.hasOwnProperty(tagName)) {return imgSize[tagName];} else {return [100, 100];}}// 创建一个JSZip实例,内容为模板的内容const zip = new PizZip(content)// 创建并加载 Docxtemplater 实例对象// 设置模板变量的值let doc = new Docxtemplater();doc.attachModule(new ImageModule(opts));doc.loadZip(zip);doc.setOptions({parser:angularParser});doc.setData(data)try {// 呈现文档,会将内部所有变量替换成值,doc.render()} catch (error) {const e = {message: error.message,name: error.name,stack: error.stack,properties: error.properties}console.log('err',{ error: e })// 当使用json记录时,此处抛出错误信息throw error}// 生成一个代表Docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)const out = doc.getZip().generate({type: 'blob',mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})// 将目标文件对象保存为目标类型的文件,并命名saveAs(out, fileName)})}/*** 将图片的url路径转为base64路径* 可以用await等待Promise的异步返回* @param {Object} imgUrl 图片路径*/export function getBase64Sync(imgUrl) {return new Promise(function (resolve, reject) {// 一定要设置为let,不然图片不显示let image = new Image();//图片地址image.src = imgUrl;// 解决跨域问题image.setAttribute("crossOrigin", '*'); // 支持跨域图片// image.onload为异步加载image.onload = function () {let canvas = document.createElement("canvas");canvas.width = image.width;canvas.height = image.height;let context = canvas.getContext("2d");context.drawImage(image, 0, 0, image.width, image.height);//图片后缀名let ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase();//图片质量let quality = 0.8;//转成base64let dataurl = canvas.toDataURL("image/" + ext, quality);//返回resolve(dataurl);};})}

调用函数:

async expotWord(){let data:{isTable:[{id: 1, created_at: "-05-19", organ_name: "测试", title: "测试", url: "测试",region_text: "测试", involved: "测试", dissemination:"测试", standpoint: "测试", risk_content: "测试", eidt_role: "测试", files_json: [{imgUrl:'http://172.16.72.27:32114/group1/hzyn/ynwx/feedback/0516/1684207872385.jpeg'},{imgUrl:'http://172.16.72.27:32114/group1/hzyn/ynwx/feedback/0516/1684207872385.jpeg'}, ] }]};for (const item of data.isTable) {for (let i in item.files_json) {item.files_json[i].imgUrl = await getBase64Sync(item.files_json[i].imgUrl)}}if (wordData.isTable.length>=1){let imgSize = {imgurl:[200, 200],//控制导出的word图片大小};ExportBriefDataDocx(`${"/yqypexportdata"}.docx`, data, "信息测试.docx", imgSize);}else {this.$message.warning("导出数据不能为空!");}},

表格模版:文件名:yqypexportdata.docx 位置放public 目录下

预期效果:

2.导出Excel表格,同样支持多张图片

封装的js:

/* eslint-disable */let idTmr;const getExplorer = () => {let explorer = window.navigator.userAgent;//ieif (explorer.indexOf("MSIE") >= 0) {return 'ie';}//firefoxelse if (explorer.indexOf("Firefox") >= 0) {return 'Firefox';}//Chromeelse if (explorer.indexOf("Chrome") >= 0) {return 'Chrome';}//Operaelse if (explorer.indexOf("Opera") >= 0) {return 'Opera';}//Safarielse if (explorer.indexOf("Safari") >= 0) {return 'Safari';}}const exportToExcel = (data,name) => {// 判断是否为IEif (getExplorer() == 'ie') {tableToIE(data, name)} else {tableToNotIE(data,name)}}const Cleanup = () => {window.clearInterval(idTmr);}const tableToIE = (data, name) => {let curTbl = data;let oXL = new ActiveXObject("Excel.Application");//创建AX对象excellet oWB = oXL.Workbooks.Add();//获取workbook对象let xlsheet = oWB.Worksheets(1);//激活当前sheetlet sel = document.body.createTextRange();sel.moveToElementText(curTbl);//把表格中的内容移到TextRange中sel.select;//全选TextRange中内容sel.execCommand("Copy");//复制TextRange中内容xlsheet.Paste();//粘贴到活动的EXCEL中oXL.Visible = true;//设置excel可见属性try {let fname = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls");} catch (e) {print("Nested catch caught " + e);} finally {oWB.SaveAs(fname);oWB.Close(savechanges = false);//xls.visible = false;oXL.Quit();oXL = null;// 结束excel进程,退出完成window.setInterval("Cleanup();", 1);idTmr = window.setInterval("Cleanup();", 1);}}const tableToNotIE = (function() {// 编码要用utf-8不然默认gbk会出现中文乱码let uri = 'data:application/vnd.ms-excel;base64,',template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="/TR/REC-html40"><head><meta charset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',base64 = function(s) {return window.btoa(unescape(encodeURIComponent(s)));},format = (s, c) => {return s.replace(/{(\w+)}/g,(m, p) => {return c[p];})}return (table, name) => {let ctx = {worksheet: name,table}//创建下载let link = document.createElement('a');link.setAttribute('href', uri + base64(format(template, ctx)));link.setAttribute('download', name);// window.location.href = uri + base64(format(template, ctx))link.click();}})()// 导出函数const export2Excel = (theadData, tbodyData, dataname) => {let re = /https?:\\.(png|gif|jpg|jpeg|bmp)/ig // 字符串中包含http,则默认为图片地址(正则)let th_len = theadData.length // 表头的长度let tb_len = tbodyData.length // 记录条数let width = 40 // 设置图片大小let height = 60// 添加表头信息let thead = '<thead><tr>'for (let i = 0; i < th_len; i++) {thead += '<th>' + theadData[i] + '</th>'}thead += '</tr></thead>'// 添加每一行数据let tbody = '<tbody>'for (let i = 0; i < tb_len; i++) {tbody += '<tr>'let row = tbodyData[i] // 获取每一行数据for (let key in row) {if (re.test(row[key])) { // 如果为图片,则需要加div包住图片let listDiv=''for (const keyElement of row[key]) {listDiv+= '<div>'+'<img src=\'' + keyElement + '\' ' + ' ' + 'width=' + '\"' + width + '\"' + ' ' + 'height=' + '\"' + height + '\"' + '/>'+'</div>'}tbody += '<td style="width:auto; height:auto; text-align: center; vertical-align: middle">' + listDiv + '</td>'} else {tbody += '<td style="text-align:center">' + row[key] + '</td>'}}tbody += '</tr>'}tbody += '</tbody>'let table = thead + tbody// 导出表格exportToExcel(table, dataname)}export {export2Excel}

调用:

expotExcel(e){let tbody =[{id:'',//序号created_at:null,//创建时间organ_name:null,//上报单位title:null,//标题url:null,//链接region_text:null,//事件属地involved:null,//涉事单位dissemination:null,//传播情况standpoint:null,//网民观点risk_content:null,//风险研判eidt_role:null,files_json:['http://172.16.72.27:32114/group1/hzyn/ynwx/feedback/0516/1684207872385.jpeg','http://172.16.72.27:32114/group1/hzyn/ynwx/feedback/0516/1684207872385.jpeg'],//附件}]let tHeader =['序号','创建时间','上报单位','标题','链接','事件属地','涉事单位','传播情况','网民观点','风险研判','选用人','附件']let dataTime=this.$moment().format('YYYY-MM-DD HH');if (tbody.length>=1){export2Excel(tHeader, tbody, '舆情信息汇总'+'('+dataTime+')')}else {this.$message.warning("导出数据不能为空!");}},

预期效果:

收到over over!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。