背景:需要使用web显示pdf文件
技术栈:vue2.x vue-cli3.x+
大坑1:使用vue-pdf
- 分页加载,大文件加载,比如加载一个300M的pdf直接崩溃,报错
- github官网运行不起来
大坑2:直接使用pdfjs-dist
基于vue-pdf不符合需求,看了看看vue-pdf源码,什么玩意,封装的组件都看不明白,而且还有bug
pdfjs-dist没有vue example,看了半天其他的文档,官网的文档也写的贼烂。。。
直接使用报下面错误
> pdfjs-dist@0.1.0 serve
> vue-cli-service serve
INFO Starting development server...
98% after emitting CopyPlugin
ERROR Failed to compile with 3 errors 00:29:54
error in ./node_modules/pdfjs-dist/build/pdf.js
Module parse failed: Unexpected character '#' (1387:9)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| class PDFDocumentLoadingTask {
> static #docId = 0;
|
| constructor() {
@ ./node_modules/cache-loader/dist/cjs.js??ref--13-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js& 12:0-39 16:0-28 27:19-39 84:28-48
@ ./src/App.vue?vue&type=script&lang=js&
@ ./src/App.vue
@ ./src/main.js
@ multi (webpack)-dev-server/client?http://192.168.1.6:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js
error in ./node_modules/pdfjs-dist/build/pdf.sandbox.js
Module parse failed: Unexpected token (162:47)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| return this.exportValueToSandbox(result);
| } catch (error) {
> throw this.createErrorForSandbox(error?.toString() ?? "");
| }
| };
@ ./node_modules/cache-loader/dist/cjs.js??ref--13-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js& 15:0-64 44:35-47
@ ./src/App.vue?vue&type=script&lang=js&
@ ./src/App.vue
@ ./src/main.js
@ multi (webpack)-dev-server/client?http://192.168.1.6:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js
error in ./node_modules/pdfjs-dist/web/pdf_viewer.js
Module parse failed: Unexpected token (342:37)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| function fixupLangCode(langCode) {
> return PARTIAL_LANG_CODES[langCode?.toLowerCase()] || langCode;
| }
|
@ ./node_modules/cache-loader/dist/cjs.js??ref--13-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js& 13:0-57 27:44-65 46:29-49 48:35-61 52:38-67 57:40-71 61:30-51
@ ./src/App.vue?vue&type=script&lang=js&
@ ./src/App.vue
@ ./src/main.js
@ multi (webpack)-dev-server/client?http://192.168.1.6:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js
原因: vue-cli babel-loader默认不重新打包node_modules里面的模块
解决办法:vue.config.js 导出的配置中添加 transpileDependencies: ['pdfjs-dist']即可,具体往下看有详细解析
大坑3:使用pdfjs-dist的legacy
在低版本的chrome部分pdf文件没有被解析出来,报错不支持
好吧,慢慢看看
下面给能用的写法,网上好多都不可以使用
安装模块 pdfjs-dist
pdf.js npm 版本就是 pdfjs-dist
目前最新文档的版本是 pdfjs-dist@2.14.305
npm install pdfjs-dist@2.14.305
配置vue.config.js 这不一定不能落下,不然直接报错,不解析语法
默认vue-cli忽略node_modules
vue.config.js
module.exports = {
// 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。你可以启用本选项,以避免构建后的代码中出现未转译的第三方依赖。
// 不过,对所有的依赖都进行转译可能会降低构建速度。如果对构建性能有所顾虑,你可以只转译部分特定的依赖:给本选项传一个数组,列出需要转译的第三方包包名或正则表达式即可。
transpileDependencies: ['pdfjs-dist']
};
编写vue组件,完整代码如下
<template>
<div id="app">
<div id="pageContainer" style="position: absolute">
<div id="viewer"></div>
</div>
</div>
</template>
<script>
import "pdfjs-dist/web/pdf_viewer.css";
import * as pdfjsLib from "pdfjs-dist";
import * as pdfjsViewer from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/build/pdf.worker.entry";
import * as pdfjsSandbox from "pdfjs-dist/build/pdf.sandbox.js";
pdfjsLib.GlobalWorkerOptions.workerSrc = window.pdfjsWorker;
export default {
name: "App",
components: {},
async mounted() {
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
// eslint-disable-next-line no-alert
alert(
"Please build the pdfjs-dist library using\n `gulp dist-install`"
);
}
// Some PDFs need external cmaps.
// const CMAP_URL = './cmaps/';
const CMAP_URL = "./cmaps/";
const CMAP_PACKED = true;
const DEFAULT_URL = "./compressed.tracemonkey-pldi-09.pdf";
// To test the AcroForm and/or scripting functionality, try e.g. this file:
// "../../test/pdfs/160F-2019.pdf"
const ENABLE_XFA = true;
const SEARCH_FOR = ""; // try "Mozilla";
// const SANDBOX_BUNDLE_SRC =
// '../../node_modules/pdfjs-dist/build/pdf.sandbox.js';
const SANDBOX_BUNDLE_SRC = pdfjsSandbox;
const container = document.getElementById("pageContainer");
const eventBus = new pdfjsViewer.EventBus();
// (Optionally) enable hyperlinks within PDF files.
const pdfLinkService = new pdfjsViewer.PDFLinkService({
eventBus,
});
// (Optionally) enable find controller.
const pdfFindController = new pdfjsViewer.PDFFindController({
eventBus,
linkService: pdfLinkService,
});
// (Optionally) enable scripting support.
const pdfScriptingManager = new pdfjsViewer.PDFScriptingManager({
eventBus,
sandboxBundleSrc: SANDBOX_BUNDLE_SRC,
});
const pdfViewer = new pdfjsViewer.PDFViewer({
container,
eventBus,
linkService: pdfLinkService,
findController: pdfFindController,
scriptingManager: pdfScriptingManager,
enableScripting: true, // Only necessary in PDF.js version 2.10.377 and below.
});
pdfLinkService.setViewer(pdfViewer);
pdfScriptingManager.setViewer(pdfViewer);
eventBus.on("pagesinit", function () {
// We can use pdfViewer now, e.g. let's change default scale.
pdfViewer.currentScaleValue = "page-width";
// We can try searching for things.
if (SEARCH_FOR) {
eventBus.dispatch("find", { type: "", query: SEARCH_FOR });
}
});
// Loading document.
const loadingTask = pdfjsLib.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
enableXfa: ENABLE_XFA,
});
const pdfDocument = await loadingTask.promise;
// Document loaded, specifying document for the viewer and
// the (optional) linkService.
pdfViewer.setDocument(pdfDocument);
pdfLinkService.setDocument(pdfDocument, null);
},
};
</script>
<style>
#pageContainer {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
#pageContainer .page {
position: relative;
border: 1px solid black;
margin-bottom: 20px;
overflow: hidden;
box-sizing: border-box;
}
</style>