You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移至iText-Core 8.0.3:如何替代getMetaData读取PDF元数据

问题描述

我需要从PDF文件中读取元数据,目前基于iTextPDF 5.5.13.3实现了如下代码:

static String getPdfFormVersion() throws IOException {

    InputStream inputStream = PDFVersionExtractor.class.getResourceAsStream("/test.pdf");
    final PdfReader pdfReader = new PdfReader(inputStream);

    final byte[] docMetaData = pdfReader.getMetadata();
    try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
        byteArrayOutputStream.write(docMetaData);
        final String fileXML = byteArrayOutputStream.toString(StandardCharsets.UTF_8.name());
        final String versionNode = fileXML.substring(fileXML.indexOf("<desc:version"), fileXML.indexOf("</desc:version>"));
        return versionNode;
    }
}

当前依赖:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.3</version>
</dependency>

计划迁移至iText 8.0.3,依赖已调整为:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-core</artifactId>
    <version>8.0.3</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>kernel</artifactId>
    <version>8.0.3</version>
    <type>pom</type>
</dependency> 

但新版本中PdfReader类的getMetaData()方法已移除,找不到替代方法,请问如何用iText 8.0.3提取PDF元数据?

解决方案

iText 8.x重构了API,元数据需通过PdfDocument和文档目录字典访问,以下是适配后的实现:

1. 简化依赖(可选)

itext-core pom已包含kernel模块,可简化依赖配置:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-core</artifactId>
    <version>8.0.3</version>
    <type>pom</type>
</dependency>

2. 重写元数据提取代码

通过PdfDocument获取XMP元数据,再按原有逻辑提取目标节点:

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfDictionary;
import com.itextpdf.kernel.pdf.PdfName;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

static String getPdfFormVersion() throws IOException {
    try (InputStream inputStream = PDFVersionExtractor.class.getResourceAsStream("/test.pdf");
         PdfReader pdfReader = new PdfReader(inputStream);
         PdfDocument pdfDoc = new PdfDocument(pdfReader)) {
        
        // 获取文档目录字典
        PdfDictionary catalog = pdfDoc.getCatalog().getPdfObject();
        // 读取XMP元数据字节数组
        byte[] metaBytes = catalog.getAsStream(PdfName.Metadata).getBytes();
        
        // 转换为XML字符串并提取目标节点
        String fileXML = new String(metaBytes, StandardCharsets.UTF_8);
        int startIndex = fileXML.indexOf("<desc:version");
        int endIndex = fileXML.indexOf("</desc:version>");
        
        return startIndex != -1 && endIndex != -1 ? fileXML.substring(startIndex, endIndex) : null;
    }
}

优化建议:使用XMP API解析(更可靠)

直接字符串截取易受XML格式变化影响,可使用iText内置的XMP解析器操作元数据节点:

import com.itextpdf.kernel.pdf.xmp.XmpException;
import com.itextpdf.kernel.pdf.xmp.XmpMeta;
import com.itextpdf.kernel.pdf.xmp.XmpParser;
import java.io.ByteArrayInputStream;

static String getPdfFormVersion() throws IOException, XmpException {
    try (InputStream inputStream = PDFVersionExtractor.class.getResourceAsStream("/test.pdf");
         PdfReader pdfReader = new PdfReader(inputStream);
         PdfDocument pdfDoc = new PdfDocument(pdfReader)) {
        
        PdfDictionary catalog = pdfDoc.getCatalog().getPdfObject();
        byte[] metaBytes = catalog.getAsStream(PdfName.Metadata).getBytes();
        
        // 解析XMP元数据
        XmpMeta xmpMeta = XmpParser.parse(new ByteArrayInputStream(metaBytes));
        // 替换为实际的命名空间URI(需匹配PDF中desc的命名空间)
        String version = xmpMeta.getPropertyString("http://your-desc-namespace-uri", "version");
        
        return version;
    }
}

内容的提问来源于stack exchange,提问作者fascynacja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:36:16