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

Adobe Acrobat JavaScript:检测含下划线/删除线文本的PDF页面并提取至新文档的实现方法

Adobe Acrobat JavaScript:检测含下划线/删除线文本的PDF页面并提取至新文档的实现方法

你遇到的问题其实是Acrobat JavaScript API的一个常见限制——getPageNthWord()确实只会返回纯文本字符串,完全不带任何样式属性,所以你代码里尝试访问.style.strikeThru或者.underline肯定会报错,因为字符串根本没有这些属性。

之所以会这样,是因为PDF里的下划线、删除线这类装饰,很多时候并不是作为文本的“属性”存储的,而是单独绘制的图形线条(比如一条细横线),和文本内容是分离的元素。Acrobat的基础文本提取接口并没有把这些图形和对应的文本关联起来,所以没法直接通过文本对象获取样式信息。

可行的实现思路

要实现你的需求,得换个思路:我们可以先获取页面上所有文本的位置,再检查页面上是否有和这些文本位置重叠的、符合下划线/删除线特征的图形元素。同时先修正你代码里的一些基础错误(比如重复添加页面、插入参数错误),下面是改进后的代码框架:

var pageSet = new Set(); // 用Set避免重复添加同一页面

for (var p = 0; p < this.numPages; p++) {
    var hasStyledText = false;
    var wordCount = this.getPageNumWords(p);
    
    // 遍历页面所有单词,获取它们的位置边界
    for (var n = 0; n < wordCount; n++) {
        var wordQuads = this.getPageNthWordQuads(p, n);
        if (!wordQuads || wordQuads.length === 0) continue;
        
        // 提取单词的坐标边界(单个单词通常对应一个四边形)
        var quad = wordQuads[0];
        var wordLeft = Math.min(quad[0], quad[2], quad[4], quad[6]);
        var wordRight = Math.max(quad[0], quad[2], quad[4], quad[6]);
        var wordTop = Math.max(quad[1], quad[3], quad[5], quad[7]);
        var wordBottom = Math.min(quad[1], quad[3], quad[5], quad[7]);
        var wordHeight = wordTop - wordBottom;
        
        // 解析页面内容流,查找符合特征的水平线条
        var pageContent = this.getPageContent(p);
        var linePattern = /(\d+\.?\d*) (\d+\.?\d*) m (\d+\.?\d*) (\d+\.?\d*) l S/g;
        var match;
        while ((match = linePattern.exec(pageContent)) !== null) {
            var x1 = parseFloat(match[1]), y1 = parseFloat(match[2]);
            var x2 = parseFloat(match[3]), y2 = parseFloat(match[4]);
            
            // 判断是否是近似水平的线条(y坐标差异极小)
            if (Math.abs(y1 - y2) < 0.5) {
                var lineLeft = Math.min(x1, x2);
                var lineRight = Math.max(x1, x2);
                var lineY = y1;
                
                // 判断是否为下划线(线条在文本下方,距离不超过单词高度1/3)
                var isUnderline = (lineY > wordBottom - wordHeight/3) && (lineY < wordBottom);
                // 判断是否为删除线(线条在文本垂直中间区域)
                var isStrikeThru = (lineY > wordBottom + wordHeight/3) && (lineY < wordTop - wordHeight/3);
                // 判断线条和单词的水平范围是否重叠
                var isOverlap = (lineRight > wordLeft) && (lineLeft < wordRight);
                
                if ((isUnderline || isStrikeThru) && isOverlap) {
                    hasStyledText = true;
                    break;
                }
            }
        }
        
        if (hasStyledText) break;
    }
    
    if (hasStyledText) {
        pageSet.add(p);
    }
}

var pageArray = Array.from(pageSet);
if (pageArray.length > 0) {
    var d = app.newDoc();
    // 修正插入页面的参数:nStart和nEnd要取单个页码
    for (var n = 0; n < pageArray.length; n++) {
        var pageNum = pageArray[n];
        d.insertPages({
            nPage: d.numPages - 1,
            cPath: this.path,
            nStart: pageNum,
            nEnd: pageNum,
        });
    }
    // 删除初始的空白页
    d.deletePages(0);
}

补充说明

上面的内容流解析是简化版逻辑,实际PDF的内容流可能更复杂(比如包含矩阵变换、不同的线条绘制命令),如果要覆盖更多场景,你需要更完整的PDF内容流解析逻辑。另外,有些PDF的下划线是字体本身的一部分(比如内置下划线的字形),这种情况用上述方法无法检测,需要结合字体信息判断,难度会更高。

你提到有人说这在Adobe里不可能,其实也不完全对——只是没有直接的API方法,需要通过间接的图形检测来实现,不过确实存在不少边缘情况可能导致检测不准确。

备注:内容来源于stack exchange,提问作者Andrew Rehn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:23:08