vue 展示pdf文件内容,
最近项目里想做一个pdf在线预览功能,所以想给大家整理一个全面的。本文主要介绍了在vue项目中实现三种常见文件类型在线预览的相关信息。文件类型有pdf/word文件/excel表格,有需要的可以参考。
目录
前言1。预览word文件1。安装npm依赖关系2。预览在线地址文件3。预览本地文件2。预览excel表格1。安装依赖关系2。预习在线表格3。预览pdf 1。安装依赖项vue-pdf2。在要求的第3页注册。使用4。加载本地pdf文件5。用自定义字体:pdfjsWrapper.js解决pdf预览和打印的乱码问题
前言
之前一直用于Pdf预览的Pdf.js,这次更简单更简单,没有太多额外要求,所以我决定使用vue-pdf作为组件。虽然没有原生那么强大,但是已经满足了常见的需求。重要的是这个组件使用起来很简单。顺便还整理了word文件和excel表格的预览。接下来,我们直接进入正题!
一、预览word文件
1.安装 npm 依赖
npm i docx-preview@0.1.4
npm i jszip
2.预览在线地址文件
模板
div class=home
div ref=file/div
/div
/模板
脚本
从“axios”导入axios
const docx=require( docx-preview );
窗户。JSZip=require(jszip )
导出默认值{
已安装(){
axios({
方法:“get”,
ResponseType: blob ,//设置响应文件格式
URL:“/docx”,
}).然后(({data})={
Doc.renderasync(数据,这个。$ refs . file)//呈现到页面预览
})
}
}
/脚本
3.预览本地文件
模板
div class=我的组件 ref=预览
输入类型= file @ change= preview ref= file
/div
/模板
脚本
const docx=require( docx-preview );
窗户。JSZip=require(jszip )
导出默认值{
方法:{
预览(e){
Doc.renderasync (this。$ refs.file.files [0],this。$ refs . preview)//呈现到页面预览
}
}
};
/脚本
style lang=less 范围。我的组件{
宽度:100%;
身高:90vh
边框:1px纯色# 000;
}
/风格
二、预览excel表格
1.安装依赖
npm i xlsx
2.预览在线表格
模板
div class=home
div v-html=tableau/div
/div
/模板
脚本
从“axios”导入axios
从“XLSX”导入XLSX;
导出默认值{
data(){
返回{
tableau:空,
}
},
已安装(){
axios.get(/xlsx ,{
ResponseType: arraybuffer ,//将响应正文类型设置为arraybuffer
}).然后(({data})={
let workbook=xlsx . read(new uint 8 array(data),{ type: array });//解析数据
var工作表=工作簿。工作表[工作簿。工作表名称[0]];//工作簿。SheetNames在该文件中存储每个工作表的名称。这里,拿出第一张工作表。
this . tableau=xlsx . utils . sheet _ to _ html(工作表);//渲染
})
}
}
/脚本
三、pdf预览
1.安装依赖vue-pdf
npm安装-保存vue-pdf
2.在需要的页面注册
脚本
从“vue-pdf”导入PDF
导出默认值{
组件:{
PDF,
},
data(){
返回{
}
}
/脚本
3.使用
一般预览pdf的时候,页面比较多。为了提高性能,可以进行分页符。Page:当前显示的页数,如第一页page=1;旋转:旋转角度,如0表示不旋转,90,-90表示水平旋转。进度:当前页面的加载进度,范围从0到1。当它等于1时,意味着当前页面已经被完全加载。页面加载:成功加载页面的回调函数,不容易使用。Num-pages:总页数;错误:加载了错误的回调链接-单击:独立pdf中的链接将触发。这是打印功能。(注意:谷歌Chrome预览时会出现乱码。这个问题是由于在pdf中使用自定义字体造成的。要解决问题,应该替换node _ modules/vue-pdf/src/pdfjsWrapper.js,我把替换的pdfjswrapper . js放在文章的最后)
!-预览PDF -
El-dialog v-dialog drag:visible . sync= preview dialog
模板
差异
工具
El-button:theme= default type= submit :title= 上一页@点击。stop= prePage class= mr10 上一页/el-button
El-button:theme= default type= submit :title= 下一页@点击。stop=下一页 class= mr10 下一页/el-button
div class= page " { pageNum } }/{ { page total num } }/div
El-button:theme= default type= submit :title= 顺时针旋转@click.stop=clock class=mr10 顺时针旋转/el-button
El-button:theme= default type= submit :title= 逆时针旋转@点击。停止=计数器锁定 class= mr10 逆时针旋转/el-button
El-button:theme= default type= submit :title= 打印@点击。stop= pdf打印全部 class= mr10 打印/el-button
/div
pdf ref= pdf :src= URL :page= pageNum :rotate= page rotate @ progress= loaded ratio=$ event @ page-loaded= page loaded($ event)
@ num-pages= page total num=$ event @ error= pdfError($ event) @ link-clicked= page=$ event /pdf
/div
/模板
/el-dialog
脚本
从" vue-pdf "导入便携文档格式
导出默认值{
组件:{
PDF,
},
data(){
返回{
previewDialog:false,
网址: http://存储。xuetangx。com/public _ assets/xuetangx/PDF/player API _ v 1。0 .6 . PDF ,
pageNum: 1,
pageTotalNum: 1,
pageRotate: 0,
//加载进度
loadedRatio: 0,
curPageNum: 0,
},
方法:{
/**
* 预览便携文档格式
*/
预览PDF(行,索引){
this.previewDialog=true
console.log( ,行,索引);
},
//上一页函数,
prePage() {
var page=this.pageNum
页面=第一页?第一页:this.pageTotalNum
this.pageNum=page
},
//下一页函数
nextPage() {
var page=this.pageNum
page=page this.pageTotalNum?第一页:1
this.pageNum=page
},
//页面顺时针翻转90度。
时钟(){
this.pageRotate=90
},
//页面逆时针翻转90度。
逆时针(){
this.pageRotate -=90
},
//页面加载回调函数,其中e为当前页数
页面加载(e) {
this.curPageNum=e
},
//错误时回调函数。
pdfError(错误){
控制台.错误(错误)
},
//打印全部
pdfPrintAll() {
/**
* 打印界面字符乱码是因为你可移植文档格式文件的扩展名(可移植文档格式的缩写)中使用了自定义字体导致的,谷歌浏览器打印的时候预览界面真的变成了真方块字,解决方案如下:
* 用文章最后的pdfjsWrapper.js在替换掉节点模块/vue-pdf/src/pdf js包装器。射流研究…
*/
console.log(打印);
这个. refs.pdf.print()
},
},
}
/脚本
4.加载本地pdf文件
如果需要加载本地可移植文档格式文件的扩展名(可移植文档格式的缩写)文件(不需要则不用配置),需要我们做一下本地配置快速装载机才行,否则工具无法编译可移植文档格式文件的扩展名(可移植文档格式的缩写)类型的文件,配置方法也很简单,在项目根目录找到vue。配置。射流研究…文件(若没有则在根目录下新建一个vue.config.js)。之后再url:require(…/assets/xxx.pdf )就没有任何问题了,注意,vue-pdf src接收的是线对象,如果直接传全球资源定位器(统一资源定位器)这里报错了,需要传网址。默认值一下。
先安装文件加载器
新公共管理安装-保存文件-加载器
然后在vue。配置。射流研究…中加入以下内容:
模块。导出={
chainWebpack: config={
const文件规则=配置。模块。规则(“文件”)
fileRule.uses.clear()
文件规则。测试(/\。pdfico$/)。使用("文件加载器")。加载器("文件加载器")。选项({
限额:10000,
})
},
公共路径:""。/
}
5.解决pdf使用自定义字体预览和打印乱码问题:pdfjsWrapper.js
从" pdfjs-dist/es5/web/pdf_viewer "导入{ PDFLinkService };
var待定操作=承诺。resolve();
导出默认函数(PDFJS) {
函数isPDFDocumentLoadingTask(obj) {
返回typeof(obj)===object obj!==空对象._ _ PDFDocumentLoadingTask===true;
//或者:返回obj。构造函数。name==== PDFDocumentLoadingTask ;
}
函数createLoadingTask(src,选项){
定义变量来源;
if ( typeof(src)===string )
source={ URL:src };
else if(uint 8数组的科学研究委员会实例)
source={ data:src };
else if(type of(src)=== object src!==null)
source=Object.assign({},src);
其他
引发新类型错误(“无效的科学研究委员会类型");
//source.verbosity=PDFJS .verbositoylevel。INFOS
//来源。pdfbug=true
//来源。stopaterrors=true
if(选项选项。有凭据)
来源。有凭证=选项。有凭据;
var加载任务=pdf js。获取文档(来源);
正在加载任务_ _ PDFDocumentLoadingTask=true//因为PDFDocumentLoadingTask不是公共的
if ( options options.onPassword)
正在加载任务。密码=选项。关于密码;
如果(选项options.onProgress)
正在加载任务。进行中=选项。关于进展;
返回加载任务
}
函数PDFJSWrapper(canvasElt,annotationLayerElt,emitEvent) {
var pdfDoc=null
var pdfPage=null
var pdfRender=null
定义变量取消=假
canvasElt.getContext(2d ).save();
函数clearCanvas() {
canvasElt.getContext(2d ).clearRect(0,0,canvasElt.width,canvasElt。身高);
}
函数clearAnnotations() {
while(annotationlayerelt。第一个孩子)
annotationlayerelt。移除子级(annotationlayerelt。第一胎);
}
this.destroy=function() {
if ( pdfDoc===null)
返回;
//中止所有网络请求并销毁工作线程。
待定操作=pdf文档。destroy();
pdfDoc=null
}
这个。getresolutionscale=function(){
返回canvaselt。offsetwidth/canvaselt。宽度;
}
this.printPage=function(dpi,pageNumberOnly) {
if ( pdfPage===null)
返回;
//1in==72pt
//1in==96px
var PRINT _ RESOLUTION=dpi===undefined?150:dpi;
var PRINT _ UNITS=PRINT _ RESOLUTION/72.0;
var CSS _ UNITS=96.0/72.0;
var printContainerElement=document。createelement( div );
printcontainerelement。设置属性(“id”、“打印容器”)
函数removePrintContainer() {
printContainerElement。父节点。移除子元素(printContainerElement);
}
新承诺(功能(解决,拒绝){
printcontainerelement。frame border=" 0
printcontainerelement。scrolling=“否”;
printcontainerelement。width= 0px
printcontainerelement。height= 0px
printcontainerelement。风格。CSS text= position:absolute;top:0;左:0 ;
窗户。文档。身体。appendchild(printContainerElement);
解决(窗口)
})。然后(函数(win) {
赢了。文档。title=
返回pdfDoc.getPage(1)。然后(功能(页面){
var viewport=page。获取视口({ scale:1 });
printcontainerelement。appendchild(赢。文档。createelement( style ).文本内容=
@supports((尺寸:A4)和(size:1pt 1pt)) {
@ page { margin:1pt;大小:“((视口。width * PRINT _ UNITS)/CSS _ UNITS) pt ((viewport。height * PRINT _ UNITS)/CSS _ UNITS) pt;}
}
#print-canvas { display: none }
@media print {
正文{ margin: 0 }
# print-canvas { page-break-before:avoid;分页后:总是;分页符-内部:避免;显示:block }
body *:not(#打印容器){ display:无;}
}
@媒体屏幕{
正文{ margin: 0 }
}
回赢;
})
})。然后(函数(win) {
var all pages=[];
for(var页码=1;页码=pdf文档。数字;页码){
if ( pageNumberOnly!==未定义的仅页码。(页码)的索引===-1
继续;
allPages.push(
pdfDoc.getPage(页码)。然后(功能(页面){
var viewport=page。获取视口({ scale:1 });
var printCanvasElt=printcontainerelement。appendchild(赢。文档。createelement( canvas );
printcanvaselt。设置属性(“id”、“print-canvas”)
printcanvaselt。宽度=(视口。宽度*打印_单位);
printcanvaselt。高度=(视口。高度*打印_单位);
return page.render({
canvasContext:printcanvaselt。获取上下文(“2d”),
转换:[ //附加转换,在视口转换之前应用。
打印单位,0,0,
打印单位,0,0
],
视口:视口,
意图:"打印"
}).承诺;
})
);
}
无极. all(所有页面)。then(function() {
赢了。焦点();//对于工业管理学(Industrial Engineering)是必需的
如果(赢了。文档。支持的查询命令( print ){
赢了。文档。exec命令( print ,false,null);
}否则{
赢了。print();
}
removePrintContainer();
})。接住(函数(错误){
removePrintContainer();
emitEvent(error ,err);
})
})
}
这个。呈现页面=函数(旋转){
如果(pdfRender!==null ) {
如果(取消)
返回;
取消=真;
pdfRender.cancel().接住(函数(错误){
emitEvent(error ,err);
});
返回;
}
if ( pdfPage===null)
返回;
var page rotate=(pdf page。旋转===未定义?0 : pdfPage.rotate) (rotate===未定义?0:旋转);
var scale=canvaselt。offsetwidth/pdf页面。获取视口({ scale:1 }).宽度*(窗口。devicepixelrratio 1);
var viewport=pdf页面。get viewport({ scale:scale,rotation:page rotate });
emitEvent(page-size ,viewport.width,viewport.height,scale);
canvaselt。宽度=视口。宽度;
canvaselt。高度=视口。身高;
pdfRender=pdfPage.render({
canvaselt。获取上下文(“2d”),
视口:视口
});
annotationlayerelt。风格。可见性=隐藏;
清除批注();
var viewer={
scrollPageIntoView:函数(参数){
emitEvent(link-clicked ,params.pageNumber)
},
};
var link service=new PDFLinkService();
链接服务。设置文档(pdf文档);
linkService.setViewer(查看器);
待定操作=待定操作。then(function(){
var getAnnotationsOperation=
pdf页面。获取注释({ intent: display })。然后(功能(注释){
PDFJS .AnnotationLayer.render({
视口:视口。克隆({ don tflip:true }),
div: annotationLayerElt,
注释:注释,
page: pdfPage,
linkService: linkService,
renderInteractiveForms: false
});
});
var pdfRenderOperation=
承诺。then(function() {
annotationlayerelt。风格。可见性=" ";
取消=假;
pdfRender=null
})。接住(函数(错误){
pdfRender=null
PDFJS的实例.RenderingCancelledException ) {
取消=假;
this.renderPage(旋转);
返回;
}
emitEvent(error ,err);
}.绑定(这个))
回报承诺。all([getannotationsooperation,pdfrenderroperation]);
}.绑定(这个));
}
这个。foreach page=function(页面回调){
var numPages=pdfDoc.numPages
(下一个函数(pageNum) {
pdfDoc.getPage(pageNum)。然后(页面回调)。then(function() {
if ( pageNum=numPages)
下一个(pageNum);
})
})(1);
}
这个。load page=function(页码,旋转){
pdfPage=null
if ( pdfDoc===null)
返回;
待定操作=待定操作。then(function(){
返回pdf文档。获取页面(页码);
})。然后(功能(页面){
pdfPage=page
this.renderPage(旋转);
emitEvent(page-loaded ,页面。页码);
}.绑定(这个))。接住(函数(错误){
清除画布();
清除批注();
emitEvent(error ,err);
});
}
这个。加载文档=函数(src){
pdfDoc=null
pdfPage=null
emitEvent(页数,未定义);
如果(!src ) {
canvaselt。删除属性(“width”);
canvaselt。删除属性(“height”);
清除批注();
返回;
}
//等待挂起的操作结束
待定操作=待定操作。then(function(){
var加载任务
if(isPDFDocumentLoadingTask(src)){
if ( src.destroyed ) {
emitEvent(error),new Error(loadingTask已销毁));
返回
}
loadingTask=src
}否则{
加载任务=创建加载任务(src,{
密码:函数(更新密码,原因){
var reasonStr
开关(原因){
案例PDFJS .密码响应。需要密码:
reasonStr=需要密码
打破;
案例PDFJS .密码响应。错误密码:
reason str= error _ PASSWORD ;
打破;
}
emitEvent(password ,updatePassword,reason str);
},
正在进行:功能(状态){
定义变量比率=状态.已加载/状态.总计
emitEvent(progress ,Math.min(ratio,1));
}
});
}
返回loadingTask .无极
})。然后(函数(pdf) {
pdfDoc=pdf
emitEvent(页数,pdf。numpages);
发出事件(“已加载”);
})。接住(函数(错误){
清除画布();
清除批注();
emitEvent(error ,err);
})
}
annotationlayerelt。风格。转换原点=“0 0”;
}
返回{
createLoadingTask:createLoadingTask,
PDFJSWrapper: PDFJSWrapper,
}
}
总结
关于vue项目中三种常见文件类型在线预览的实现,本文到此为止。更多vue文件的相关在线预览,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。