这里写自定义目录标题
简介
项目需求有显示excel的功能,经过一番讨论后,得到有几种方案,最终定下来的方案是在后端将excel文档转换成pdf后再在前端进行显示。遂准备在项目中整合pdfjs库。在整合的过程中遇到几个问题,特此记录下。
在项目中安装pdfjs库
# 笔者这里使用的是npm包管理工具,故后面所有的包管理工具都默认为使用npm
# 安装pdfjs
npm install pdfjs-dist
通过pdfjs库封装pdf显示组件
<script setup lang="ts">
import {nextTick, onMounted, ref, watch} from "vue";
import {getDocument, GlobalWorkerOptions} from "pdfjs-dist";
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.min.mjs'
const props = defineProps(["url", "showPageList"])
const canvasRef = ref()
onMounted(() => {
watch(props, (value, oldValue, onCleanup) => {
// 如果有设置显示内容,就开始显示
if (props.url && props.showPageList.length > 0) loadPdf()
}, {immediate: true})
})
const loadPdf = () => {
nextTick(async () => {
GlobalWorkerOptions.workerSrc = pdfjsWorker.default
const pdf = await getDocument(props.url).promise
const page = await pdf.getPage(props.showPageList[0]) // 设置显示页
const viewport = page.getViewport({scale: 1})
// Render PDF page into canvas context
page.render({
canvasContext: canvasRef.value.getContext("2d"),
viewport: viewport
});
})
}
</script>
<template>
<div class="show_sop">
<canvas ref="canvasRef"/>
</div>
</template>
<style scoped lang="stylus">
.show_sop
width 100%
height 100%
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)
canvas
width 100%
height 100%
</style>
遇到的问题
上面的组件只是一个很简单的例子,用于指定显示pdf文件中的哪几页,pdfjs这个库还有很多其他的功能笔者暂时还没时间去挖掘。
但是还没运行时就遇到一个问题,只见控制台发生了一个错误
http://localhost:5173/node_modules/.vite/deps/pdfjs-dist.js?v=6a8263ac net::ERR_ABORTED 504 (Outdated Optimize Dep)
看了一眼ide中的控制台。发现真实错误为 vite 不支持顶级的 async/await 语法,
Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)
node_modules/pdfjs-dist/build/pdf.mjs:17349:53:
17349 │ /******/ __webpack_exports__ = globalThis.pdfjsLib = await (globalThis.pdfjsLibPromise = __webpack_exports__);
问题的解决
需要在项目中安装topLevelAwait插件做兼容
# 安装topLevelAwait插件
npm install vite-plugin-top-level-await -D
修改项目根目录下的vite.config.ts文件,在这个文件中的plugins属性内导入刚刚安装的插件即可正常显示
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import topLevelAwait from "vite-plugin-top-level-await";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), topLevelAwait({promiseExportName: '__tla', promiseImportName: (i) => `__tla_${i}`})],
})