欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實(shí)現(xiàn)導(dǎo)出word文檔功能實(shí)例(含多張圖片)

 更新時(shí)間:2022年09月23日 11:47:34   作者:薇森  
項(xiàng)目需要導(dǎo)出word,于是乎又是查閱資料,然后自己寫,下面這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)導(dǎo)出word文檔功能(含多張圖片)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、實(shí)現(xiàn)效果  

以填寫并導(dǎo)出房屋出租審批表為例,首先填寫表格相應(yīng)內(nèi)容后,點(diǎn)擊" 導(dǎo)出 "按鈕實(shí)現(xiàn)word文檔的導(dǎo)出功能,界面如下所示: 

最后導(dǎo)出word文檔如下所示:

二、所需插件

這里使用npm對以下所需依賴進(jìn)行安裝,并在后面封裝的js文件(導(dǎo)出word文檔主要實(shí)現(xiàn)方法)中引入 。

-- 安裝 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

三、word文檔模板 

在導(dǎo)出word之前,需要準(zhǔn)備一個(gè)word模板文件(按自己所需最后導(dǎo)出的樣式),放到該vue項(xiàng)目public文件夾下, 房屋出租審批表模板word樣式如下所示:

ed329decadf045c699760052e86b97ce.jpeg

需要填寫的部分都被定義為變量或者json對象數(shù)組,具體格式如下:

1.  單一變量使用  {  }  包含,例如:

{ user } 、{ area }

2.  json數(shù)組格式,則包裹一個(gè)循環(huán)對象,例如:

 原格式為:

"thinglist": [
      { time :"2022-4-1",thing: "在家"},
      { time :"2022-4-2",thing: "上班"},
 ]

 在模板文件中表示為:

{#thinglist}
    {time}-{thing}
{/thinglist}

如果對象是圖片地址時(shí),需要在對象前加上% ,例如:

 原格式為:

imglist:[
	{ imgUrl: "  "},
	{ imgUrl: "  "},
]

 在模板文件中表示為:

{#imglist}
    {%imgUrl}
{/imglist}

四、封裝js 文件

這部分主要是實(shí)現(xiàn)word文檔導(dǎo)出含圖片的主要實(shí)現(xiàn)方法,包括將圖片的url路徑轉(zhuǎn)為base64路徑、base64轉(zhuǎn)二進(jìn)制、以及導(dǎo)出圖片的處理,可以直接復(fù)制粘貼在頁面引入使用,具體代碼如下: 

import PizZip from 'pizzip'
import docxtemplater from 'docxtemplater'
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 = new Buffer(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;
}
 
/**
 * 導(dǎo)出word,支持圖片
 * @param {Object} tempDocxPath 模板文件路徑
 * @param {Object} wordData 導(dǎo)出數(shù)據(jù)
 * @param {Object} fileName 導(dǎo)出文件名
 * @param {Object} imgSize 自定義圖片尺寸
 */
export const exportWord = (tempDocxPath, wordData, fileName,imgSize) => {
	//這里要引入處理圖片的插件
	var ImageModule = require('docxtemplater-image-module-free');
 
	const expressions = require("angular-expressions");
 
	// 讀取并獲得模板文件的二進(jìn)制內(nèi)容
	JSZipUtils.getBinaryContent(tempDocxPath, function(error, content) {
 
		if (error) {
			throw error;
		}
		expressions.filters.size = function(input, width, height) {
			return {
				data: input,
				size: [width, height],
			};
		};
		function angularParser(tag) {
			const expr = expressions.compile(tag.replace(/'/g, "'"));
			return {
				get(scope) {
					return expr(scope);
				},
			};
		}
		// 圖片處理
		let opts = {}
 
		opts = {
			//圖像是否居中
			centered: true
		};
		opts.getImage = (chartId) => {
			//console.log(chartId);//base64數(shù)據(jù)
			//將base64的數(shù)據(jù)轉(zhuǎn)為ArrayBuffer
			return base64DataURLToArrayBuffer(chartId);
		}
		opts.getSize = function(img, tagValue, tagName) {
			//自定義指定圖像大小
			if(imgSize.hasOwnProperty(tagName)){
				return imgSize[tagName];
			}else{
				return [300, 300];
			}
		}
		// 創(chuàng)建一個(gè)PizZip實(shí)例,內(nèi)容為模板的內(nèi)容
		let zip = new PizZip(content);
		// 創(chuàng)建并加載docxtemplater實(shí)例對象
		let doc = new docxtemplater();
		doc.attachModule(new ImageModule(opts));
		doc.loadZip(zip);
		doc.setData(wordData);
		try {
			// 用模板變量的值替換所有模板變量
			doc.render();
		} catch (error) {
			// 拋出異常
			let e = {
				message: error.message,
				name: error.name,
				stack: error.stack,
				properties: error.properties
			};
			console.log(JSON.stringify({
				error: e
			}));
			throw error;
		}
		// 生成一個(gè)代表docxtemplater對象的zip文件(不是一個(gè)真實(shí)的文件,而是在內(nèi)存中的表示)
		let out = doc.getZip().generate({
			type: "blob",
			mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
		});
		// 將目標(biāo)文件對象保存為目標(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;
		// 解決跨域問題
		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);
		};
	})
}

五、實(shí)現(xiàn)導(dǎo)出word文檔

1.  首先是前端部分,這里使用ElementPlus進(jìn)行前端頁面實(shí)現(xiàn),代碼如下:

<template>
	<div class="page-css">
		   <el-card class="box-card" shadow="never">
			   <div class="search-data">
				   <el-button type="success" @click="editVisible=true">填寫審批表</el-button>
			   </div> 
		   </el-card>
		   <el-dialog v-model="editVisible" title="房屋出租審批表" width="50%" custom-class="role-mask">
			   <div>
				   <div class="tablename">
					   <h2>房屋出租審批表</h2>
				   </div>
				  <table class="tb" border="1">
				  		<tr>
				  			<td height="60">承租人</td>
				  			<td colspan="2"  width="180">
								<input class="inputone" v-model="user"/>
							</td>
				  			<td colspan="2" width="125">房屋面積</td>
				  			<td colspan="2" width="175">
								<input class="inputtwo" v-model="area" />
								平方米
							</td>
				  		</tr>
				  		<tr>
				  			<td height="60">年租金</td>
				  			<td colspan="2" >
								<input class="inputtwo" v-model="annualrent" />
								元/年
							</td>
				  			<td colspan="2" >出租用途</td>
				  			<td colspan="2" >
								<input class="inputone" v-model="purpose"/>
							</td>
				  		</tr>
						<tr>
							<td height="300">房屋平面示意圖</td>
							<td  colspan="6">
								 <div v-for="(item,index) in imglist">
									 <img style="width: 60%;" :src="item.imgUrl"/>
								 </div>
							</td>
						</tr>
				  	</table>
			   </div>
		       <template #footer>
		   		 <span class="dialog-footer">
		   			 <el-button type="info" @click="editVisible=false">取消</el-button>
		   			 <el-button type="primary" @click="exportWordFile" >導(dǎo)出</el-button>
		   		 </span>
		      </template>
		   </el-dialog> 
		   </div>
</template>

實(shí)現(xiàn)過程遇到一個(gè)問題:使用el-dialog彈出框時(shí),想固定其在頁面居中、距離頁面頂部以及底部的固定距離,但是里面的表格內(nèi)容卻超出其顯示范圍,該如何實(shí)現(xiàn)喃?css設(shè)置如下:

/* 彈出框居中顯示 */
/deep/.el-dialog {
   left: 50%;
   top: 50%;
   transform: translate(-50%, -50%);
   margin: 0px !important;
}
/* 彈出框超出部分滑動(dòng) */
/deep/.el-dialog__body {
	 height: 75vh;
	 overflow: hidden;
	 overflow-y: auto;
}

 包括更改el-dialog彈出框頭部以及底部區(qū)域樣式,css設(shè)置如下:

/deep/.el-dialog__header {
    width: 100%;
    background-color:#f8f8f8 ;
}
/deep/ .el-dialog__footer {
    width: 100%;
	border-top: 1px #ebebeb solid ;
}

 2.然后在頁面內(nèi)引入封裝js里的exportWord以及getBase64Sync方法,data部分定義的是雙向綁定填寫的內(nèi)容以及圖片地址,考慮到圖片可能不知一張,需要循環(huán)對其處理轉(zhuǎn)為base64路徑,代碼如下:

// 引入將圖片的url路徑轉(zhuǎn)為base64路徑的方法
for (let i in this.imglist) {
	this.imglist[i].imgUrl = await getBase64Sync(this.imglist[i].imgUrl)
}

完整代碼如下所示: 

<script>
import {exportWord,getBase64Sync} from '@/assets/js/outword.js'
export default {
  data () {
      return {
		editVisible:false,
		user:'',
		area:'',
		annualrent:'',
		purpose:'',
		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 (){
			for (let i in this.imglist) {
			    this.imglist[i].imgUrl = await getBase64Sync(this.imglist[i].imgUrl)
			}
			 let  data= {
				user:this.user,
				area:this.area,
				annualrent:this.annualrent,
				purpose:this.purpose,
				imglist:this.imglist
			}
	        let imgSize = {
			//控制導(dǎo)出的word圖片大小
	          imgurl:[200, 200],
	        };
	        exportWord("/房屋出租審批表.docx", data, "房屋出租審批表.docx", imgSize);
	      }	
  }
}
</script>

總結(jié)

到此這篇關(guān)于vue實(shí)現(xiàn)導(dǎo)出word文檔功能(含多張圖片)的文章就介紹到這了,更多相關(guān)vue導(dǎo)出word文檔內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue?transition組件簡單實(shí)現(xiàn)數(shù)字滾動(dòng)

    Vue?transition組件簡單實(shí)現(xiàn)數(shù)字滾動(dòng)

    這篇文章主要為大家介紹了Vue?transition組件簡單實(shí)現(xiàn)數(shù)字滾動(dòng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • vue3界面使用router及使用watch監(jiān)聽router的改變

    vue3界面使用router及使用watch監(jiān)聽router的改變

    vue2中使用router非常簡單,但是vue3中略微有些改變,通過本文講解下他的改變,對vue3?watch監(jiān)聽router相關(guān)知識感興趣的朋友一起看看吧
    2022-11-11
  • vue 進(jìn)階之實(shí)現(xiàn)父子組件間的傳值

    vue 進(jìn)階之實(shí)現(xiàn)父子組件間的傳值

    這篇文章主要介紹了vue 進(jìn)階之實(shí)現(xiàn)父子組件間的傳值,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • Vue-Cli中自定義過濾器的實(shí)現(xiàn)代碼

    Vue-Cli中自定義過濾器的實(shí)現(xiàn)代碼

    本篇文章主要介紹了Vue-Cli中自定義過濾器的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Vue+Spring Boot簡單用戶登錄(附Demo)

    Vue+Spring Boot簡單用戶登錄(附Demo)

    這篇文章主要介紹了Vue+Spring Boot簡單用戶登錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 詳解Vue+elementUI build打包部署后字體圖標(biāo)丟失問題

    詳解Vue+elementUI build打包部署后字體圖標(biāo)丟失問題

    這篇文章主要介紹了詳解Vue+elementUI build打包部署后字體圖標(biāo)丟失問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • vue使用Element的Tree樹形控件實(shí)現(xiàn)拖動(dòng)改變節(jié)點(diǎn)順序方式

    vue使用Element的Tree樹形控件實(shí)現(xiàn)拖動(dòng)改變節(jié)點(diǎn)順序方式

    這篇文章主要介紹了vue使用Element的Tree樹形控件實(shí)現(xiàn)拖動(dòng)改變節(jié)點(diǎn)順序方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 詳解基于vue的移動(dòng)web app頁面緩存解決方案

    詳解基于vue的移動(dòng)web app頁面緩存解決方案

    這篇文章主要介紹了詳解基于vue的移動(dòng)web app頁面緩存解決方案,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-08-08
  • vue中@click綁定事件點(diǎn)擊不生效的原因及解決方案

    vue中@click綁定事件點(diǎn)擊不生效的原因及解決方案

    根據(jù)Vue2.0官方文檔關(guān)于父子組件通訊的原則,父組件通過prop傳遞數(shù)據(jù)給子組件,子組件觸發(fā)事件給父組件,這篇文章主要介紹了vue中@click綁定事件點(diǎn)擊不生效的解決方案,需要的朋友可以參考下
    2022-12-12
  • Vue項(xiàng)目中引入外部腳本的多種方式

    Vue項(xiàng)目中引入外部腳本的多種方式

    在現(xiàn)代的前端開發(fā)中,我們經(jīng)常需要使用一些第三方的外部腳本或庫,尤其是像地圖、圖表、分析工具等,在 Vue 項(xiàng)目中,有多種方式可以引入外部腳本,本文將詳細(xì)介紹在 Vue 項(xiàng)目中引入外部腳本的幾種常見方法,需要的朋友可以參考下
    2025-01-01

最新評論