迁移至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
相关产品推荐
相关产品推荐

