如何使用JavaScript检测PDF是否为适配屏幕阅读器的带标签版本?
完全可以基于 PDF.js 实现这个检测需求。
带标签PDF(Tagged PDF)的核心标识是PDF文档目录中存在合法的StructTreeRoot(结构树根)对象以及对应的结构化标签树,这个属性确实不会在常规的文档元数据字段中暴露,而PDF.js支持访问PDF底层的字典对象结构,可以读取到相关信息。
核心实现方向
- 第一步:加载PDF文档后首先访问文档目录对象
pdfDocument.catalog,调用get('StructTreeRoot')判断结构树根是否存在,这是带标签PDF的必要前提 - 第二步:校验结构树有效性,避免空结构树的假阳性结果:遍历
StructTreeRoot下的K(子节点)字段,确认存在至少一个符合PDF无障碍标准的有效结构标签(比如H1/H2/P/Figure/Table等) - 第三步(可选深化检测):校验标签和内容的关联关系,比如确认结构节点的
Pg属性关联到对应页码,图片类节点存在Alt文本属性,进一步排除无效空标签的情况
极简示例代码
// 需提前引入PDF.js,获取到加载完成的PDFDocument实例 async function checkIsTaggedPDF(pdfDoc) { try { // 读取结构树根 const structTreeRoot = await pdfDoc.catalog.get("StructTreeRoot"); if (!structTreeRoot) return false; // 校验是否有子节点 const rootChildren = await structTreeRoot.get("K"); if (!Array.isArray(rootChildren) || rootChildren.length === 0) return false; // 标准结构标签白名单,可按需扩展 const validTagSet = new Set(["H1", "H2", "H3", "P", "Figure", "Table", "L", "LI"]); let hasValidTag = false; // 递归遍历结构树 const traverse = async (node) => { if (hasValidTag) return; const tagName = await node.get("S"); if (tagName && validTagSet.has(tagName)) { hasValidTag = true; return; } const kids = await node.get("K"); if (Array.isArray(kids)) { for (const kid of kids) await traverse(kid); } }; for (const child of rootChildren) await traverse(child); return hasValidTag; } catch (err) { // 读取结构树失败默认判定为非带标签PDF return false; } }
注意事项
- 不要使用PDF.js封装的高层文本/渲染API,直接操作底层
catalog的字典属性才能获取到结构树相关信息 - 大文件检测时可以做提前中断优化,找到第一个有效标签即可终止遍历,不需要全量解析整个结构树
- 如果需要更高准确率,可以增加逻辑校验结构节点关联的内容流是否存在,避免纯占位标签导致的假阳性
内容的提问来源于stack exchange,提问作者Gavin Coulson
相关产品推荐
相关产品推荐

