Java 解析 PDF:抽取文本、识别表格、导出图片、读取元数据等

发布时间:2026/7/11 3:04:15
Java 解析 PDF:抽取文本、识别表格、导出图片、读取元数据等 在 Java 项目中处理 PDF 文档最常见也最头疼的需求莫过于解析——把里面的文字、表格、图片和元数据提取出来供后续搜索、分析或迁移使用。不同于生成或编辑 PDF解析更考验库对文档结构的还原能力和对异常布局的容错性。最近我在做一个文档自动化处理系统把 PDF 解析拆成了几个独立的步骤加载验证、文本抽取、表格识别、图片导出、元数据读取。每个步骤都单独封装这样既能复用也方便在复杂文档时定位问题。下面是我的实践记录。1. 环境配置首先需要引入 PDF 解析库。我使用的是 Spire.PDF for Java它提供了专门用于解析的 APIPdfTextExtractor、PdfTableExtractor、PdfImageHelper等。如果你用 Maven在pom.xml中添加repositoriesrepositoryidcom.e-iceblue/idnamee-iceblue/nameurlhttps://repo.e-iceblue.cn/repository/maven-public//url/repository/repositoriesdependenciesdependencygroupIde-iceblue/groupIdartifactIdspire.pdf/artifactIdversion12.7.0/version/dependency/dependencies非 Maven 用户可直接从官网下载 JAR 包并添加到类路径。2. 加载与验证 PDF 文档在进行任何解析之前先加载并验证文档是个好习惯。这一步可以提前发现损坏或不支持的 PDF避免后续解析引发连锁异常。importcom.spire.pdf.PdfDocument;publicclassLoadPDF{publicstaticvoidmain(String[]args){PdfDocumentpdfnewPdfDocument();pdf.loadFromFile(sample.pdf);intpageCountpdf.getPages().getCount();System.out.println(总页数: pageCount);}}这里我们加载了一个 PDF并获取总页数。如果能成功执行说明文件符合 PDF 格式规范文档结构可解析无致命损坏页面树Page Tree可访问。在实际生产环境中我会把这一步作为前置校验失败时直接拒绝处理避免浪费后续计算资源。3. 解析 PDF 中的文本文本提取是最常见的解析操作。与简单读取字符串不同PDF 中的文本是由字形glyph位置拼合而成的并非自然段落。因此提取时最好使用可配置的提取器例如PdfTextExtractor配合PdfTextExtractOptions以获得更干净的输出。importcom.spire.pdf.PdfDocument;importcom.spire.pdf.texts.PdfTextExtractOptions;importcom.spire.pdf.texts.PdfTextExtractor;publicclassExtractPdfText{publicstaticvoidmain(String[]args){PdfDocumentpdfnewPdfDocument();pdf.loadFromFile(sample.pdf);StringBuilderextractedTextnewStringBuilder();PdfTextExtractOptionsoptionsnewPdfTextExtractOptions();// 开启简单提取模式输出的文本更连续、易读options.setSimpleExtraction(true);for(inti0;ipdf.getPages().getCount();i){PdfTextExtractorextractornewPdfTextExtractor(pdf.getPages().get(i));StringpageTextextractor.extract(options);extractedText.append(pageText).append(\n);}System.out.println(extractedText.toString());}}关键点PdfTextExtractor以页面为单位便于定位问题页面PdfTextExtractOptions的setSimpleExtraction(true)可简化布局重建让文本更连贯按页处理也方便大文档的内存控制。如果遇到扫描件或图片型 PDF文本提取会返回空此时需要 OCR 前置处理这是任何纯解析库的共同局限。4. 解析 PDF 中的表格表格解析比纯文本复杂因为它需要从视觉对齐中推断出行列结构。我经常用它处理财务报表、对账单等。importcom.spire.pdf.PdfDocument;importcom.spire.pdf.utilities.PdfTable;importcom.spire.pdf.utilities.PdfTableExtractor;publicclassExtractPdfTable{publicstaticvoidmain(String[]args){PdfDocumentpdfnewPdfDocument();pdf.loadFromFile(sample1.pdf);PdfTableExtractorextractornewPdfTableExtractor(pdf);PdfTable[]tablesextractor.extractTable(0);// 解析第一页if(tables!null){for(PdfTabletable:tables){introwCounttable.getRowCount();intcolCounttable.getColumnCount();System.out.println(行数: rowCount, 列数: colCount);StringBuildersbnewStringBuilder();for(inti0;irowCount;i){for(intj0;jcolCount;j){sb.append(table.getText(i,j));if(jcolCount-1)sb.append(\t);}if(irowCount-1)sb.append(\n);}System.out.println(sb.toString());}}}}PdfTableExtractor会分析页面上的文本对齐方式自动识别表格区域。解析结果是PdfTable对象通过行列索引获取每个单元格的内容。注意表格边界依赖视觉布局复杂或嵌套表格可能识别不准表头行不会自动标记需要业务逻辑额外处理解析后的数据建议导出为 CSV 或存入数据库。5. 解析 PDF 中的图片提取图片常用于存档或复核文档中的图像资源。与文本不同图片是嵌入在页面资源中的独立对象不受布局影响。importcom.spire.pdf.PdfDocument;importcom.spire.pdf.utilities.PdfImageHelper;importcom.spire.pdf.utilities.PdfImageInfo;importjavax.imageio.ImageIO;importjava.awt.image.BufferedImage;importjava.io.File;publicclassExtractPdfImages{publicstaticvoidmain(String[]args)throwsException{PdfDocumentpdfnewPdfDocument();pdf.loadFromFile(sample.pdf);PdfImageHelperhelpernewPdfImageHelper();for(inti0;ipdf.getPages().getCount();i){PdfImageInfo[]infoshelper.getImagesInfo(pdf.getPages().get(i));if(infos!null){for(intj0;jinfos.length;j){BufferedImageimginfos[j].getImage();FileoutnewFile(images/page_i_img_j.png);ImageIO.write(img,PNG,out);}}}}}PdfImageHelper.getImagesInfo()返回页面所有图片的信息每个PdfImageInfo包含图片数据BufferedImage可直接保存为 PNG、JPEG 等格式。实用提醒有些 PDF 中的图片可能只是装饰性背景提取后需人工筛选大图片会占用较多内存建议按需处理或限制尺寸提取后的图片格式和色彩空间可能与原始有差异但一般够用。6. 解析 PDF 元数据元数据标题、作者、主题、创建/修改日期等是文档的“身份证”解析它不需要遍历页面开销极小适合作为预处理步骤。importcom.spire.pdf.PdfDocument;publicclassParsePdfMetadata{publicstaticvoidmain(String[]args){PdfDocumentpdfnewPdfDocument();pdf.loadFromFile(sample.pdf);varinfopdf.getDocumentInformation();System.out.println(标题: info.getTitle());System.out.println(作者: info.getAuthor());System.out.println(主题: info.getSubject());System.out.println(关键词: info.getKeywords());System.out.println(创建者: info.getCreator());System.out.println(生成器: info.getProducer());System.out.println(创建日期: info.getCreationDate());System.out.println(修改日期: info.getModificationDate());}}元数据可能为空使用时最好判空。另外这些信息是文档静态属性不会随内容变化而自动更新除非重新保存。7. 注意事项在实际项目中我通常把上述解析能力组合成一条管道先读元数据做路由再按页提取文本、表格和图片各自落库。但需要注意扫描件/图片型 PDF任何文本或表格解析都无效需要先 OCR例如 Tesseract布局复杂性表格解析依赖视觉对齐对于无边框、错行或合并单元格较多的表格准确率会下降字体编码部分特殊字体可能导致文本提取乱码此时可尝试调整PdfTextExtractOptions或更换字体映射资源清理解析完记得pdf.close()释放文件句柄尤其是批量处理时。另外如果文档体积较大建议按需加载或使用流式处理参考官方示例避免内存溢出。结语以上是我在 Java 中解析 PDF 文档的常用方法加载验证、文本提取、表格识别、图片导出、元数据读取每个环节独立封装便于组合和扩展。得益于专门的 PDF 解析库这些操作可以用简洁的代码实现无需自己解析底层对象。实际使用时请根据文档类型文本型 vs 扫描型和业务需求选择合适的解析策略并对异常情况做好容错。希望这些代码片段能成为你日常开发中的实用参考。如有更多问题欢迎交流。