VUE使用docxtemplater導(dǎo)出word文檔實(shí)例(帶圖片)
一、docxtemplater
docxtemplater 是一種郵件合并工具,以編程方式使用并處理?xiàng)l件、循環(huán),并且可以擴(kuò)展以插入任何內(nèi)容(表格、html、圖像)。
npm 是安裝 docxtemplater 最簡(jiǎn)單的方法
npm install docxtemplater pizzip --save?
// 安裝 docxtemplater npm install docxtemplater pizzip --save // 安裝 jszip-utils npm install jszip-utils --save // 安裝 jszip npm install jszip --save // 安裝 FileSaver npm install file-saver --save // 引入處理圖片的插件1 npm install docxtemplater-image-module-free --save // 引入處理圖片的插件2 npm install angular-expressions --save
二、在導(dǎo)出word前,需要準(zhǔn)備一個(gè)word模板文件(按自己所需最后導(dǎo)出的樣式),放到public文件夾下
如下所示
(這里感覺(jué)用的語(yǔ)法比較全了,有其他語(yǔ)法可以交流一下)
注:
需要填寫的部分都被定義為變量或者json對(duì)象數(shù)組,具體格式如下:
1. 單一變量使用 { } 包含,例如:
{name}、{user}
2. json數(shù)組格式,則包裹一個(gè)循環(huán)對(duì)象,例如:
原格式為:
list:[ {name:'lipipi'}, {name:'heyaya'} ]
在模板文件中表示為:
{#list}{name}{/}
如果對(duì)象是圖片地址時(shí),需要在對(duì)象前加上% ,例如:
在模板文件中表示為:
{#imglist}
{%imgUrl}
{/imglist}
踩坑:圖片這里我一直報(bào)錯(cuò)‘%imgUrl’,最后發(fā)現(xiàn)必須要換行寫,而其他數(shù)組可以在一行寫。
三、封裝JS
這部分主要是實(shí)現(xiàn)word文檔導(dǎo)出含圖片的主要實(shí)現(xiàn)方法,包括將圖片的url路徑轉(zhuǎn)為base64路徑、base64轉(zhuǎn)二進(jìn)制、以及導(dǎo)出圖片的處理,可以直接復(fù)制粘貼在頁(yè)面引入使用,具體代碼如下:
/** * 導(dǎo)出word文檔(帶圖片) * */ import Docxtemplater from 'docxtemplater' import PizZip from 'pizzip' import JSZipUtils from 'jszip-utils' import { saveAs } from 'file-saver' /** * 將base64格式的數(shù)據(jù)轉(zhuǎn)為ArrayBuffer * @param {Object} dataURL base64格式的數(shù)據(jù) */ 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) => { console.log(111, 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) { // This condition should be used to make sure that if your input is // undefined, your output will be undefined as well and will not // throw an error if (!input) return input // toLowerCase() 方法用于把字符串轉(zhuǎn)換為小寫。 return input.toLowerCase() } function angularParser(tag) { tag = tag .replace(/^\.$/, 'this') .replace(/('|‘)/g, "'") .replace(/(“|”)/g, '"') const expr = expressions.compile(tag) return { get: function (scope, context) { let obj = {} const index = last(context.scopePathItem) const scopeList = context.scopeList const num = context.num for (let i = 0, len = num + 1; i < len; i++) { obj = assign(obj, scopeList[i]) } //word模板中使用 $index+1 創(chuàng)建遞增序號(hào) 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: true }; opts.getImage = (chartId) => { //將base64的數(shù)據(jù)轉(zhuǎn)為ArrayBuffer return base64DataURLToArrayBuffer(chartId); } opts.getSize = function (img, tagValue, tagName) { //自定義指定圖像大小 if (imgSize.hasOwnProperty(tagName)) { return imgSize[tagName]; } else { return [200, 200]; } } // 創(chuàng)建一個(gè)JSZip實(shí)例,內(nèi)容為模板的內(nèi)容 const zip = new PizZip(content) // 創(chuàng)建并加載 Docxtemplater 實(shí)例對(duì)象 // 設(shè)置模板變量的值 let doc = new Docxtemplater(); doc.attachModule(new ImageModule(opts)); doc.loadZip(zip); doc.setOptions({parser:angularParser}); doc.setData(data) try { // 呈現(xiàn)文檔,會(huì)將內(nèi)部所有變量替換成值, doc.render() } catch (error) { const e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties } console.log('err',{ error: e }) // 當(dāng)使用json記錄時(shí),此處拋出錯(cuò)誤信息 throw error } // 生成一個(gè)代表Docxtemplater對(duì)象的zip文件(不是一個(gè)真實(shí)的文件,而是在內(nèi)存中的表示) const out = doc.getZip().generate({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }) // 將目標(biāo)文件對(duì)象保存為目標(biāo)類型的文件,并命名 saveAs(out, fileName) }) } /** * 將圖片的url路徑轉(zhuǎn)為base64路徑 * 可以用await等待Promise的異步返回 * @param {Object} imgUrl 圖片路徑 */ export function getBase64Sync(imgUrl) { return new Promise(function (resolve, reject) { // 一定要設(shè)置為let,不然圖片不顯示 let image = new Image(); //圖片地址 image.src = imgUrl; // 解決跨域問(wèn)題 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(); //圖片質(zhì)量 let quality = 0.8; //轉(zhuǎn)成base64 let dataurl = canvas.toDataURL("image/" + ext, quality); //返回 resolve(dataurl); }; }) }
四、調(diào)用導(dǎo)出方法
<script> import {exportWord,getBase64Sync} from '@/assets/js/outword.js' export default { data () { return { name:'lipipi', listname:'導(dǎo)出的模板' imglist:[ { imgUrl: "https://img2.baidu.com/it/u=2709954499,581919391&fm=253&fmt=auto&app=138&f=JPEG?w=468&h=518" }, { imgUrl: "https://img0.baidu.com/it/u=1462004956,1440895436&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=353" } ] } }, methods:{ async exportWordFile (){ //多個(gè)圖片遍歷轉(zhuǎn)base64 for (let i in this.imglist) { this.imglist[i].imgUrl = await getBase64Sync(this.imglist[i].imgUrl) } let data= { name:this.name imglist:this.imglist } let imgSize = { //控制導(dǎo)出的word圖片大小 imgurl:[200, 200], }; exportWord("/我的模板.docx", data, `${this.listname}.docx`, imgSize); } } } </script>
總結(jié)
到此這篇關(guān)于VUE使用docxtemplater導(dǎo)出word文檔的文章就介紹到這了,更多相關(guān)VUE用docxtemplater導(dǎo)出word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue打包部署到tomcat上頁(yè)面空白資源加載不出來(lái)的解決
這篇文章主要介紹了vue打包部署到tomcat上頁(yè)面空白資源加載不出來(lái)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue中使用vant的Toast輕提示報(bào)錯(cuò)的解決
這篇文章主要介紹了vue中使用vant的Toast輕提示報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05vue實(shí)現(xiàn)監(jiān)控視頻直播的示例代碼
本文主要介紹了vue實(shí)現(xiàn)監(jiān)控視頻直播的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05uniapp使用scroll-view下拉刷新無(wú)法取消的坑及解決
這篇文章主要介紹了uniapp使用scroll-view下拉刷新無(wú)法取消的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05vue?element-ui如何在el-tabs組件最右側(cè)添加按鈕
這篇文章主要介紹了vue?element-ui如何在el-tabs組件最右側(cè)添加按鈕問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07如何在Vue中使localStorage具有響應(yīng)式(思想實(shí)驗(yàn))
這篇文章主要介紹了如何在Vue中使localStorage具有響應(yīng)式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07VueCli4項(xiàng)目配置反向代理proxy的方法步驟
這篇文章主要介紹了VueCli4項(xiàng)目配置反向代理proxy的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05