我想将nameddests添加到现有PDF的位置,这些位置由一些字符串指定(例如:在字符串“第1章”的第一个出现时放置一个nameddest)。然后我希望能够使用JS事件跳转到那些命名的参数。
到目前为止,我使用PHP和FPDF / FPDI实现了目标:我可以使用FPDI加载现有的PDF,并使用稍微修改的[1]版本将nameddests添加到任意位置。然后我可以将PDF嵌入到iframe中,并使用例如JS按钮导航到nameddests。
然而,到目前为止,我需要手工找出命名的位置。如何在PDF中搜索字符串并获取搜索结果的页码和位置,以便我可以在那里添加nameddests?
答案 0 :(得分:0)
使用FPDI分析PDF文档的内容是不可能的。
我们(Setasign - FPDI和PDF_NamedDestinations的作者)有一个产品(非免费),它允许您处理此任务:SetaPDF-Extractor组件。
项目的简单POC可能如下:
<?php
// load and register the autoload function
require_once('library/SetaPDF/Autoload.php');
$writer = new SetaPDF_Core_Writer_Http('result.pdf', true);
$document = SetaPDF_Core_Document::loadByFilename('file/with/chapters.pdf', $writer);
$extractor = new SetaPDF_Extractor($document);
// define the word strategy
$strategy = new SetaPDF_Extractor_Strategy_Word();
$extractor->setStrategy($strategy);
// get the pages helper
$pages = $document->getCatalog()->getPages();
// get access to the named destination tree
$names = $document
->getCatalog()
->getNames()
->getTree(SetaPDF_Core_Document_Catalog_Names::DESTS, true);
for ($pageNo = 1; $pageNo <= $pages->count(); $pageNo++) {
/**
* @var SetaPDF_Extractor_Result_Word[] $words
*/
$words = $extractor->getResultByPageNumber($pageNo);
// iterate over all found words and search for "Chapter" followed by a numeric string...
foreach ($words AS $word) {
$string = $word->getString();
if ($string === 'Chapter') {
$chapter = $word;
continue;
}
if (null === $chapter) {
continue;
}
// is the next word a numeric string
if (is_numeric($word->getString())) {
// get the coordinates of the word
$bounds = $word->getBounds()[0];
// create a destination
$destination = SetaPDF_Core_Document_Destination::createByPageNo(
$document,
$pageNo,
SetaPDF_Core_Document_Destination::FIT_MODE_FIT_BH,
$bounds->getUl()->getY()
);
// create a name (shall be unique)
$name = strtolower($chapter . $word->getString());
try {
// add the named destination to the name tree
$names->add($name, $destination->getPdfValue());
} catch (SetaPDF_Core_DataStructure_Tree_KeyAlreadyExistsException $e) {
// handle this exception
}
}
$chapter = null;
}
}
// save and finish the resulting document
$document->save()->finish();
然后,您可以通过URL以这种方式访问指定的目的地(查看器应用程序和浏览器插件需要支持此功能):
http://www.example.com/script.php#chapter1
http://www.example.com/script.php#chapter2
http://www.example.com/script.php#chapter10
...