首页 > 其他分享 >vue3+vite使用vue-pdf-embed或者pdf-vue3预览 PDF 文件(能躲避 XSS 攻击,需要 pdf 文件的 base64 或者字节数组形式)

vue3+vite使用vue-pdf-embed或者pdf-vue3预览 PDF 文件(能躲避 XSS 攻击,需要 pdf 文件的 base64 或者字节数组形式)

时间:2024-02-26 10:44:22浏览次数:17  
标签:文件 vue const import vue3 pdf embed

1.使用vue-pdf-embed

1.npm 安装所需插件
npm i [email protected]
npm i [email protected]
2.封装组件(创建pdfPriview.index 文件)
<template>
  <div class="pdf-preview">
	<vue-pdf-embed
	  :source="state.source"
	  v-for="page in state.numPages"
	  :page="page"
	  :key="page"
	  textLayer
	></vue-pdf-embed>
  </div>
</template>
<script setup lang="ts">
import { reactive, onMounted, computed, ref } from 'vue';
import VuePdfEmbed from 'vue-pdf-embed';
import { createLoadingTask } from 'vue3-pdfjs';
import { getFileInfoIO } from '@/api/file/index';

const props = defineProps({
  pdfUrl: {
	type: String
  },
  pdfId: {
	type: Number
  }
});

const state = reactive({
  source: undefined,
  pageNum: 1,
  scale: 1, // 缩放比例
  numPages: 0 // 总页数
});

onMounted(() => {
  if (props.pdfId) {
	getFileInfoIO(props.pdfId)
	  .then((fileInfoRes) => {
		const binaryString = atob(fileInfoRes?.data);
		const bytes = new Uint8Array(binaryString.length);
		for (let i = 0; i < binaryString.length; i++) {
		  bytes[i] = binaryString.charCodeAt(i);
		}
		const blob = new Blob([bytes], { type: 'application/octet-stream' });
		const fileStream = URL.createObjectURL(blob);
		console.log('fileStream', fileStream);
		state.source = fileStream;
		const loadingTask = createLoadingTask(fileStream);
		loadingTask.promise.then((pdf: { numPages: number }) => {
		  state.numPages = pdf.numPages;
		});
	  })
	  .catch(() => {});
  }
});
</script>
<style lang="css" scoped>
.vue-pdf-embed {
  text-align: center;
  width: 515px;
  margin: 0 auto;
  box-sizing: border-box;
}

.pdf-preview {
  position: relative;
  height: 70vh !important;
  padding: 20px 0;
  box-sizing: border-box;
  background-color: e9e9e9;
}
.pdf-wrap {
  overflow-y: auto;
}
.vue-pdf-embed {
  text-align: center;
  width: 515px;
  margin: 0 auto;
  box-sizing: border-box;
}

.page-tool {
  position: absolute;
  bottom: 35px;
  padding-left: 15px;
  padding-right: 15px;
  display: flex;
  align-items: center;
  color: white;
  border-radius: 19px;
  z-index: 100;
  cursor: pointer;
  margin-left: 50%;
  transform: translateX(-50%);
}
.page-tool-item {
  padding: 8px 15px;
  padding-left: 10px;
  cursor: pointer;
}

body {
  padding: 16px;
  background-color: #ccc;
}

.vue-pdf-embed {
  margin: 0 auto;
}

.vue-pdf-embed__page {
  margin-bottom: 8px;
  box-shadow: 0 2px 8px 4px rgba(0, 0, 0, 0.1);
}
</style>
3.如何使用
import PdfPreview from '@/components/pdfPreview/index.vue';
<PdfPreview
  v-else-if="fileType == 'pdf'"
  :pdfId="previewOption.uid"
  :key="previewOption.uid"
></PdfPreview>

2.使用 pdf-vue3

1.npm 插件安装
npm i [email protected]
2.封装组件
<template>
  <div class="box" style="height: 70vh">
	<PDF :src="state.source" style="height: 70vh" />
  </div>
</template>

<script setup lang="ts">
import { reactive, onMounted, computed } from 'vue';
import { getFileInfoIO } from '/@/api/file/index';
import PDF from 'pdf-vue3';

const props = defineProps({
  pdfUrl: {
	type: String,
	default: '',
  },
  pdfId: {
	type: Number,
	default: '',
  },
});

const state = reactive({
  source: undefined,
  pageNum: 1,
  numPages: 1, // 总页数
});

onMounted(() => {
  if (props.pdfId) {
	try {
	  getFileInfoIO(props.pdfId)
		.then((fileInfoRes) => {
		  if (fileInfoRes && fileInfoRes.data) {
			state.source = fileInfoRes.data;
		  } else {
			console.error('fileInfoRes 或 fileInfoRes.data 为空');
		  }
		})
		.catch(() => {});
	} catch (error) {
	  console.log('vue-pdf-embed', error);
	}
  }
});
</script>

<style lang="less" scoped></style>
3.如何使用
import PdfPreview from '/@/components/pdfPreview/index.vue';
<PdfPreview
  v-else-if="fileType == 'pdf'"
  :pdfId="previewOption.uid"
  :key="previewOption.uid"
></PdfPreview>

注意:本组件是后端给了个 文件 id 接口,返回文件的 base64。

标签:文件,vue,const,import,vue3,pdf,embed
From: https://www.cnblogs.com/songkomei/p/18033821

相关文章

  • 经销商文件分发 如何兼顾安全和效率?
    经销商文件分发是指将文件、资料、产品信息等从制造商或经销商传递给经销商的过程。这一过程对于确保经销商能够获取最新的产品信息、销售策略、市场活动资料等至关重要。想要管理众多经销商合作伙伴之间的文件传输并提高效率,可以采取以下措施:1、建立标准化流程:制定清晰的文件......
  • 第八章 从源文件到可执行文件
    第八章主要讲述了从源文件到可执行文件的转换过程,即程序的编译和链接。以下是该章节的总结:编译和链接的操作需要使用编译器何链接器来完成,所以本章重点讲述编译器和链接器的功能,介绍了程序从编写到运行的整个过程。计算机只能执行本机代码:源代码是不能直接运行的,因为CPU能直接解......
  • 什么样的数据摆渡系统 可以实现跨网文件安全收发?
    随着网络技术和互联网技术的成熟和高速发展,来自互联网的安全威胁越来越严重。大多数企业为了防止内部核心数据泄露,内部都划分高密网和低密网进行隔离,确保网络间数据安全性。企业内部不同网络之间,以及企业内部网络和外部合作伙伴之间,数据交换是客观存在的需求,很多企业会采用传统......
  • powershell遍历文件获取字段列表
    #指定要搜索的文件夹路径和正则表达式关键字$folderPath="C:\myapp\"$table_list="tblBOM,tblTest"$tables=$table_list.Split(',')foreach($tablein$tables){$regexPattern_field="$table\.(\w+......
  • java实现scp功能实现目录下所有文件拷贝至指定服务器
    1、添加pom依赖<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version></dependency>2、示例代码publicstaticvoidmain(String[]args)throwsIOException{try{......
  • c#中bin,obj,properties文件夹的作用
    c#中bin,obj,properties文件夹的作用Bin目录用来存放编译的结果,bin是二进制binrary的英文缩写,因为最初C编译的程序文件都是二进制文件,它有Debug和Release两个版本,分别对应的文件夹为bin/Debug和bin/Release,这个文件夹是默认的输出路径,我们可以通过:项目属性—>配置属性—>输出路......
  • 使用defineAsyncComponent解决Vue3中的动态组件不显示问题
    参考:https://www.php.cn/faq/562208.html之前的写法<component:is='xxx'></component>异步加载组件<template><AsyncComponentv-if="item.data":key="item.data.comId"></AsyncComponent></template>&......
  • Vue3学习(十八) - TreeSelect 树选择
    写在前面本以为可以在家学习一天,结果家里来了客人拜年,就没学习上,有点小遗憾吧。昨天完成从分类管理的前后端代码复制出文档管理的前后端代码,遗留问题是只能选择一级父分类。值得说的是,昨晚的遗留的问题修复了,开心。遗留问题点击父文档,弹出警告,从报错来看那意思就是parent应该......
  • golang文件和目录操作
    读取文件通过Read方法读取import( "fmt" "os")funcmain(){ /* 打开文件 */ //以只读的方式打开文件,返回一个文件指针类型的对象和error file,err:=os.Open("./test.txt") //文件打开操作完之后必须关闭文件流,可以使用defer延迟关闭 deferfile.Close()......
  • 读取一个图片文件,显示在一个窗口(opencv生成的)
    //下面3行增加在CPP头部#include<opencv2/opencv.hpp>#include<opencv2/highgui/highgui_c.h>usingnamespacecv;//下面的代码添加在功能需要的地方,这个窗口和windows程序的窗口不一样,只是一个简单的将图片显示在一个独立的窗口。//菜单、按钮响应功能都可以......