javascript - 从pdf文件中读取注释

标签 javascript php pdf

enter image description here

我有一个 PDF 文件,其中包含在鼠标悬停在带注释的词上时出现的注释和注释建议。

例如,考虑上面的图像,其中您将花费的词被划线(表示不正确的词),并且将鼠标悬停在它上面会显示弹出窗口,其中出现了正确的词。类似地,还有另一个插入符号也是如此。

我想提取两个单词的列表,这将从文件中显示正确和错误的单词。

最佳答案

我刚刚用我们的 SetaPDF-Extractor 做了一个简单的 POC组件(我们的商业产品)导致: result of the POC

遗憾的是,PDF 中的评论“树”并不是那么微不足道。 POC 只是遍历注释并创建过滤器,然后供提取器组件使用。 Here是另一个提取评论树的演示,它可能是排序/更合乎逻辑的结果的基础。

这是我用于给定输出的代码:

<?php
// load and register the autoload function
require_once('library/SetaPDF/Autoload.php');

// create a document instance
$document = SetaPDF_Core_Document::loadByFilename('camtown/Terms-and-Conditions - revised.pdf');
    // initate an extractor instance
$extractor = new SetaPDF_Extractor($document);

// get page documents pages object
$pages = $document->getCatalog()->getPages();

// we are going to save the extracted text in this variable
$results = [];
// map pages and filternames to annotation instances
$annotationsByPageAndFilterName = [];

// iterate over all pages
for ($pageNo = 1, $pageCount = $pages->count(); $pageNo <= $pageCount; $pageNo++) {
    // get the page object
    $page = $pages->getPage($pageNo);
    // get the annotations
    $annotations = array_filter($page->getAnnotations()->getAll(), function(SetaPDF_Core_Document_Page_Annotation $annotation) {
        switch ($annotation->getType()) {
            case SetaPDF_Core_Document_Page_Annotation::TYPE_HIGHLIGHT:
            case SetaPDF_Core_Document_Page_Annotation::TYPE_STRIKE_OUT:
            case SetaPDF_Core_Document_Page_Annotation::TYPE_CARET:
            case SetaPDF_Core_Document_Page_Annotation::TYPE_UNDERLINE:
                return true;
        }

        return false;
    });

    // create a strategy instance
    $strategy = new SetaPDF_Extractor_Strategy_ExactPlain();
    // create a multi filter instance
    $filter = new SetaPDF_Extractor_Filter_Multi();
    // and pass it to the strategy
    $strategy->setFilter($filter);

    // iterate over all highlight annotations
    foreach ($annotations AS $tmpId => $annotation) {
        /**
         * @var SetaPDF_Core_Document_Page_Annotation_Highlight $annotation
         */
        $name = 'P#' . $pageNo . '/HA#' . $tmpId;
        if ($annotation->getName()) {
            $name .= ' (' . $annotation->getName() . ')';
        }

        if ($annotation instanceof SetaPDF_Core_Document_Page_Annotation_TextMarkup) {
            // iterate over the quad points to setup our filter instances
            $quadpoints = $annotation->getQuadPoints();
            for ($pos = 0, $c = count($quadpoints); $pos < $c; $pos += 8) {
                $llx = min($quadpoints[$pos + 0], $quadpoints[$pos + 2], $quadpoints[$pos + 4], $quadpoints[$pos + 6]) - 1;
                $urx = max($quadpoints[$pos + 0], $quadpoints[$pos + 2], $quadpoints[$pos + 4], $quadpoints[$pos + 6]) + 1;
                $lly = min($quadpoints[$pos + 1], $quadpoints[$pos + 3], $quadpoints[$pos + 5], $quadpoints[$pos + 7]) - 1;
                $ury = max($quadpoints[$pos + 1], $quadpoints[$pos + 3], $quadpoints[$pos + 5], $quadpoints[$pos + 7]) + 1;

                // reduze it to a small line
                $diff = ($ury - $lly) / 2;
                $lly = $lly + $diff - 1;
                $ury = $ury - $diff - 1;

                // Add a new rectangle filter to the multi filter instance
                $filter->addFilter(
                    new SetaPDF_Extractor_Filter_Rectangle(
                        new SetaPDF_Core_Geometry_Rectangle($llx, $lly, $urx, $ury),
                        SetaPDF_Extractor_Filter_Rectangle::MODE_CONTACT,
                        $name
                    )
                );
            }
        }

        $annotationsByPageAndFilterName[$pageNo][$name] = $annotation;
    }

    // if no filters for this page defined, ignore it
    if (count($filter->getFilters()) === 0) {
        continue;
    }

    // pass the strategy to the extractor instance
    $extractor->setStrategy($strategy);
    // and get the results by the current page number
    $result = $extractor->getResultByPageNumber($pageNo);
    if ($result === '')
        continue;

    $results[$pageNo] = $result;
}

// debug output
foreach ($annotationsByPageAndFilterName AS $pageNo => $annotations) {
    echo '<h1>Page No #' . $pageNo . '</h1>';
    echo '<table border="1"><tr><th>Name</th><th>Text</th><th>Subject</th><th>Comment</th></tr>';
    foreach ($annotations AS $name => $annotation) {
        echo '<tr>';
        echo '<td>' . $name . '</td>';
        echo '<td><pre>' . ($results[$pageNo][$name] ?? '') . '</pre></td>';
        echo '<td><pre>' . $annotation->getSubject() . '</pre></td>';
        echo '<td><pre>' . $annotation->getContents() . '</pre></td>';
        echo '</tr>';
    }

    echo '</table>';
}

关于javascript - 从pdf文件中读取注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57248230/

相关文章:

php - 查询将旧哈希密码转换为 AES

php - 在PHP中过滤重复的电话号码

php - 从 MySQL 生成表到 PDF(使用 PHP)

javascript - 从单引号中的文本中获取单词

javascript - 使用 isBetween 函数比较对象中的键值

javascript - 将输入框调整为内容 onload

pdf - 在 pdf/postscript 中围绕一个圆圈放置超链接

javascript - 使用 Google Apps 脚本创建 "old-fashioned"邮件合并时出现问题

php - Laravel 5.3 护照的单点登录

javascript - 通过组合 pdf.js 和 pdf.worker.js 创建 pdf.js 的离线版本