vuepress 整合pdf、word在线预览
2022年12月6日大约 5 分钟
npm 整合 pdf
安装
# 安装依赖
npm i pdfjs-dist
# vite引入
import * as pdfjsLib from "pdfjs-dist";
# webpack 引入方式
# const pdfjsLib = require("pdfjs-dist");页面
html
<template>
<canvas id="theCanvas"></canvas>
</template>js
import * as pdfjsLib from "pdfjs-dist";
export default {
data() {
return {};
},
mounted() {
const pdfPath = "/xxx.pdf";
pdfjsLib.getDocument(pdfPath).promise.then(function (pdfDocument) {
// 请求第一页
return pdfDocument.getPage(1).then(function (pdfPage) {
// 在现有画布上以 100% 比例显示页面。
const viewport = pdfPage.getViewport({ scale: 1.0 });
const canvas = document.getElementById("theCanvas");
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext("2d");
const renderTask = pdfPage.render({
canvasContext: ctx,
viewport,
});
return renderTask.promise;
});
});
},
methods: {},
};相关信息
vuepress 和 pdfjs 的依赖会产生冲突,报一些莫明奇妙的错,所以尝试使用 pdfjs 提供的构建包
构建包整合 pdf
安装
将构建包下载地址拷贝到项目静态资源目录下,本项目为 .vuepress/public/tool/pdfjs-dist/
访问 http://localhost:8080/tool/pdfjs-dist/web/viewer.html 验证是否可用
局部预览
- 创建组件
新建一个名为 MyPdfTool.vue 的文件,并注册为全局组件
<template>
<div>
<iframe
:src="'/tool/pdfjs-dist/web/viewer.html?file=' + finalBaseUrl"
:width="finalWidth"
:height="finalHeight"
></iframe>
</div>
</template>
<script>
export default {
props: {
width: {
type: String,
},
height: {
type: String,
},
baseUrl: {
type: String,
default: "", //pdf路径,也可以是网络pdf
},
},
data() {
return {
finalBaseUrl: "",
finalWidth: "",
finalHeight: "",
};
},
mounted() {
// 组件宽高赋值 -- 默认全屏
if (!this.width) this.finalWidth = window.innerWidth + "px";
else this.finalWidth = this.width;
if (!this.height) this.finalHeight = window.innerHeight + "px";
else this.finalHeight = this.height;
// 组件接收的pdf地址
if (this.$route.query.basePdfUrl) {
// 作为路由跳转
this.finalBaseUrl = this.$route.query.basePdfUrl;
} else if (this.baseUrl) {
// 作为组件引入
this.finalBaseUrl = this.baseUrl;
} else {
// 给个默认值意思一下
this.finalBaseUrl = "/document/pdf/Java开发手册(嵩山版).pdf";
}
},
methods: {},
};
</script>
<style lang="less" scoped></style>- 新建 docs/.vuepress/document/test.md;
## 局部预览示例
在md文档中引用组件实现局部预览,可自定义组件宽高
<MyPdfTool
baseUrl='/document/pdf/keyboard-vscode.pdf'
width='500px'
height="600px"/>- 访问 http://localhost:8080/document/test.md 即可局部查看 pdf 效果
局部预览示例
全屏预览-静态页面方式(推荐)
成功安装构建包后,直接访问:
http://localhost:8080/tool/pdfjs-dist/web/viewer.html?file=xxx.pdf 即可
相关信息
路径参数 file 可以是相对路径,也可以是网络资源路径
全屏预览-.md 方式
要在 vuepress 中实现全屏预览,必须禁用掉默认的所有主题效果,比如侧边栏等, 但是不能单独给一个具体的页面禁用主题;解决方法为自定义一个最简单的主题,并局部使用它自定义主题;
- 在 docs/.vuepress/theme/components 中创建一个主题容器 MyLayout.vue
<template>
<div>
<!--
<Content/> 是一个独特的vuepress全局组件 ,可展示当前的 .md 文件渲染的内容
-->
<Content />
</div>
</template>
<script>
export default {
name: "MyLayout",
};
</script>- 注册主题,编辑 client.ts
import { defineClientConfig } from "@vuepress/client";
import MyLayout from "./theme/components/MyLayout.vue";
export default defineClientConfig({
// 你可以在这里覆盖或新增布局
layouts: {
// 同时我们新增了一个 MyLayout 布局
MyLayout,
},
});- 在 docs/common/pdf-tool 中新建 README.md,并在其 Front Matter 中使用主题
---
lang: zh-CN
description: 通用的pdf查看页
layout: MyLayout
---
<MyPdfTool/>4.访问 http://localhost:8080/common/pdf-tool?basePdfUrl=xxx 即可全屏查看 pdf 效果
使用方法:路径跳转并携带参数
示例: /common/pdf-tool?basePdfUrl=pdf 路径
相关信息
为啥一定要单独新建 md 文件,直接给 MyPdfTool 组件添加一个路由不行吗?
因为 vuepress 用路由注册组件,不会被打包构建,也就是说只能在编译环境下访问;
整合 word
和整合 pdf 类似,直接 npm 引入会报一些莫名其妙的错,这里也直接使用静态引入的方式
安装
- 下载依赖
# word 预览插件
npm i docx-preview
# word 预览插件 需要的额外插件 js-zip 和 axios
npm i js-zip
# 下载axios
# https://github.com/axios/axios/archive/refs/tags/v1.2.1.zip- 拷贝依赖到项目静态目录
新建目录: docs/.vuepress/public/tool/docx-preview
相对于新建目录./
- 拷贝 node_model/docx-preview/ 的 dist 目录到./docx-dist
- 拷贝 node_model/js-zip/ 的 jszip.min.js 到./js-zip
- 解压下载的 axios.zip ,解压后拷贝 dist/** 到./axios
全屏预览
- 在 docs/.vuepress/public/tool/docx-preview 创建 viewer.html 文件
html
<body>
<div>
<a class="downLoad" id="downLoad">下载</a>
<div id="bodyContainer"></div>
</div>
</body>js
<!--lib uses jszip-->
<script src="../js-zip/jszip.min.js"></script>
<script src="../docx-dist/docx-preview.min.js"></script>
<script src="../axios/axios.min.js"></script>
<script>
// 从参数中获取docx实际路径
function getDocxUrlFromParams() {
var paramsDocxPath;
var paramsString = location.search;
// 如果有参数
if (paramsString.indexOf("?") != -1) {
if ("?docx-path" == paramsString.split("=")[0])
paramsDocxPath = paramsString.split("=")[1];
} else {
return "";
}
// 获取当前程序协议、域名、端口
var protocol = location.protocol; // 协议
var domain = document.domain; // 域名
var port = location.port; // 端口
var docxUrl;
// 如果docx-path是网络http全路径
if (paramsDocxPath.substring(0, 4) === "http") {
return paramsDocxPath;
}
// 如果docx-path是相对路径
if (port != 80) {
docxUrl = protocol + "//" + domain + ":" + port + paramsDocxPath;
} else {
docxUrl = protocol + "//" + domain + paramsDocxPath;
}
return docxUrl;
}
// 渲染docx到页面
var url = getDocxUrlFromParams();
if (url) {
axios({
method: "get",
responseType: "blob", // 设置响应文件格式
url,
})
.then(({ data }) => {
docx.renderAsync(data, document.getElementById("bodyContainer"));
})
.catch(function (error) {
console.log("此路径下,word文档不存在---" + url);
});
} else {
console.error("请携带路径参数:docx-path (docx文档路径) !");
}
document.getElementById("downLoad").onclick = function () {
window.location = url;
};
</script>css
<style>
.downLoad {
z-index: 10;
position: fixed;
top: 1rem;
right: 1rem;
margin: 0.6rem 0.8rem;
padding: 0.3rem 1.5rem;
border: 2px solid #3eaf7c;
background-color: #3eaf7c;
border-radius: 0.5rem;
color: #fff;
font-size: 1rem;
transition: color #f8f8f8, color #f8f8f8;
cursor: pointer;
}
</style>- 测试是否可用
http://localhost:8080/tool/docx-preview/web/viewer.html?docx-path=/document/docx/hello.docx
此页面需携带一个名为 docx-path 的路径参数,参数值为.docx 文件的路径,可以是相对路径,也可以是完整的 http 网络路径
局部预览
- 新建一个名为 MyDocxTool.vue 的文件,并注册为全局组件
<template>
<div>
<iframe
:src="'/tool/docx-preview/web/viewer.html?docx-path=' + finalBaseUrl"
:width="finalWidth"
:height="finalHeight"
></iframe>
</div>
</template>
<script>
export default {
props: {
width: {
type: String,
},
height: {
type: String,
},
baseUrl: {
type: String,
default: "",
},
},
data() {
return {
finalBaseUrl: "",
finalWidth: "",
finalHeight: "",
};
},
mounted() {
// 组件宽高赋值 -- 默认全屏
if (!this.width) this.finalWidth = window.innerWidth + "px";
else this.finalWidth = this.width;
if (!this.height) this.finalHeight = window.innerHeight + "px";
else this.finalHeight = this.height;
// 组件接收的docx地址
if (this.$route.query.baseDocxUrl) {
// 作为路由跳转
this.finalBaseUrl = this.$route.query.baseDocxUrl;
} else if (this.baseUrl) {
// 作为组件引入
this.finalBaseUrl = this.baseUrl;
} else {
// 给个默认值意思一下
this.finalBaseUrl = "/document/docx/hello.docx";
}
},
methods: {},
};
</script>
<style lang="less" scoped></style>- 测试是否可用
## 局部预览示例
在 md 文档中引用组件实现局部预览,可自定义组件宽高
<MyDocxTool
baseUrl='/document/docx/hello.docx'
width='500px'
height="600px"/>局部预览示例

