当前位置: 首页 > news >正文

预览 PDF 文档

引言

在现代Web应用中,文件预览功能是非常常见的需求之一。特别是在企业级应用中,用户经常需要查看各种类型的文件,如 PDF、Word、Excel 等。本文将详细介绍如何在Vue项目中实现 PDF 文档的预览功能。

实现原理

后端API

后端需要提供一个API接口,用于获取文件的二进制数据。这个接口通常会根据文件名或文件ID来返回文件内容。

前端处理

前端通过调用后端 API 获取文件的二进制数据,并将其转换为 Blob 对象。然后使用window.URL.createObjectURL 方法生成一个临时的 URL,最后通过 window.open 方法在新窗口中打开这个 URL,从而实现文件预览。

代码示例

node 服务端代码

const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');const app = express();
// 定义文件夹路径
const mergedDir = path.join(__dirname, 'merged');// 文件下载接口
app.get('/download', (req, res) => {const { fileName } = req.query;const filePath = path.join(mergedDir, fileName);fs.access(filePath, fs.constants.F_OK, (err) => {if (err) {return res.status(404).json({ error: '文件不存在' });}const stats = fs.statSync(filePath);if (stats.isFile()) {const contentType = getContentType(fileName);res.setHeader('Content-Type', contentType);// 对 fileName 进行编码const encodedFileName = encodeURIComponent(fileName);res.setHeader('Content-Disposition', `attachment; filename=${encodedFileName}`);fs.createReadStream(filePath).pipe(res);} else {res.status(400).json({ error: '不是一个文件' });}});
});// 获取文件的 MIME 类型
function getContentType(fileName) {const ext = path.extname(fileName).toLowerCase();switch (ext) {case '.js':return 'application/javascript';case '.json':return 'application/json';case '.html':return 'text/html';case '.css':return 'text/css';case '.txt':return 'text/plain';case '.png':return 'image/png';case '.jpg':case '.jpeg':return 'image/jpeg';case '.gif':return 'image/gif';case '.pdf':return 'application/pdf';case '.doc':return 'application/msword';case '.docx':return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';case '.ppt':return 'application/vnd.ms-powerpoint';case '.pptx':return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';case '.xlsx':return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';default:return 'application/octet-stream';}
}
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {console.log(`Server is running on port ${PORT}`);
});

前端代码实现

接口 API

import request from "@/utils/request";// 获取文件列表
export function getFilesList() {return request({url: "/getFilesList",method: "get",});
}// 文件预览
export function previewFile(fileName) {return request({url: `/download?fileName=${fileName}`,method: "get",responseType: "blob",});
}

页面代码

<template><div class="table"><el-table :data="tableData" header-align="center" border style="width: 100%"><el-table-column align="center" type="index" width="60" label="序号"></el-table-column><el-table-column align="center" prop="fileName" label="文件名" /><el-table-column align="center" prop="upTime" label="上传日期" width="200" /><el-table-column align="center" fixed="right" label="操作" width="120"><template slot-scope="scope"><el-button @click="handleClick(scope.row)" type="text">预览</el-button></template></el-table-column></el-table></div>
</template><script>
import { previewFile } from "@/api/file";
import { timeStampToString } from "@/utils/utils";
import { getFilesList } from "@/api/file";export default {name: "fileTable",data() {return {tableData: [],}},created() {this.getFileName();},methods: {// 获取文件列表async getFileName() {const { code, data: resData } = await getFilesList();console.log('code, data::: ', code, resData);if (code === 200) {resData.forEach(item => {item.upTime = timeStampToString(item.upTime);});this.tableData = resData;}},handleBlob(blob, filename) {console.log('blob::: ', blob,filename);let url = window.URL.createObjectURL(blob);var tempwindow = window.open("_blank");if (tempwindow) {tempwindow.location = url;}},// 文件预览async handleClick(row) {try {const response = await previewFile(row.fileName)console.log('response::: ', response);this.handleBlob(response, row.fileName)} catch (err) {console.error('Failed to preview file', err);}},}
}
</script>

实现效果
在这里插入图片描述

设置网页标题为文件名

 handleBlob(blob, filename) {console.log('blob::: ', blob, filename);let url = window.URL.createObjectURL(blob);// 创建一个新窗口let tempWindow = window.open("", "_blank");// 设置新窗口的标题为文件名tempWindow.document.title = filename;// 在新窗口中嵌入一个 <iframe> 来预览 PDF 文件tempWindow.document.write('<html><head><title>' + filename + '</title></head><body>');tempWindow.document.write('<iframe src="' + url + '" style="width:100%;height:100%;border:none;"></iframe>');tempWindow.document.write('</body></html>');// 确保新窗口的内容加载完成后再释放 URLtempWindow.onload = function () {window.URL.revokeObjectURL(url);};},

修改后的效果
在这里插入图片描述

总结

本文详细介绍了如何在Vue项目中实现PDF文档的预览功能。通过前后端的协同工作,我们实现了从文件的存储、获取到预览的完整流程。具体来说:

  • 后端API:提供了文件下载接口,根据文件名或文件ID返回文件的二进制数据,并设置了正确的MIME类型。

  • 前端处理:通过调用后端API获取文件的二进制数据,将其转换为 Blob 对象,并生成一个临时的 URL。然后在新窗口中打开这个 URL,实现文件预览。

  • 优化体验:为了提升用户体验,我们进一步优化了预览功能,通过在新窗口中嵌入 <iframe> 并设置网页标题为文件名,使得预览界面更加友好和直观。

通过本文的介绍,读者可以轻松地在自己的Vue项目中实现类似的功能,提升应用的用户体验。希望本文对大家有所帮助。

相关文章:

预览 PDF 文档

引言 在现代Web应用中&#xff0c;文件预览功能是非常常见的需求之一。特别是在企业级应用中&#xff0c;用户经常需要查看各种类型的文件&#xff0c;如 PDF、Word、Excel 等。本文将详细介绍如何在Vue项目中实现 PDF 文档的预览功能。 实现原理 后端API 后端需要提供一个…...

Chromium 在WebContents中添加自定义数据c++

为了能在WebContents中添加自定义数据先看下几个关键类的介绍。 一、WebContents 介绍&#xff1a; WebContents是content模块核心&#xff0c;是呈现 Web 内容&#xff08;通常为 HTML&#xff09;位于矩形区域中。 最直观的是一个浏览器标签对应一个WebContents&#xff0c…...

【Apache Zookeeper】

一、简介 1、场景 如何让⼀个应⽤中多个独⽴的程序协同⼯作是⼀件⾮常困难的事情。开发这样的应⽤&#xff0c;很容易让很多开发⼈员陷⼊如何使多个程序协同⼯作的逻辑中&#xff0c;最后导致没有时间更好地思考和实现他们⾃⼰的应⽤程序逻辑&#xff1b;又或者开发⼈员对协同…...

13.音乐管理系统(基于SpringBoot + Vue)

目录 1.系统的受众说明 ​​​​​​​ 2 需求分析 2.1用例图及用例分析 2.1.1 用户用例图及用例分析 2.1.2 管理员用例图及用例分析 2.2 系统结构图和流程图 2.2.1 音乐播放器的系统流程图&#xff08;图2.2.1-1&#xff09; 2.2.2 系统功能表&#xff08;表2.2.2…...

如何从iconfont中获取字体图标并应用到微信小程序中去?

下面我们一一个微信小程序的登录界面的制作为例来说明&#xff0c;如何从iconfont中获取字体图标是如何应用到微信小程序中去的。首先我们看效果。 这里所有的图标&#xff0c;都是从iconfont中以字体的形式来加载的&#xff0c;也就是说&#xff0c;我们自始至终没有使用一张…...

C语言中的位操作

第一章 变量某位赋值与连续赋值 寄存器 | 值 //例如&#xff1a;a 1000 0011b a | (1<<2) //a 1000 0111 b 单独赋值 a | (3<<2*2) // 1011 0011b 连续赋值 第二章 变量某位清零与连续清零 寄存器 & ~&#xff08;&#xff09; 值 //例子&#xff1a;a …...

Spring之HTTP客户端--RestTemplate的使用

原文网址&#xff1a;Spring之HTTP客户端--RestTemplate的使用_IT利刃出鞘的博客-CSDN博客 简介 本文介绍RestTemplate的用法。RestTemplate是Spring自带的HTTP客户端&#xff0c;推荐使用。 项目中经常需要使用http调用第三方的服务&#xff0c;常用的客户端如下&#xff1…...

vscode和pycharm在当前工作目录的不同|python获取当前文件目录和当前工作目录

问题背景 相信大家都遇到过一个问题&#xff1a;一个项目在vscode&#xff08;或pycharm&#xff09;明明可以正常运行&#xff0c;但当在pycharm&#xff08;或vscode&#xff09;中时&#xff0c;却经常会出现路径错误。起初&#xff0c;对于这个问题&#xff0c;我也是一知…...

速盾:海外高防CDN有哪些优势?

海外高防CDN&#xff08;Content Delivery Network&#xff09;是一种通过部署分布式节点服务器来加速网站内容分发的技术&#xff0c;它能够提供更快速、稳定、安全的网站访问体验。相比于传统的CDN服务&#xff0c;海外高防CDN具有以下几个优势&#xff1a; 全球分布&#xf…...

OpenCV视觉分析之目标跟踪(4)目标跟踪类TrackerDaSiamRPN的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::TrackerDaSiamRPN 是 OpenCV 中用于目标跟踪的一个类&#xff0c;它实现了 DaSiam RPN&#xff08;Deformable Siamese Region Proposal Net…...

自动对焦爬山算法原理

自动对焦爬山算法原理可以归纳为以下几个关键步骤&#xff1a; &#xff08;1&#xff09;初始化&#xff1a; 爬山算法从一个随机或预设的初始位置开始&#xff0c;这个位置代表了镜头的初始焦距。 &#xff08;2&#xff09;清晰度评价&#xff1a; 算法首先在当前焦距下捕…...

Hyperledger Fabric有那些核心技术,和其他区块链对比Hyperledger Fabric有那些优势

Hyperledger Fabric是一个模块化、权限化的企业级区块链平台&#xff0c;与比特币、以太坊等公有链相比&#xff0c;Fabric主要为私有链或联盟链设计&#xff0c;适用于企业应用。它包含多项核心技术&#xff0c;使其在企业级区块链应用中具有独特优势。以下是Fabric的核心技术…...

「Mac畅玩鸿蒙与硬件8」鸿蒙开发环境配置篇8 - 应用依赖与资源管理

本篇将介绍如何在 HarmonyOS 项目中高效管理资源文件和依赖&#xff0c;以确保代码结构清晰并提升应用性能。资源管理涉及图片、字符串、多语言文件等&#xff0c;通过优化文件加载和依赖管理&#xff0c;可以显著提升项目的加载速度和运行效率。 关键词 资源管理应用依赖优化…...

【Gorm】传统sql的增删查改,通过go去操作sql

MySQL中的建库&#xff0c;建表&#xff0c;删库&#xff0c;删表&#xff0c;添加记录&#xff0c;查询&#xff0c;删除记录&#xff0c;更新记录这些命令是一定要回的&#xff0c;就算我们脱离 orm 这些&#xff0c;也能直接连接上数据库进行操作。 一、数据库的操作 # 查…...

HTML小阶段二维表和思维导图

下面是对标签、元素、属性的对比二维表&#xff0c;通过对比3w1h&#xff08;what是什么、where用在哪、why为什么要用、how如何用&#xff09;来学习区分学习标签、元素、属性 标签 元素 属性 what &#xff08;Tags&#xff09;标签是用来标记内容块或标明元素内容意义 …...

AI与低代码的碰撞:企业数字化转型的新引擎

引言 在当今的商业环境中&#xff0c;企业数字化转型已从选择题变成了必答题。面对日益复杂的市场竞争和不断变化的客户需求&#xff0c;传统的开发模式常常显得力不从心——开发周期冗长、技术门槛高、成本居高不下&#xff0c;企业很难快速响应市场变化。而在这种背景下&…...

HarmonyOS应用开发者基础认证——初级闯关习题参考答案大全

相关文章 HarmonyOS应用开发者中级认证——中级闯关习题参考答案大全 HarmonyOS应用开发者高级认证——高级闯关习题参考答案大全 文章目录 HarmonyOS第一课 HarmonyOS介绍判断题单选题多选题 HarmonyOS第一课 DevEco Studio的使用判断题单选题多选题 HarmonyOS第一课 ArkTS语法…...

Vue背景图片自适应大屏与小屏

1&#xff0c;父绝子相 效果是台式看的更多&#xff0c;笔记本看部分。但是图片不会变形 <div class"father" style"width:100%; position:relative"> <img src"test.png" class"son" style"width:1920px; position:a…...

MongoDB 8.0.3版本安装教程

MongoDB 8.0.3版本安装教程 一、下载安装 1.进入官网 2.选择社区版 3.点击下载 4.下载完成后点击安装 5.同意协议&#xff0c;下一步 6.选择第二个Custon&#xff0c;自定义安装 7.选择安装路径 &#xff01;记住安装路径 8.默认&#xff0c;下一步 9.取…...

【C语言】预处理(预编译)详解(下)(C语言最终篇)

文章目录 一、#和##1.#运算符2.##运算符 二、预处理指令#undef三、条件编译1.单分支条件编译2.多分支条件编译3.判断符号是否被定义4.判断符号是否没有被定义 四、头文件的包含1.库头文件的包含2.本地头文件的包含3.嵌套包含头文件的解决方法使用条件编译指令使用预处理指令#pr…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...