北京网站建设是什么意思wordpress注册密码插件
web/
2025/10/7 23:37:42/
文章来源:
北京网站建设是什么意思,wordpress注册密码插件,网站建设捌金手指专业1,肥东房产网前言
近期我正在开发一个前后端分离项目#xff0c;使用了Spring Boot 和 Vue2#xff0c;借助了国内优秀的框架 jeecg#xff0c;前端UI库则选择了 ant-design-vue。在项目中#xff0c;需要实现文件上传功能#xff0c;同时还要能够在线预览和下载图片和PDF文件#x…前言
近期我正在开发一个前后端分离项目使用了Spring Boot 和 Vue2借助了国内优秀的框架 jeecg前端UI库则选择了 ant-design-vue。在项目中需要实现文件上传功能同时还要能够在线预览和下载图片和PDF文件甚至需要在页面上直接打印PDF文件。尽管框架自带了 vue-print-nb-jeecg 组件但它相对较为简陋只支持单页打印无法实现多页打印。经过仔细的权衡和比较后最终决定采用 vue-pdf 和 print-js 组件来满足需求。
一、先来展示一下最终效果
前端上传文件列表
点击PDF文件后展示预览 点击打印按钮后效果 二、实现步骤及代码
vue-pdf 可以用于在线预览而 print-js 则提供了更强大的打印功能支持多种文档类型包括PDF、HTML、IMAGE和JSON而且默认情况下是PDF。其实vue-pdf 也可以实现打印功能但是跟前述的vue-print-nb一样只能打印页面显示的第一页内容预览展示没问题。 Print.js官网点我直达
1. 在vue中安装vue-pdf 和Print.js
yarn add vue-pdf
...
yarn add print-js2. 可以全局引入也可以在需要的文件中引入 import pdf from vue-pdfimport printJS from print-js3.主要代码
a-modal :visiblepreviewVisibleForAll :footernull cancelhandleCancelAll :width800 :maskClosablemaskClosable :keyboardkeyboardimg altexample stylewidth: 100%;margin-top:20px :srcpreviewFileSrc v-ifisImage/div v-ifisPdf styleoverflow-y: auto;overflow-x: hidden;a-button shaperound iconfile-pdf clickhandlePrint(printData) sizesmall打印/a-buttondiv idprintFrompdf refpdf v-foritem in pageTotal:srcpreviewFileSrc:keyitem:pageitem/pdf/div/div/a-modal打印按钮执行的方法
// data参数
printData: {printable: printFrom,header: ,ignore: [no-print]
},// 执行方法
handlePrint(params) {printJS({printable: params.printable, // printFrom, // 标签元素idtype: params.type || html,header: params.header, // 表单,targetStyles: [*],style: page {margin:0 10mm};, // 可选-打印时去掉眉页眉尾ignoreElements: params.ignore || [], // [no-print]properties: params.properties || null})
}不同组件如果文件是图片就预览图片PDF就预览PDF。
4. 全部代码
templatediv :idcontainerId styleposition: relative!-- ---------------------------- begin 图片左右换位置 ------------------------------------- --div classmovety-container :style{top:toppx,left:leftpx,display:moveDisplay} stylepadding:0 8px;position: absolute;z-index: 91;height: 32px;width: 104px;text-align: center;div :idcontainerId-mover :classshowMoverTask?uploadty-mover-mask:movety-opt stylemargin-top: 12pxa clickmoveLast stylemargin: 0 5px;a-icon typearrow-left stylecolor: #fff;font-size: 16px//aa clickmoveNext stylemargin: 0 5px;a-icon typearrow-right stylecolor: #fff;font-size: 16px//a/div/div!-- ---------------------------- end 图片左右换位置 ------------------------------------- --a-uploadnamefile:multiplemultiple:actionuploadAction:headersheaders:data{biz:bizPath}:fileListfileList:beforeUploaddoBeforeUploadchangehandleChange:disableddisabled:returnUrlreturnUrl:listTypecomplistTypepreviewhandlePreview1:showUploadList{showRemoveIcon: true,showDownloadIcon: true}:class{uploadty-disabled:disabled}templatediv v-ifisImageCompa-icon typeplus /div classant-upload-text{{ text }}/div/diva-button v-else-ifbuttonVisiblea-icon typeupload /{{ text }}/a-button/template/a-uploada-modal :visiblepreviewVisible :footernull cancelhandleCancelimg altexample stylewidth: 100% :srcpreviewImage //a-modala-modal :visiblepreviewVisibleForAll :footernull cancelhandleCancelAll :width800 :maskClosablemaskClosable :keyboardkeyboardimg altexample stylewidth: 100%;margin-top:20px :srcpreviewFileSrc v-ifisImage/div v-ifisPdf styleoverflow-y: auto;overflow-x: hidden;a-button shaperound iconfile-pdf clickhandlePrint(printData) sizesmall打印/a-buttondiv idprintFrompdf refpdf v-foritem in pageTotal:srcpreviewFileSrc:keyitem:pageitem/pdf/div/div/a-modal/div
/templatescriptimport Vue from vueimport { ACCESS_TOKEN } from /store/mutation-typesimport { getFileAccessHttpUrl } from /api/manage;import pdf from vue-pdfimport printJS from print-jsconst FILE_TYPE_ALL allconst FILE_TYPE_IMG imageconst FILE_TYPE_TXT fileconst uidGenerator(){return -parseInt(Math.random()*100001,10);}const getFileName(path){if(path.lastIndexOf(\\)0){let regnew RegExp(\\\\,g);path path.replace(reg,/);}return path.substring(path.lastIndexOf(/)1);}export default {name: JUpload,components: { pdf },data(){return {printData: {printable: printFrom,header: ,ignore: [no-print]},uploadAction:window._CONFIG[domianURL]/sys/common/upload,headers:{},fileList: [],newFileList: [],uploadGoOn:true,previewVisible: false,//---------------------------- begin 图片左右换位置 -------------------------------------previewImage: ,containerId:,top:,left:,moveDisplay:none,showMoverTask:false,moverHold:false,currentImg:,//---------------------------- end 图片左右换位置 -------------------------------------previewVisibleForAll:false,pageTotal: null,previewFileSrc:,isImage:false,isExcel:false,isPdf:false,}},props:{text:{type:String,required:false,default:点击上传},fileType:{type:String,required:false,default:FILE_TYPE_ALL},/*这个属性用于控制文件上传的业务路径*/bizPath:{type:String,required:false,default:temp},value:{type:[String,Array],required:false},// update-begin- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击disabled:{type:Boolean,required:false,default: false},// update-end- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击//此属性被废弃了triggerChange:{type: Boolean,required: false,default: false},/*** update -- author:lvdandan -- date:20190219 -- for:Jupload组件增加是否返回url* true仅返回url* false返回fileName filePath fileSize*/returnUrl:{type:Boolean,required:false,default: true},number:{type:Number,required:false,default: 0},buttonVisible:{type:Boolean,required:false,default: true},multiple: {type: Boolean,default: true},beforeUpload: {type: Function},maskClosable: {type: Boolean,default:true,},keyboard: {type: Boolean,default:true,},},watch:{value:{immediate: true,handler() {let val this.valueif (val instanceof Array) {if(this.returnUrl){this.initFileList(val.join(,))}else{this.initFileListArr(val);}} else {this.initFileList(val)}}}},computed:{isImageComp(){return this.fileType FILE_TYPE_IMG},complistType(){return this.fileType FILE_TYPE_IMG?picture-card:text}},created(){const token Vue.ls.get(ACCESS_TOKEN);//---------------------------- begin 图片左右换位置 -------------------------------------this.headers {X-Access-Token:token};this.containerId container-ty-new Date().getTime();//---------------------------- end 图片左右换位置 -------------------------------------},methods:{handlePrint(params) {printJS({printable: params.printable, // printFrom, // 标签元素idtype: params.type || html,header: params.header, // 表单,targetStyles: [*],style: page {margin:0 10mm};, // 可选-打印时去掉眉页眉尾ignoreElements: params.ignore || [], // [no-print]properties: params.properties || null})},printPdf() {this.$refs.pdf.print()// window.print()},initFileListArr(val){console.log(val)if(!val || val.length0){this.fileList [];return;}let fileList [];for(var a0;aval.length;a){let url getFileAccessHttpUrl(val[a].filePath);fileList.push({uid:uidGenerator(),name:val[a].fileName,status: done,url: url,response:{status:history,message:val[a].filePath}})}this.fileList fileListconsole.log(this.fileList)},initFileList(paths){if(!paths || paths.length0){//return [];// update-begin- --- author:os_chengtgen ------ date:20190729 ---- for:issues:326,Jupload组件初始化bugthis.fileList [];return;// update-end- --- author:os_chengtgen ------ date:20190729 ---- for:issues:326,Jupload组件初始化bug}let fileList [];let arr paths.split(,)for(var a0;aarr.length;a){let url getFileAccessHttpUrl(arr[a]);fileList.push({uid:uidGenerator(),name:getFileName(arr[a]),status: done,url: url,response:{status:history,message:arr[a]}})}this.fileList fileList},handlePathChange(){let uploadFiles this.fileListlet path if(!uploadFiles || uploadFiles.length0){path }let arr [];for(var a0;auploadFiles.length;a){// update-begin-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时控制台报错if(uploadFiles[a].status done ) {arr.push(uploadFiles[a].response.message)}else{return;}// update-end-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时控制台报错}if(arr.length0){path arr.join(,)}this.$emit(change, path);},doBeforeUpload(file){this.uploadGoOntruevar fileType file.type;if(this.fileTypeFILE_TYPE_IMG){if(fileType.indexOf(image)0){this.$message.warning(请上传图片);this.uploadGoOnfalsereturn false;}}// 文件大小限定在600K以下const isLt2M file.size / 1024 / 1024 10;if (!isLt2M){this.$message.warning(请确保上传的文件小于10MB);this.fileList []this.uploadGoOnfalsereturn false;}// 扩展 beforeUpload 验证if (typeof this.beforeUpload function) {return this.beforeUpload(file)}return true},handleChange(info) {console.log(--文件列表改变--)if(!info.file.status this.uploadGoOn false){info.fileList.pop();}let fileList info.fileListif(info.file.statusdone){if(this.number0){fileList fileList.slice(-this.number);}if(info.file.response.success){fileList fileList.map((file) {if (file.response) {let reUrl file.response.message;file.url getFileAccessHttpUrl(reUrl);}return file;});}//this.$message.success(${info.file.name} 上传成功!);}else if (info.file.status error) {this.$message.error(${info.file.name} 上传失败.);}else if(info.file.status removed){this.handleDelete(info.file)}this.fileList fileListif(info.file.statusdone || info.file.status removed){//returnUrl为true时仅返回文件路径if(this.returnUrl){this.handlePathChange()}else{//returnUrl为false时返回文件名称、文件路径及文件大小this.newFileList [];for(var a0;afileList.length;a){// update-begin-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时控制台报错if(fileList[a].status done ) {var fileJson {fileName:fileList[a].name,filePath:fileList[a].response.message,fileSize:fileList[a].size};this.newFileList.push(fileJson);}else{return;}// update-end-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时控制台报错}this.$emit(change, this.newFileList);}}},handleDelete(file){//如有需要新增 删除逻辑console.log(file)},// handlePreview(file){// console.log(file)// console.log(file)// if(this.fileType FILE_TYPE_IMG){// this.previewImage file.url || file.thumbUrl;// this.previewVisible true;// }else{// if(file.name.endsWith(pdf) || file.name.endsWith(PDF)) {// let viewPath window._CONFIG[domianURL].replace(9999, 15550).replace(/jeecg-boot, ) / (file.url.replace(window._CONFIG[staticDomainURL] /, ))// console.log(viewPath)// window.open(viewPath,_blank)// this.isPdf true// this.previewFileSrc file.url// }// // else {//TODO:重新打开页面// // location.hreffile.url// // }// }// },// 获取pdf总页数getTotal() {// 多页pdf的src中不能直接使用后端获取的pdf地址 否则会按页数请求多次数据// 需要使用下述方法的返回值作为urlthis.previewFileSrc pdf.createLoadingTask(this.previewFileSrc)// 获取页码this.previewFileSrc.promise.then(pdf this.pageTotal pdf.numPages).catch(error {})},handlePreview1(file){if(this.fileType FILE_TYPE_IMG){this.previewImage file.url || file.thumbUrl;this.previewVisible true;}else{// 判断当前文件类型this.previewFileSrc file.url || file.thumbUrl; // http://localhost:9999/sys/common/static/orderPaymentInfo/网约区域复习题_1694585302732.pdflet fileTypeLocal this.matchFileType(file.name);this.isImage false;this.isPdf false;if(fileTypeLocal image) {this.previewVisibleForAll true;this.isImage true;} else if(fileTypeLocal pdf) {this.previewVisibleForAll true;this.isPdf true;this.getTotal()} else {location.hreffile.url}}},matchFileType(fileName) {// 后缀获取let suffix ;// 获取类型结果let result ;if (!fileName) return false;try {// 截取文件后缀suffix fileName.substr(fileName.lastIndexOf(.) 1, fileName.length)// 文件后缀转小写方便匹配suffix suffix.toLowerCase()} catch (err) {suffix ;}// fileName无后缀返回 falseif (!suffix) {result false;return result;}let fileTypeList [// 图片类型{typeName: image, types: [png, jpg, jpeg, bmp, gif]},// 文本类型{typeName: txt, types: [txt]},// excel类型{typeName: excel, types: [xls, xlsx]},{typeName: word, types: [doc, docx]},{typeName: pdf, types: [pdf]},{typeName: ppt, types: [ppt]},// 视频类型{typeName: video, types: [mp4, m2v, mkv]},// 音频{typeName: radio, types: [mp3, wav, wmv]}]// let fileTypeList [image, txt, excel, word, pdf, video, radio]for (let i 0; i fileTypeList.length; i) {const fileTypeItem fileTypeList[i]const typeName fileTypeItem.typeNameconst types fileTypeItem.typesconsole.log(fileTypeItem);result types.some(function (item) {return item suffix;});if (result) {return typeName}}return other},handleCancel(){this.previewVisible false;},handleCancelAll(){this.previewVisibleForAll false;this.isImage false;this.isPdf false;},//---------------------------- begin 图片左右换位置 -------------------------------------moveLast(){//console.log(ev)//console.log(this.fileList)//console.log(this.currentImg)let index this.getIndexByUrl();if(index0){this.$message.warn(未知的操作)}else{let curr this.fileList[index].url;let last this.fileList[index-1].url;let arr []for(let i0;ithis.fileList.length;i){if(iindex-1){arr.push(curr)}else if(iindex){arr.push(last)}else{arr.push(this.fileList[i].url)}}this.currentImg lastthis.$emit(change,arr.join(,))}},moveNext(){let index this.getIndexByUrl();if(indexthis.fileList.length-1){this.$message.warn(已到最后~)}else{let curr this.fileList[index].url;let next this.fileList[index1].url;let arr []for(let i0;ithis.fileList.length;i){if(iindex1){arr.push(curr)}else if(iindex){arr.push(next)}else{arr.push(this.fileList[i].url)}}this.currentImg nextthis.$emit(change,arr.join(,))}},getIndexByUrl(){for(let i0;ithis.fileList.length;i){if(this.fileList[i].url this.currentImg || encodeURI(this.fileList[i].url) this.currentImg){return i;}}return -1;}},mounted(){const moverObj document.getElementById(this.containerId-mover);if(moverObj){moverObj.addEventListener(mouseover,(){this.moverHold truethis.moveDisplay block;});moverObj.addEventListener(mouseout,(){this.moverHold falsethis.moveDisplay none;});}let picList document.getElementById(this.containerId)?document.getElementById(this.containerId).getElementsByClassName(ant-upload-list-picture-card):[];if(picList picList.length0){picList[0].addEventListener(mouseover,(ev){ev ev || window.event;let target ev.target || ev.srcElement;if(ant-upload-list-item-info target.className){this.showMoverTaskfalselet item target.parentElementthis.left item.offsetLeftthis.topitem.offsetTopitem.offsetHeight-50;this.moveDisplay block;this.currentImg target.getElementsByTagName(img)[0].src}});picList[0].addEventListener(mouseout,(ev){ev ev || window.event;let target ev.target || ev.srcElement;//console.log(移除,target)if(ant-upload-list-item-info target.className){this.showMoverTasktruesetTimeout((){if(this.moverHold false)this.moveDisplay none;},100)}if(ant-upload-list-item ant-upload-list-item-done target.className || ant-upload-list ant-upload-list-picture-card target.className){this.moveDisplay none;}})//---------------------------- end 图片左右换位置 -------------------------------------}},model: {prop: value,event: change}}
/scriptstyle langless
.uploadty-disabled{.ant-upload-list-item {.anticon-close{display: none;}.anticon-delete{display: none;}}
}//---------------------------- begin 图片左右换位置 -------------------------------------.uploadty-mover-mask{background-color: rgba(0, 0, 0, 0.5);opacity: .8;color: #fff;height: 28px;line-height: 28px;}//---------------------------- end 图片左右换位置 -------------------------------------
/style总结
除了以上两个组件库11的方式还有百度前端大神开发的vue-office组件库而且优点也很明显
使用简单对新手友好只传递一个文件地址就可实现预览。提供多种文件的一站式预览解决方案解决常见的docx、excel、pdf三种文件的预览。预览效果也好不只是对内容预览也要支持样式。
预览的效果确实超级棒可惜的是不支持打印功能不能满足需求可惜了。 有需要的可以去看vue-office的演示效果 Vue框架演示效果 非Vue框架文件预览
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88754.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!