如何更改PDF元数据中的内部页码?


37

我有一个通过非Acrobat方式创建的pdf文档(打印为pdf,然后合并一堆pdf),但我想手动更改页码(即前几页只是标题页,即被标记为 “第1页”是真正的PDF格式的第7张)。什么是最简单(最好是免费)的方法?

需要明确的是,我并不是要更改页面本身上的编号,而是要保存pdf存储的“元数据”中的页面编号(页面本身已经正确编号;我只想“转到页面1”到标记为 1 的页面(可能是第7页)。

值得一提的是,尽管我也可以使用Mac,但我使用Windows。


我不确定我是否完全了解您的描述和要求。您可以提供要修改的样本PDF的链接吗?
Kurt Pfeifle

是否有命令行工具可以执行此操作,例如在没有实际打开txt文件的大pdf文件上?
jj_p 2013年

例如pdftk?
jj_p

Answers:


39

您真正想要的就是页面标签,可以轻松地直接将其添加到PDF的源代码中。将文件扩展名从重命名为pdftxt然后在文本编辑器中打开文件(这可能会很慢,具体取决于文件大小,请耐心等待)。有关页面标签的信息存储在称为文档目录的节点中,该节点如下所示:

3 0 obj
<< /Type /Catalog
   /Pages 1 0 R
>>
endobj

它可能包含更多令人困惑的内容,但这是基本结构。目录只有一个,因此在一个大文件中,您可以搜索包含的节点/Catalog。现在,您可以通过插入以下/PageLabels条目来进行所需的更改:

3 0 obj
<< /Type /Catalog
   /Pages 1 0 R
   /PageLabels << /Nums [ 0 << /P (cover) >>
                          % labels 1st page with the string "cover"
                          1 << /S /r >>
                          % numbers pages 2-6 in small roman numerals
                          6 << /S /D >>
                          % numbers pages 7-x in decimal arabic numerals
                        ]
               >>
>>
endobj

以数字开头的三行称为页索引。第1页具有索引0,第2 页具有索引,1依此类推。它们始终描述范围,因此带有的行1 <<...>>适用于从索引1到5的6 <<...>>所有页面,带有的行适用于从6到最后一页的所有页面。0 <<...>>必须始终定义标签。

您可以在PDF标准PDF标准Wiki中找到有关页面标签和PDF源代码的更多信息。


4
奇妙!这是我在网络上找到此类直接有用信息的唯一地方。毕竟,我们都没有Acrobat Reader。
Noldorin

3
使用示例/St 8/St 2,您可以为显示的标签设置起点;但请选择任何数字代替8(或2),该数字必须> =1。例如,1 << /S /r /St 12 >>将(实际上)2-6中的页面编号为(显示)xii-xvii-因为“ 12”对应于“ xii”。
n611x007 2013年

1
感谢您的回答,但是以我的经验,这种方法有时行得通,有时却行不通;另外,我碰巧发现了多个目录:您如何解释?
jj_p

1
很棒的信息。这是另一个有用的资源的链接:从W3C 为PDF文档指定一致的页码
亚当·麦克勒

2
您确定它像这样工作吗?从看一些PDF文件的原始内容这似乎是一些指标数字,指向的目录之后的文件中的位置就必须更新如果前面的内容长度的变化..
OR映射

6

如果我对您的理解正确,那么它应该如何工作:

gs \
  -o modified-pagelabels-50pages.pdf \
  -sDEVICE=pdfwrite \
  -c "[ /Page 1 /Label (i)     /PAGELABEL pdfmark" \
  -c "[ /Page 2 /Label (ii)    /PAGELABEL pdfmark" \
  -c "[ /Page 3 /Label (III)   /PAGELABEL pdfmark" \
  -c "[ /Page 4 /Label (four)  /PAGELABEL pdfmark" \
  -c "[ /Page 5 /Label (v)     /PAGELABEL pdfmark" \
  -c "[ /Page 6 /Label (|||||) /PAGELABEL pdfmark" \
  -f 50pages.pdf

但是,我似乎记得,上次尝试此操作(大约2年前)时,此操作无法可靠或完全起作用。

更新:我的记忆没有让我失望。现在,我再次尝试并提交了有关此问题的Ghostscript错误报告错误691889。单击错误报告的链接以查看详细信息。


5

注意1:可接受的答案在大多数情况下仍然是正确的,但存在一些差距。缺少许多PDF文件不能直接编辑为文本的缺点。即使是这样,这种编辑有时也会损坏PDF,使其无法读取。一种适用于Unix和Microsoft Windows的解决方案是qpdf,它可以将PDF文件转换为“ QDF”,这是一种文本可编辑形式,仍然是有效的PDF文件。编辑QDF文件以更正任何损坏后,该qpdf软件包随附了fix-qdf重新计算偏移量的软件包。

注意2:对文本编辑器感到不舒服吗?首先尝试使用GUI编辑器,例如jpdftweak。有时,GUI pdf编辑器可以工作,在这种情况下,您就完成了。但是,当它们失败时(就像我经常遇到的那样),您可以尝试这种更可靠的选择。无论哪种方式,请不要拒绝我的回答,因为它不够优雅。


如何使用Qpdf编辑PDF页码

摘要:

  1. qpdf -qdf foo.pdf foo.qdf
  2. 编辑foo.qdf

     0 << >>           % No label on first pages
     6 << /S /D >>     % Start numbering from 7th page.
    
  3. fix-qdf foo.qdf >bar.qdf
  4. 测试栏
  5. qpdf bar.qdf bar.pdf

详细步骤

步骤1。

将文档转换为易于编辑的QDF格式。从命令行运行qpdf,如下所示:

qpdf -qdf foo.pdf foo.qdf

注意:如果尚未安装qpdf,则可以从https://github.com/qpdf/qpdf/releases下载Microsoft Windows可执行文件。Unix系统(例如Ubuntu和Debian GNU / Linux)可以通过键入进行安装apt install qpdf

第2步。

使用文本编辑器(例如notepad ++,emacs或gedit)编辑QDF文档。搜索单词/Catalog并注意其中的《尖括号》。在附近,您会找到当前的/PageLabels如果有的话)。

我们将在每个部分添加不同的编号/PageLabels。格式为start-page<< style>>。请注意,空格并不重要,文档的第一页是0。除非另有说明,否则新部分始终从1开始编号。

例子

这是PageLabel外观的完整示例,并添加了注释:

/Type /Catalog
/PageLabels <<
  /Nums [
    0           % From the first page of the document,
      <<
        /S /r   % ...use the lowercase roman numeral style.
      >>
    6           % From seventh page onward,
      <<
        /S /D   % ...use ordinary digits (arabic numerals)
      >>
  ]
>>

如果文件没有PageLabels,请在之后添加它们/Type /Catalog。例如,一个人可能会改变,

1 0 obj
<<
  …
  /Type /Catalog
>>
endobj

进入

1 0 obj
<<
  … 
  /Type /Catalog
  /PageLabels
      << /Nums [
    0 << >>                 % No label for cover
    1 << /S /r >>           % i, ii for index
    3 << /S /D /St 15 >>    % 15, 16, 17, ... for article
    31 << /S /D /P (A-) >>  % A-1, A-2, A-3... for appendix
       ]
  >>
>>
endobj

可选:从不同的数字开始 /St

除非另有说明,否则每个部分均以1重新开始编号/St。请注意,在上面的示例中,第四页从15开始。

可选:使用不同的样式 /S

/S运营商需要一个参数,可以让你选择编号样式,

  • / D数字(1、2、3 ...)
  • / R大写罗马字(I,II,III ...)
  • / r小写罗马(i,ii,iii ...)
  • / A大写字母(A,B,C,....,X,Y,Z,AA,AB,AC,...)
  • / a小写字母(a,b,c,....,x,y,z,aa,ab,ac,...)

如果省略/S操作员,则该页页面将没有编号。例如:

0 << >>         % No label for cover

可选:将前缀添加到每个页面 /P

通过在括号后指定一个单词,可以在页码之前显示任何文本字符串/P

  31
  <<
    /S /D
    /P (A-)     % label appendix pages A-1, A-2, A-3
  >>

指定不带样式的前缀(/S),将使您的页面只有单词,没有任何数字。例如,如果您希望封面仅带有标签“ Cover”,这将很有用。

     0 << /P (Cover) >>        % No number, just "Cover"

第三步

运行fix-qdf以使您的编辑有效为PDF,然后将输出放入bar.qdf。

fix-qdf foo.qdf > bar.qdf

第四步。

在您的PDF查看程序中打开bar.qdf,并检查其编号是否正确。

步骤五

将QDF文件转换回普通PDF,如下所示:

qpdf bar.qdf bar.pdf

da 你完成了。现在,您在bar.pdf中有一个带有正确标记页码的文档。


4

有一个小的python脚本可以完成这项工作:https : //github.com/lovasoa/pagelabels-py

在您的情况下,请致电:

./addpagelabels.py --delete file.pdf
./addpagelabels.py --startpage 1 --type 'roman lowercase' file.pdf
./addpagelabels.py --startpage 7 --type arabic file.pdf

这完全按照我的需要完成了工作。谢谢!
telotortium

3

jPdf Tweak是一个开源图形实用程序,可让您编辑PDF文件中的页面标签。该文档页面提供一步一步的指示。


我使用它来将自定义页面标签添加为“空”格式,并以文本作为前缀。做得好!
马特·塞弗顿

与手工编辑文本相比,这是一种更好的答案
Endolith

请在此处添加分步说明,而不要依赖外部链接。谢谢!
hackerb9

1

要删除旧的,可能最简单的跨平台方法就是裁剪旧的。例如,您可以使用BRISS。

使用免费工具添加新工具比较棘手。就我个人而言,我可能会使用pdflatex来完成此任务,就像在StackExchange答案中一样,尽管除非您有其他使用pdflatex的用途,否则这可能是一个相当复杂的解决方案。

我认为可以做到,但是可以使用jPdfTweak代替。


1

Dane H.给出的方法确实可以与Acrobat Reader(或更确切地说,是Adobe Reader 的当前版本)一起使用。需要注意的一点是:顶部的字段只能接受8个字符,因此,如果使用了这样的标签,则不能在其中输入“主题索引”之类的内容。但是,您可以改为使用菜单项“视图”>“页面导航”>“转到...”,或等效的键。

另一个提示:pdf规范始终分配连续的页码,因此,在通过扫描成对的页面生成的文档中,两组编号不一致(除非您费力地为每页单独编号)。但是您可以毫不费力地设置文档,因此适用“进入第n页使您进入第2n和2n + 1页”的约定。


1

Danes的答案是最好的,格式现在有所更改,这可能会有所帮助:

%PDF-1.6

29241 0 obj

<</Metadata 1685 0 R/Outlines 29461 0 R/PageLabels<</Nums[0<</S/D>>3<</S/D/St 6>>4<</S/D/St 10>>5<</S/D/St 12>>15<</S/D/St 70>>16<</S/D/St 72>>17<</S/D/St 80>>18<</S/D/St 82>>19<</S/D/St 90>>23<</S/D/St 96>>25<</S/D/St 99>>29<</S/D/St 110>>31<</S/D/St 130>>32<</S/D/St 133>>35<</S/D/St 137>>36<</S/D/St 140>>37<</S/D/St 145>>39<</S/D/St 150>>40<</S/D/St 152>>42<</S/D/St 155>>43<</S/D/St 160>>46<</S/D/St 165>>47<</S/D/St 167>>48<</S/D/St 170>>49<</S/D/St 180>>50<</S/D/St 190>>52<</S/D/St 300>>53<</S/D/St 305>>54<</S/D/St 319>>56<</S/D/St 380>>57<</S/D/St 390>>58<</S/D/St 500>>67<</S/D/St 515>>68<</S/D/St 525>>70<</S/D/St 550>>71<</S/D/St 553>>72<</S/D/St 560>>73<</S/D/St 600>>76<</S/D/St 620>>78<</S/D/St 650>>82<</S/D/St 670>>85<</S/D/St 700>>95<</S/D/St 714>>117<</S/D/St 900>>162<</S/D/St 1000>>178<</S/D/St 1200>>209<</S/D/St 1500>>263<</S/D/St 1555>>270<</S/D/St 1563>>389<</S/D/St 1681>>522<</S/D/St 1813>>]>> /PageMode/UseOutlines/Pages 29177 0 R/Type/Catalog>>

endobj

1

我发现,如果在“ / outlines”区域中已经设置了“ / titles”,则无法直接编辑文件(由pdftk压缩)。上面的文章中介绍的直接编辑技术已在YouTube上进行了演示:https//www.youtube.com/watch?v = zoH1Z_hSpak

但是,通过编辑此处使用的“ doc_data.txt”文件,pdftk的“更新”功能可能更直观(当PDF文件的“ / outlines”区域中已经存在“ / titles”时更加可靠) : /www.pdflabs.com/blog/export-and-import-pdf-bookmarks/


1
@Bob,您好!仅链接的答案质量低下。如果目标站点移动或消失,它们将无用。请编辑您的答案,并在此处引用解决方案的相关部分。
C0deDaedalus

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.