别再手动数了!用Apache POI和iText,5行代码搞定Java批量统计文档页数
5行代码实现Java批量文档页数统计Apache POI与iText的高效实践当你在整理年度报告、审计文档或准备印刷材料时是否曾被成百上千份文档的页数统计折磨得焦头烂额手动打开每个文件查看页数不仅效率低下还容易出错。今天我将分享一个基于Java的轻量级解决方案只需5行核心代码就能自动扫描整个文件夹统计所有Word、PPT和PDF文档的页数。1. 环境准备与依赖配置在开始之前我们需要确保开发环境已经配置好必要的依赖库。Apache POI和iText是处理Office文档和PDF的两大Java利器它们能够帮助我们轻松获取各种文档的页数信息。创建一个新的Maven项目在pom.xml中添加以下依赖dependencies !-- 处理PDF文档 -- dependency groupIdcom.itextpdf/groupId artifactIditextpdf/artifactId version5.5.13.3/version /dependency !-- 处理Office文档 -- dependency groupIdorg.apache.poi/groupId artifactIdpoi/artifactId version5.2.3/version /dependency dependency groupIdorg.apache.poi/groupId artifactIdpoi-ooxml/artifactId version5.2.3/version /dependency dependency groupIdorg.apache.poi/groupId artifactIdpoi-scratchpad/artifactId version5.2.3/version /dependency /dependencies提示选择较新的稳定版本可以避免一些已知的兼容性问题同时获得更好的性能表现。2. 核心工具类设计我们将创建一个高度封装的工具类DocumentPageCounter它能够处理各种格式的文档页数统计。这个类的设计目标是简洁易用同时具备良好的扩展性。import org.apache.poi.hslf.usermodel.*; import org.apache.poi.xslf.usermodel.*; import org.apache.poi.xwpf.usermodel.*; import org.apache.poi.hwpf.extractor.*; import com.itextpdf.text.pdf.*; import java.io.*; import java.nio.file.*; import java.util.*; import java.util.zip.ZipFile; public class DocumentPageCounter { public static int getPageCount(File file) throws Exception { String name file.getName().toLowerCase(); if (name.endsWith(.pdf)) return new PdfReader(file.getPath()).getNumberOfPages(); if (name.endsWith(.docx)) return new XWPFDocument(new FileInputStream(file)).getProperties().getExtendedProperties().getUnderlyingProperties().getPages(); if (name.endsWith(.doc)) return new WordExtractor(new FileInputStream(file)).getSummaryInformation().getPageCount(); if (name.endsWith(.pptx)) return new XMLSlideShow(new FileInputStream(file)).getSlides().size(); if (name.endsWith(.ppt)) return new HSLFSlideShow(new FileInputStream(file)).getSlides().size(); throw new UnsupportedOperationException(Unsupported file type: name); } }这个工具类的核心优势在于简洁性每个文件类型的处理仅需一行代码扩展性可以轻松添加对其他文件格式的支持易用性通过统一的接口getPageCount处理所有文档类型3. 批量处理文件夹的实现有了核心工具类我们现在可以实现批量处理整个文件夹的功能。以下是一个完整的命令行工具实现import java.io.File; import java.util.Arrays; import java.util.Comparator; import java.util.stream.Collectors; public class BatchPageCounter { public static void main(String[] args) throws Exception { if (args.length 0) { System.out.println(Usage: java BatchPageCounter directory); return; } File dir new File(args[0]); if (!dir.isDirectory()) { System.out.println(Error: args[0] is not a directory); return; } Arrays.stream(dir.listFiles()) .filter(f - f.getName().matches(.*\\.(pdf|docx?|pptx?)$)) .sorted(Comparator.comparing(File::getName)) .forEach(f - { try { System.out.printf(%-40s %4d页%n, f.getName(), DocumentPageCounter.getPageCount(f)); } catch (Exception e) { System.out.printf(%-40s 解析失败: %s%n, f.getName(), e.getMessage()); } }); } }这个批量处理程序的特点包括支持命令行参数可以直接指定要扫描的文件夹路径智能过滤只处理PDF、Word和PPT文件排序输出按文件名排序便于查看错误处理对无法解析的文件会给出友好提示4. 性能优化与异常处理在实际应用中我们还需要考虑性能和稳定性问题。以下是几个关键的优化点4.1 内存管理优化处理大型文档时内存消耗可能成为问题。我们可以通过以下方式优化// PDF内存优化示例 PdfReader reader new PdfReader(new RandomAccessFile(file, r).getChannel()); int pages reader.getNumberOfPages(); reader.close(); // PPTX内存优化示例 ZipSecureFile.setMinInflateRatio(0.001); // 降低解压内存需求 XMLSlideShow ppt new XMLSlideShow(new FileInputStream(file)); int slides ppt.getSlides().size(); ppt.close();4.2 并发处理加速对于包含大量文件的文件夹可以使用并行流加速处理Arrays.stream(dir.listFiles()) .parallel() // 启用并行处理 .filter(f - f.getName().matches(.*\\.(pdf|docx?|pptx?)$)) .sorted(Comparator.comparing(File::getName)) .forEach(f - { /* 处理逻辑 */ });4.3 常见异常处理在实际应用中我们可能会遇到各种异常情况需要妥善处理异常类型可能原因解决方案IOException文件损坏或权限问题跳过该文件并记录错误OutOfMemoryError文档过大增加JVM内存或使用流式处理UnsupportedOperationException不支持的格式提前过滤文件类型NullPointerException文档元数据缺失使用备选方法获取页数5. 扩展应用场景这个工具不仅限于简单的页数统计还可以扩展应用到更多实际场景中5.1 文档管理系统集成将页数统计功能集成到文档管理系统中可以自动记录每个文档的页数信息public class DocumentInfo { private String name; private int pages; private long size; private Date lastModified; // 构造函数、getter和setter省略 public static DocumentInfo fromFile(File file) throws Exception { DocumentInfo info new DocumentInfo(); info.setName(file.getName()); info.setPages(DocumentPageCounter.getPageCount(file)); info.setSize(file.length()); info.setLastModified(new Date(file.lastModified())); return info; } }5.2 批量打印成本计算结合页数统计可以自动计算批量打印的成本public class PrintingCostCalculator { private static final double COST_PER_PAGE 0.5; // 每页打印成本 public static double calculate(File dir) throws Exception { return Arrays.stream(dir.listFiles()) .filter(f - f.getName().matches(.*\\.(pdf|docx?|pptx?)$)) .mapToDouble(f - { try { return DocumentPageCounter.getPageCount(f) * COST_PER_PAGE; } catch (Exception e) { return 0; } }) .sum(); } }5.3 文档质量分析通过分析文档页数分布可以发现潜在的问题public class DocumentAnalyzer { public static void analyze(File dir) throws Exception { IntSummaryStatistics stats Arrays.stream(dir.listFiles()) .filter(f - f.getName().matches(.*\\.(pdf|docx?|pptx?)$)) .mapToInt(f - { try { return DocumentPageCounter.getPageCount(f); } catch (Exception e) { return 0; } }) .summaryStatistics(); System.out.println(文档页数分析:); System.out.println(总文档数: stats.getCount()); System.out.println(总页数: stats.getSum()); System.out.println(平均页数: stats.getAverage()); System.out.println(最多页数: stats.getMax()); System.out.println(最少页数: stats.getMin()); } }在实际项目中我发现对于特别大的文件夹包含数千个文档将结果输出到CSV文件比直接打印到控制台更实用。可以使用OpenCSV等库轻松实现import com.opencsv.CSVWriter; // ... try (CSVWriter writer new CSVWriter(new FileWriter(result.csv))) { writer.writeNext(new String[]{文件名, 页数, 大小(KB), 修改日期}); Arrays.stream(dir.listFiles()) .filter(f - f.getName().matches(.*\\.(pdf|docx?|pptx?)$)) .forEach(f - { try { writer.writeNext(new String[]{ f.getName(), String.valueOf(DocumentPageCounter.getPageCount(f)), String.valueOf(f.length() / 1024), new Date(f.lastModified()).toString() }); } catch (Exception e) { writer.writeNext(new String[]{f.getName(), ERROR, , }); } }); }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2469842.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!