Java利用poi实现word,excel,ppt,pdf等各类型文档密码检测

介绍

最近工作上需要对word,excel,ppt,pdf等各类型文档密码检测,对文件进行分类,有密码的和没密码的做区分。查了一堆资料和GPT都不是很满意,最后东拼西凑搞了个相对全面的检测工具代码类,希望能给需要的人带来帮助。

说明

这段代码提供了一个全面的工具类,用于检测多种办公文档(.xls, .xlsx, .doc, .docx, .pdf, .ppt, .pptx)是否设置了密码保护。以下是该实现的核心逻辑和要点:

1、通用检测入口 :通过isFileProtected(File file, String fileExtension)方法,根据文件扩展名调用特定的检测方法。

2、Excel文件检测 (isExcelProtected(File file)): 使用WorkbookFactory.create()尝试打开文件,如果文件加密,会抛出EncryptedDocumentException异常。

3、Word文件检测 (isWordProtected(File file)): 利用WordExtractor尝试读取文件内容,当文件加密时,会抛出EncryptedDocumentException异常,或者从异常信息中判断文件是否加密。

4、PDF文件检测 (isPdfProtected(File file)): 使用PDFBox库的Loader.loadPDF()加载文件,然后检查PDDocument实例的isEncrypted()状态,或捕获InvalidPasswordException来判断是否加密。

5、PPT文件检测 (isPptProtected(File file)): 对于.ppt文件使用HSLFSlideShow尝试读取,通过捕获异常并检查消息中是否包含"encrypted"关键字来判断文件是否加密。注意,对于.pptx文件,理论上应该使用与.xlsx类似的处理方式,但示例中未单独区分。

6、资源管理 :使用try-with-resources语句确保文件输入流和各种文档对象在操作完成后能被正确关闭,同时利用自定义的IoUtil.close()方法进一步确保资源的释放(假设这是您项目中的一个辅助方法)。

7、日志记录:在捕获异常时记录错误日志,有助于追踪问题。

实现步骤

添加依赖

  • poi-4.1.2
  • hu-tool
  • pdfbox
xml 复制代码
<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.21</version>
        </dependency>
 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <dependency>
            <!-- jsoup HTML parser library @ https://jsoup.org/ -->
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.17.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>3.0.2</version>
        </dependency>

工具类

java 复制代码
public class TestFileEncrypt {
    private static final Logger log = LoggerFactory.getLogger(TestFileEncrypt.class);

    public static void main(String[] args) {
        String filePath = "d:/tmp/enc/data0.xls"; // 替换为你要检查的文件路径
        boolean isLikelyEncrypted = isExcelProtected(FileUtil.newFile(filePath));
        System.out.println("文件是否加密的: " + isLikelyEncrypted);
    }

    // 创建通用方法,根据文件后缀名识别文件类型,调用不同的方法进行检测
    public static boolean isFileProtected(File file, String fileExtension) {
        switch (fileExtension.toLowerCase()) {
            case "xls":
            case "xlsx":
                return isExcelProtected(file);
            case "doc":
            case "docx":
                return isWordProtected(file);
            case "pdf":
                return isPdfProtected(file);
            case "ppt":
            case "pptx":
                return isPptProtected(file);
            default:
                return false;
        }
    }

    // 检查XLSX文件是否受密码保护
    public static boolean isExcelProtected(File file) {
        boolean isProtected = false;
        Workbook sheets = null;
        try (FileInputStream fis = new FileInputStream(file)) {
            sheets = WorkbookFactory.create(fis);// 尝试打开XLSX文件
            sheets.close();
        } catch (EncryptedDocumentException e) {
            isProtected = true;  // 抛出异常表示文件受密码保护
        } catch (IOException e) {
            log.error("读取Excel文件失败:{},{}",file.getName(),e.getMessage());
        } finally {
            if (sheets != null) {
                IoUtil.close(sheets);
            }
            return isProtected;
        }
    }

    public static boolean isWordProtected(File file) {
        boolean isProtected = false;
        WordExtractor extractor = null;
        try (FileInputStream fis = new FileInputStream(file)) {
            // 创建WordExtractor以读取内容,这一步可能会在文件受保护时失败
            extractor = new WordExtractor(fis);
            extractor.close(); // 关闭提取器
        } catch (EncryptedDocumentException e){
            isProtected = true;
        } catch (IOException e) {
            if(e.getMessage().indexOf("EncryptedPackage") != -1){
                isProtected = true;
            }else{
                log.error("读取Word文件失败:{},{}",file.getName(),e.getMessage());
            }
        } finally {
            if(extractor!=null){
                IoUtil.close(extractor);
            }
            return isProtected;
        }
    }

    // 检查PDF文件是否受密码保护
    public static boolean isPdfProtected(File file) {
        boolean isEncrypted = false;
        try (PDDocument document = Loader.loadPDF(file)) {
            if (document.isEncrypted()) {
                isEncrypted =  true;
            }
        } catch (InvalidPasswordException e) {
            isEncrypted = true;
        } catch (IOException e) {
            log.error("读取pdf文件失败:{},{}",file.getName(),e.getMessage());
        }finally {
            return isEncrypted;
        }
    }

    public static boolean isPptProtected(File file) {
        boolean isProtected = false;
        HSLFSlideShow ppt=null;
        try (FileInputStream fis = new FileInputStream(file)) {
            ppt = new HSLFSlideShow(fis);
            ppt.getPageSize();
            ppt.close();
        } catch (Exception e){
            if(e.getMessage().toLowerCase().indexOf("encrypted")!=-1){
                isProtected = true;
            }
        } finally {
            if(ppt!=null){
                IoUtil.close(ppt);
            }
            return isProtected;
        }
    }

}
相关推荐
Freak嵌入式3 分钟前
MicroPython+Pico 接收空闲中断和发送空闲中断全实战
java·开发语言·stm32·单片机·嵌入式硬件
计算机毕设定制辅导-无忧学长17 分钟前
《基于SpringBoot的图书管理系统设计与实现》
java·spring boot·后端
小蒜学长17 分钟前
借助于大模型工具Cursor的中药材交易系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
Arvin62718 分钟前
SonarQube 扫描 Maven 项目编译错误
java·maven·sonar
lhldsg25 分钟前
宠物同城领养平台开发实战:从需求分析到上线部署指南
java·前端·小程序·需求分析·宠物
风萧萧199929 分钟前
JAVA :JSONObject转换为XML
xml·java·python
阿图灵29 分钟前
LangGraph 实战 03:Workflows 与 Agents——六种工作流模式与智能体实战(附 6 个可运行示例)
java·前端·javascript·工作流·ai agent·智能体·langgraph
程序员三明治35 分钟前
【体验毛坯房】Deep Harness 入门教程
java·人工智能·后端·大模型·llm·deepseek·dsh
zzzll111135 分钟前
深入理解 Java HashMap:从原理到实战
java·开发语言·哈希算法
猫猫不是喵喵.43 分钟前
Java开发高频面试题汇总(通俗易懂版)
java·开发语言·java高频面试