系统访问ppt 转换成pdf,
pdf得放在public目录下才能生效
this.$router.push({ path: "/PDFViewer", query: { pptUrl: '/pdf/znt/sjzlgxn.pdf' } })
。vue页面
<template>
<div class="pdf-viewer-container">
<div class="home-btn" @click="goHome">
<span>返回首页</span>
</div>
<img
ref="pdfImage"
class="pdf-image"
:src="pdfImageData"
alt="PDF内容"
style="display: none"
/>
<!-- 隐藏的canvas用于PDF渲染 -->
<canvas
ref="renderCanvas"
class="render-canvas"
style="position: absolute; left: -9999px; top: -9999px; display: none"
></canvas>
<!-- Loading 显示 -->
<div v-if="loading" class="loading-container">
<div class="loading-spinner"></div>
<div class="loading-text">加载中...</div>
</div>
</div>
</template>
<script>
export default {
name: "PDFViewer",
data() {
return {
pdfImageData: "",
pdfjsLib: null,
loading: false,
devicePixelRatio: window.devicePixelRatio || 1,
}
},
mounted() {
this.loadPDFJS()
// 监听窗口大小变化,重新渲染PDF
// window.addEventListener("resize", this.handleResize)
},
beforeUnmount() {
// 清理资源
if (this.pdfjsLib) {
this.pdfjsLib = null
}
this.pdfImageData = ""
// 移除事件监听
window.removeEventListener("resize", this.handleResize)
},
methods: {
goHome() {
this.$router.push({ path: "dashboard" })
},
loadPDFJS() {
// 使用CDN加载PDF.js
const script = document.createElement("script")
script.src =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"
script.onload = () => {
this.pdfjsLib = window["pdfjs-dist/build/pdf"]
this.pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js"
this.loadPDF()
}
script.onerror = () => {
console.error("PDF.js 加载失败,将尝试使用图片模式")
this.loading = false // 加载失败时关闭loading
this.fallbackToImageMode()
}
document.head.appendChild(script)
},
async loadPDF() {
this.loading = true;
try {
const loadingTask = this.pdfjsLib.getDocument({
url: this.$route.query.pptUrl,
cMapUrl: "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/cmaps/",
cMapPacked: true,
});
const pdf = await loadingTask.promise;
const page = await pdf.getPage(1);
const viewport = page.getViewport({ scale: 1 });
// 计算显示比例
const containerWidth = window.innerWidth;
const containerHeight = window.innerHeight;
const displayScale = Math.min(
containerWidth / viewport.width,
containerHeight / viewport.height
);
// **使用2倍或3倍分辨率渲染**
const renderScale = displayScale * 2; // 或 3,根据性能调整
const canvas = this.$refs.renderCanvas;
// 设置canvas物理像素
canvas.width = viewport.width * renderScale;
canvas.height = viewport.height * renderScale;
const context = canvas.getContext("2d");
// 高质量渲染设置
context.imageSmoothingEnabled = true;
context.imageSmoothingQuality = "high";
context.mozImageSmoothingEnabled = true;
context.webkitImageSmoothingEnabled = true;
context.msImageSmoothingEnabled = true;
const renderContext = {
canvasContext: context,
viewport: page.getViewport({ scale: renderScale }),
};
await page.render(renderContext).promise;
// 转换为图片
this.pdfImageData = canvas.toDataURL("image/png", 1.0);
if (this.$refs.pdfImage) {
this.$refs.pdfImage.style.display = "block";
// 设置图片显示尺寸为原始比例
this.$refs.pdfImage.style.width = `${viewport.width * displayScale}px`;
this.$refs.pdfImage.style.height = `${viewport.height * displayScale}px`;
}
this.loading = false;
} catch (error) {
console.error(error);
this.loading = false;
this.fallbackToImageMode();
}
},
fallbackToImageMode() {
// 降级方案:直接将PDF作为图片显示
this.pdfImageData = this.$route.query.pptUrl
// 添加null检查,防止TypeError
if (this.$refs && this.$refs.pdfImage) {
const imgElement = this.$refs.pdfImage
imgElement.style.display = "block"
}
this.loading = false // 降级模式下也关闭loading
},
// 处理窗口大小变化
handleResize() {
// 添加null检查,确保组件已正确挂载
if (this.pdfjsLib) {
this.loadPDF()
}
},
},
}
</script>
<style scoped>
.home-btn {
position: absolute;
display: inline-block;
width: 4.583vw;
height: 7.778vh;
background: url("@/assets/img/home-btn.png") no-repeat;
background-size: 100% 100%;
right: 0.78125vw;
top: 4.926vh;
color: #ffffff;
font-family: YouSheBiaoTiHei;
font-weight: 400;
font-size: 1.512vh;
z-index: 1000; /* 增加z-index确保按钮显示在最上层 */
span {
display: inline-block;
width: 1.7vw;
line-height: 1;
margin-top: 2.454vh;
cursor: pointer;
}
}
.pdf-viewer-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
margin: 0 !important;
padding: 0 !important;
border: none !important;
background-color: black; /* 改为黑色背景 */
overflow: hidden !important;
}
.pdf-image {
position: absolute;
top: 0;
left: 0;
width: 100% !important;
height: 100% !important;
object-fit: fill !important;
margin: 0 !important;
padding: 0 !important;
border: none !important;
background-color: black;
/* position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 100%;
max-height: 100%;
/* 保持图片质量 */
/* image-rendering: -moz-crisp-edges; Firefox */
/* image-rendering: -webkit-optimize-contrast; Webkit (Safari) */
/* image-rendering: crisp-edges; */
/* image-rendering: pixelated; */
/* -ms-interpolation-mode: nearest-neighbor; IE (non-standard property) */
/* 现代浏览器 */
/* image-rendering: optimizeQuality;
object-fit: contain !important;
background-color: black; */
}
.render-canvas {
position: absolute;
left: -9999px;
top: -9999px;
display: none;
margin: 0;
padding: 0;
border: none;
}
/* Loading 样式 */
.loading-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
z-index: 2000;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: #ffffff;
animation: spin 1s ease-in-out infinite;
margin-bottom: 10px;
}
.loading-text {
color: #ffffff;
font-size: 16px;
font-weight: 500;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
html,
body,
#app {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
height: 100% !important;
overflow: hidden !important;
background-color: black !important; /* 改为黑色背景 */
}
</style>
浙公网安备 33010602011771号