获取Word、PPT、Excel、PDF文件页数及加密校验

想要获取一个pdf文件的页数,有多种实现方式。可以利用pdfjs,也可以利用PDFDocument:

// 方法一:利用文件的arrayBuffer
let arrayBuffer = await file.arrayBuffer();
const pdfDoc = await PDFDocument.load(arrayBuffer, { ignoreEncryption: true });
const pageCount =  pdfDoc.getPageCount();// 方法二:利用文件生成blob对象
const pdfObj = await PDFDocument.load(blob, { ignoreEncryption: true });
const pageCount = pdfObj.getPageCount();// 方法三:利用文件的在线预览地址
const byteString = atob(file.base64.split(',')[1]);
const mimeString = file.base64.split(',')[0].split(':')[1].split(';')[0];
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {ia[i] = byteString.charCodeAt(i);
}const loadingTask = pdfjsLib.getDocument({data: ab,password: file.code || '',
});const pdfDocument = await loadingTask.promise;
const pageCount = pdfDocument.numPages;

如果是加密文件,想要使用pdfjs方式获取文件页数,需要提前给用户弹出密码框进行密码输入及验证,如何进行密码验证呢

(office文件暂时没有密码正确性验证的方式,因此只能校验是否是加密文件,而pdf文件可以校验出是否其他权限有无加密)

import { PDFDocument  } from 'pdf-lib';
import '@/assets/pdfjs/build/pdf.js'
import '@/assets/pdfjs/build/pdf.worker.js'
import * as XLSX from 'xlsx';
import JSZip from 'jszip';
import { gaEvent } from '@/utils/gtag'// 判断是否已加密
const checkIfFileEncrypted = async (file: any, isCloud: boolean) => {try {let arrayBuffer;if (isCloud) {const link = await getAccessLink(file.cloudId || file.file_id, file.name || file.file_name);const response = await fetch(link);if (!response.ok) throw new Error('Failed to fetch file');arrayBuffer = await response.arrayBuffer();} else {if(!file.base64) {arrayBuffer = await file.arrayBuffer();} else {const byteString = atob(file.base64.split(',')[1]);const mimeString = file.base64.split(',')[0].split(':')[1].split(';')[0];const ab = new ArrayBuffer(byteString.length);const ia = new Uint8Array(ab);for (let i = 0; i < byteString.length; i++) {ia[i] = byteString.charCodeAt(i);}// 创建 Blobconst blob = new Blob([ab], { type: mimeString });const fileObj = blobToFile(blob, file.name);arrayBuffer = await fileObj.arrayBuffer();}}if (file.type === 'application/pdf' || file.file_type === 'pdf' || file.name.endsWith('.pdf')) {// PDF 文件的加密检查const result = await checkPDFFileEncryption(arrayBuffer);return result.isEncrypted;} else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||file.type === 'application/msword' ||file.file_type === 'docx' ||file.file_type === 'doc') {// Word 文件的加密检查return checkWordFileEncryption(arrayBuffer);} else if (file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||file.type === 'application/vnd.ms-excel' ||file.file_type === 'xlsx' ||file.file_type === 'xls') {// Excel 文件的加密检查return checkExcelFileEncryption(arrayBuffer);} else if (file.type === 'application/vnd.openxmlformats-officedocument.presentationml.presentation' ||file.type === 'application/vnd.ms-powerpoint' ||file.file_type === 'pptx' ||file.file_type === 'ppt') {// PPT 文件的加密检查return checkPPTFileEncryption(arrayBuffer);} else {return false; // 默认不加密}} catch (error) {return false;}
};// PDF 文件加密检测
const checkPDFFileEncryption = async (arrayBuffer: any) => {try {const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer });const pdfDoc = await loadingTask.promise;const permissions = await pdfDoc.getPermissions();if (permissions) {return {isEncrypted: false,hasOwnerPassword: true};}return {isEncrypted: false,hasOwnerPassword: false};} catch (error: any) {if (error.name === 'PasswordException') {return {isEncrypted: true,hasOwnerPassword: false};}return {isEncrypted: false,hasOwnerPassword: false};}
};// 验证 PDF 密码的函数
const verifyPDFPassword = async (file: any, password: string, isCode: boolean) => {try {let arrayBuffer;if (isCode) { // 云盘文件const link = await getAccessLink(file.cloudId || file.file_id, file.name || file.file_name);const response = await fetch(link);if (!response.ok) throw new Error('Failed to fetch file');arrayBuffer = await response.arrayBuffer();} else {arrayBuffer = await file.arrayBuffer();}const loadingTask = pdfjsLib.getDocument({data: arrayBuffer,password: password,});await loadingTask.promise;return true; // 密码正确} catch (error: any) {if (error.name === 'PasswordException') {return false; // 密码错误}return false; // 其他错误}
};// 提示用户输入密码的函数
const promptUserForPassword = async (file: any) => {return new Promise((resolve) => {EventBus.$emit('show-password-prompt', file, (action: any, password: string) => {resolve({ action, password });});});
};// Word 文件加密检测
const checkWordFileEncryption = async (arrayBuffer: any) => {try {const zip = await JSZip.loadAsync(arrayBuffer);if (zip.files['word/document.xml']) {return false; // 文件解压成功,说明未加密}} catch (error: any) {if (error.message.includes('End of data reached') ||error.message.includes('Corrupted zip') ||error.message.includes('Can\'t find end of central directory')) {return true; // 文件加密或损坏}}return false;
};// Excel 文件加密检测
const checkExcelFileEncryption = async (arrayBuffer: any) => {try {const workbook = XLSX.read(arrayBuffer, { type: 'array' });if (workbook.SheetNames.length > 0) {return false; // 文件解压成功,说明未加密}} catch (error: any) {if (error.message.includes('Encrypted') ||error.message.includes('File is password-protected')) {return true; // 文件加密}}return false;
};// PPT 文件加密检测
const checkPPTFileEncryption = async (arrayBuffer: any) => {try {const zip = await JSZip.loadAsync(arrayBuffer);if (zip.files['ppt/presentation.xml']) {return false; // 文件解压成功,说明未加密}} catch (error: any) {if (error.message.includes('Encrypted') ||error.message.includes('Can\'t find end of central directory')) {return true; // 文件加密}}return false;
};

通过以上方式即可成功拿到进行加密校验,下面是word、PPT、Excel格式文件获取文件页数的方式:

// 获取PDF文件页数
const getPDFPageCount = async (arrayBuffer, password) => {const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer, password });const pdfDocument = await loadingTask.promise;return pdfDocument.numPages;
};// 获取Word文件页数
const getWordPageCount = async (arrayBuffer) => {try {const zip = await JSZip.loadAsync(arrayBuffer);if (zip.files['word/document.xml']) {// 解析 document.xml 获取页数(此处仅为示例,具体解析需要更复杂的处理)return 1; // Word文件页数暂时返回1}} catch (error) {console.error('Error processing Word file:', error);}return 1;
};// 获取Excel文件页数
const getExcelPageCount = async (arrayBuffer) => {try {const workbook = XLSX.read(arrayBuffer, { type: 'array' });// 以工作表的数量作为页数return workbook.SheetNames.length;} catch (error) {console.error('Error processing Excel file:', error);}return 1;
};// 获取PPT文件页数
const getPPTPageCount = async (arrayBuffer) => {try {const zip = await JSZip.loadAsync(arrayBuffer);if (zip.files['ppt/slides/']) {// 以幻灯片数量作为页数return Object.keys(zip.files['ppt/slides/']).length;}} catch (error) {console.error('Error processing PPT file:', error);}return 1;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/52779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于AI大模型开发上层应用常见的技术栈

基于AI大模型的上层应用开发&#xff0c;技术栈要求通常包括以下几个方面&#xff1a; 编程语言&#xff1a;Python是AI领域的主要编程语言&#xff0c;具有大量的库和框架支持&#xff0c;是大模型开发的首选语言 。TypeScript也是不错的选择&#xff0c;很多模型对外提供类似…

LuaJit分析(六)luajit -bl 命令分析

Luajit -bl命令用于将luajit字节码文件或者lua脚本文件反汇编&#xff0c;输出汇编指令&#xff0c;很好奇怎么将字节码文件和lua脚本文件放在一块处理的&#xff0c;下面一步步分析&#xff1a; luajit虚拟机由luajit.c文件生成&#xff0c;首先定位到main函数&#xff0c;代…

【ceph学习】ceph如何进行数据的读写(3)

本章摘要 上文说到&#xff0c;osdc中封装请求&#xff0c;使用message中的相关机制将请求发送出去。 本文详细介绍osd服务端如何进行请求的接收。 osd初始化 osd启动时&#xff0c;定义了message变量ms_public&#xff0c;该变量绑定public网络&#xff0c;负责接收客户端的…

Java使用POI创建带样式和公式的Excel文件

这篇文章将演示如何使用POI 创建带样式和公式的Excel文件。 代码 import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream; import java.io.IOException;public class ExcelDemo {public static void mai…

FPGA第 5 篇,FPGA技术优略势,FPGA学习方向,FPGA学习路线(FPGA专业知识的学习方向,FPGA现场可编程门阵列学习路线和方向)

前言 前几篇讲了一下FPGA的发展和应用&#xff0c;以及未来前景。具体详细&#xff0c;请看 FPGA发展和应用&#xff0c;以及未来前景https://blog.csdn.net/weixin_65793170/category_12665249.html 这里我们来&#xff0c;记录一下&#xff0c;FPGA专业知识的学习路线 一.…

Python(C++)自动微分导图

&#x1f3af;要点 反向传播矢量化计算方式前向传递和后向传递计算方式图节点拓扑排序一阶二阶前向和伴随模式计算二元分类中生成系数高斯噪声和特征二元二次方程有向无环计算图超平面搜索前向梯度下降算法快速傅里叶变换材料应力和切线算子GPU CUDA 神经网络算术微分 Pytho…

理解 decltype() 指定符(C++ 11 及以上版本)

目录 1. 功能 2. 语法格式 3. 理解 3.1 第一点 1.2 第二点 4. 例释 在 C 编程语言中&#xff0c;decltype 是一个用于检查实体的声明类型或表达式的类型和值类别的关键字。该关键字在 C11 中引入&#xff0c;主要用于泛型编程中&#xff0c;因为在泛型编程中&#x…

数据类型 NVARCHAR2 与 VARCHAR2 的对比

数据类型 NVARCHAR2 与 VARCHAR2 的对比 在数据库系统中&#xff0c;字符数据类型是用于存储文本数据的关键部分。在达梦数据库&#xff08;DM Database&#xff09;以及许多其他关系数据库管理系统&#xff08;例如 Oracle&#xff09;&#xff0c;常见的字符数据类型有 NVAR…

C语言阴阳迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <Windows.h> enum WASD {W…

CityHash、FarmHash

CityHash和FarmHash都是由Google开发的非加密哈希函数&#xff0c;专为快速处理大量数据而设计。它们在数据中心和大规模分布式系统中尤其有用&#xff0c;用于任务如数据分区、查找优化、数据校验等。这两种哈希函数都以其高效的性能和良好的分布特性而著称。 CityHash City…

设计模式 -- 外观模式(Facade Pattern)

1 问题引出 组建一个家庭影院 DVD 播放器、投影仪、自动屏幕、环绕立体声、爆米花机,要求完成使用家庭影院的功能&#xff0c;其过程为&#xff1a; 直接用遥控器&#xff1a;统筹各设备开关 开爆米花机&#xff0c;放下屏幕 &#xff0c;开投影仪 &#xff0c;开音响&#xf…

【人工智能】AI算法系统设计与算法建模的详细阐述

&#x1f3c6;&#x1f3c6;欢迎大家来到我们的天空&#x1f3c6;&#x1f3c6; &#x1f3c6;&#x1f3c6;如果文章内容对您有所触动&#xff0c;别忘了点赞、关注&#xff0c;收藏&#xff01; &#x1f3c6; 作者简介&#xff1a;我们的天空 &#x1f3c6;《头衔》&#x…

自定义全局变量在uniapp的Vuex应用

本文介绍了uniapp使用自定义全局变量的方法。当同一业务在连续页面操作时&#xff0c;存在部分筛选变量需要始终保持一致&#xff0c;比如时间筛选条件等&#xff0c;来回跳转页面时如果采用变量传递&#xff0c;常较为繁琐&#xff0c;存在遗漏传递或未清除上一次变量值&#…

图像金字塔的作用

1. 概述 图像金字塔是图像多尺度表达的一种&#xff0c;主要应用与图像分割&#xff0c;是一种以多分辨率来解释图像的有效但概念简单的结构。图像金字塔实际上是一张图片在不同尺度下的集合&#xff0c;即原图的上采样和下采样集合。金字塔的底部是高分辨率图像&#xff0c;而…

LuaJit分析(九)LuaJit中的JIT原理分析

Jit in luajit Luajit是一款高性能的lua解释器&#xff0c;与官方的lua解释器相比&#xff0c;luajit的高速除了将解释器直接以汇编代码实现外&#xff0c;还支持jit模式&#xff08;Just in time&#xff09;。Jit模式即将luajit的字节码编译成处理器能够直接执行的机器码&am…

vue3如何监听reactive对象是哪个属性发生的变化

在 Vue 3 中&#xff0c;如果你想监听 reactive 对象中的某个属性发生的变化&#xff0c;你可以使用 watch 函数进行监听。watch 函数允许你观察 reactive 对象的某个属性或者整个对象&#xff0c;并在变化时执行相应的操作。 1. 监听 reactive 对象的某个属性 如果你只想监听…

C++学习/复习补充记录 --- 图论(深搜,广搜)

数据结构与算法 | 深搜&#xff08;DFS&#xff09;与广搜&#xff08;BFS&#xff09;_深搜广搜算法-CSDN博客 深度优先搜索理论基础 深搜和广搜的区别&#xff1a; &#xff08;通俗版&#xff09; dfs是可一个方向去搜&#xff0c;不到黄河不回头&#xff0c;直到遇到绝境了…

在Unity中使用C#进行Xml序列化时保留特定小数位的方法参考

序列化方法代码参考&#xff1a; using System.IO; using System.Xml.Serialization;public class XmlTool {public static string ToXml<T>(T obj){XmlSerializer xmlSerializer new XmlSerializer(typeof(T));using var stringWriter new StringWriter();//让xml文档…

linux驱动 -- 输入子系统

1:输入子系统介绍 一个统一的输入设备的开发框架&#xff0c; 统一生成设备文件&#xff0c; 统一返回固定格式值。 2:输入子系统开发设备 键盘、鼠标、触摸屏等等。 3&#xff1a;输入子系统运行框架 应用层&#xff1a;操作设备文件openclosereadwrite 输入子系统&#xff…

Netty 学习笔记

Java 网络编程 早期的 Java API 只支持由本地系统套接字库提供的所谓的阻塞函数&#xff0c;下面的代码展示了一个使用传统 Java API 的服务器代码的普通示例 // 创建一个 ServerSocket 用以监听指定端口上的连接请求 ServerSocket serverSocket new ServerSocket(5000); //…