| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- <template>
- <div class="vue_ppt" id="vue_ppt" ref="vuePpt">
- <!-- 上下两地址都能用 ——不稳定 -->
- <!-- :src="`https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(props?.fileMessage?.url)}`" -->
- <!-- <iframe
- class="ppt_iframe"
- v-else-if="['ppt','pptx'].includes(previewType)"
- :src="`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(props?.fileMessage?.url)}`"
- width="100%"
- height="100%"
- frameborder="0"
- ></iframe> -->
- <div v-if="pptLoading" class="loading_bg">
- <el-icon class="is-loading">
- <Loading />
- </el-icon>
- 加载中
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import {init} from 'pptx-preview'
- import { onMounted, ref,computed} from 'vue'
- const props = defineProps({
- fileMessage:{
- type:{
- url:String,
- name:String,
- }
- },
- initCourseLearnPage:{
- type:Number,
- required:false,
- default:0
- }
- })
- const emit = defineEmits(['pageChange','fileLoaded'])
- const vuePpt = ref()
- const pptLoading = ref(false)
- const pptxPrviewer = ref()
- const timeoutFlag = ref()
- const pageTotalHeight = ref()
- const currentReadHeight = ref()
- const progressPercent = computed(()=>{
- if(currentReadHeight.value == 0 || pageTotalHeight.value == 0){
- return 0
- }
- return Math.round((currentReadHeight.value / pageTotalHeight.value) * 100)
- })
- // 防抖
- // 不再连续滚动的时候,记录最后一次滚动的位置,
- // 200毫秒内没有再次滚动,就认为用户停止了滚动,此时记录用户的阅读进度
- const HandleScroll = (e)=>{
- console.log('页面监听滚动',e)
- if(timeoutFlag.value){
- clearTimeout(timeoutFlag.value)
- }
- timeoutFlag.value = setTimeout(() => {
- let totalHeight = e.target.scrollHeight //总高度
- let scrollTop = e.target.scrollTop //滚动高度
- let pageHeight = e.target.clientHeight // 客户端高度
- // 用户阅读进度 = ( pageHeight + scrollTop ) / totalHeight
- console.log('滚动事件',e)
- console.log('滚动高度',scrollTop)
- console.log('总高度',totalHeight)
- console.log('客户端高度',pageHeight)
- pageTotalHeight.value = Math.floor(Number(totalHeight)) || 0
- currentReadHeight.value = Math.floor( Number(pageHeight) + Number(scrollTop) ) || 0
- emit('pageChange',{currentProcess:progressPercent.value})
-
- clearTimeout(timeoutFlag.value)
- timeoutFlag.value = null
- }, 200);
- }
- const HandlePageRedirect = (dom)=>{
- console.log('滚动dom',dom)
- console.log('当前滚动进度--',props.initCourseLearnPage)
- // props.initCourseLearnPage
- // 根据百分比 换算滚动高度
- let totalHeight = dom.scrollHeight //总高度
- let pageHeight = dom.clientHeight // 客户端高度
- let realScroll = props.initCourseLearnPage * 0.01 * totalHeight - pageHeight
- let scrollTop = realScroll > 0 ? realScroll : 0
- console.log('高度 pageHeight / totalHeight',pageHeight,totalHeight)
- console.log('触发滚动了',scrollTop)
- dom.scrollTo({
- top: scrollTop,
- left: 0,
- behavior: 'smooth'
- });
-
- pageTotalHeight.value = Math.floor(Number(totalHeight)) || 0
- // 用户阅读进度 = ( pageHeight + scrollTop ) / totalHeight
- currentReadHeight.value = Math.floor( Number(pageHeight) + Number(scrollTop) ) || 0
- emit('pageChange',{currentProcess:progressPercent.value})
- }
- const HandlePptPreview =()=>{
- pptLoading.value = true
- //调用库的init方法生成一个预览器
- pptxPrviewer.value = init(vuePpt.value, {
- width: (vuePpt.value?.clientWidth * 0.8),
- // height: 540
- })
- //获取文件或者读取文件,获取文件的 ArrayBuffer格式数据,传给组件进行预览
- fetch(props?.fileMessage?.url).then(response=>{
- return response.arrayBuffer()
- }).then(res =>{
- console.log('获取文件完成',res)
- // 在这里监听文档的滚动
- let pptDom = document.querySelectorAll('.vue_ppt')
- console.log('dom',pptDom)
- //调用预览器的preview方法
- pptxPrviewer.value.preview(res).then(previewRes=>{
- console.log('转换结果',previewRes)
- HandlePageRedirect(pptDom[0])
- pptLoading.value = false
- emit('fileLoaded')
- }).catch(err=>{
- // 解析失败
- pptLoading.value = false
- })
- pptDom[0]?.addEventListener('scroll',
- (e)=>{
- HandleScroll(e)
- },false)
-
- }).catch(err=>{
- // 获取文件失败
- pptLoading.value = false
- })
- }
- onMounted(()=>{
- console.log('加载中')
- HandlePptPreview()
- })
- </script>
- <style lang="scss" scoped>
- .vue_ppt{
- display: flex;
- position: relative;
- flex-direction: column;
- align-items: center;
- justify-content: flex-start;
- min-height: 100%;
- overflow: auto;
- background-color: #e8eaee;
- .loading_bg{
- width: 100%;
- flex: 1 1;
- display: flex;
- justify-content: center;
- align-items: center;
- gap:3px;
- color:#2e64fa;
- }
- }
- </style>
- <style lang="scss">
- .vue_ppt{
- .pptx-preview-wrapper{
- height: auto !important;
- width: 80% !important; //主体宽度
- }
- }
- </style>
|