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

YGA*_*YGA 48 pdf metadata

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

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

无论如何,我使用的是 Windows,但我也可以使用 Mac。

Dan*_*ton 50

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

3 0 obj
<< /Type /Catalog
   /Pages 1 0 R
>>
endobj
Run Code Online (Sandbox Code Playgroud)

它可能包含更多令人困惑的东西,但这是基本结构。只有一个目录,因此您可以在一个大文件中搜索包含/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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 奇妙!这是我在网络上唯一找到如此直接和有用的信息的地方。毕竟,我们并不是*所有人*都有 Acrobat Reader。 (5认同)
  • 例如`/St 8` 或`/St 2`,你可以为显示的标签设置一个起点;但是选择任何数字代替 8(或 2),它必须 &gt;= 1。例如,`1 &lt;&lt; /S /r /St 12 &gt;&gt;` 会将(实际上)*2-6* 的页面编号为(显示)*xii-xvii* - 因为“12”对应于“xii”。 (4认同)
  • @ORMapper 是对的。此方法将 **破坏 pdf 的“外部引用”**“*交叉引用表*”,其中应包含每个 pdf“*对象*”的字节位置 - 使用 [pdf 标准](https:// www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf)。第二个问题是,如果您的文本编辑器**混合了 Unix 和 Windows 行结尾,它可能会破坏**一些阅读器,例如。 verapdf PDF/A 验证器。要解决外部参照问题,如果您使用 Ghostscript,请在​​ pdf 上使用 gs 执行某些操作,在我的情况下重新构建外部参照。据说在 Acrobat 中打开它也可能会重建外部参照。 (3认同)
  • 很棒的信息。这是另一个有用来源的链接:[为 PDF 文档指定一致的页码](http://www.w3.org/TR/WCAG20-TECHS/PDF17.html#PDF17-examples) 来自 W3C。 (2认同)
  • 你确定它像这样工作吗?从查看某些 PDF 文件的原始内容来看,如果前面内容的长度发生变化,则某些指向文件中位置的索引号似乎必须在目录之后更新。 (2认同)

hac*_*rb9 12

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

注意 2:不喜欢使用文本编辑器?首先尝试使用诸如jpdftweak 之类的 GUI 编辑器。有时 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.
    
    Run Code Online (Sandbox Code Playgroud)
  3. fix-qdf foo.qdf >bar.qdf
  4. 测试栏.qdf
  5. qpdf bar.qdf bar.pdf

详细步骤

第1步。

将文档转换为易于编辑的 QDF 格式。从命令行运行 qpdf 像这样:

qpdf -qdf foo.pdf foo.qdf
Run Code Online (Sandbox Code Playgroud)

注意:如果您还没有安装 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 页开始编号。

例子

以下是 PageLabels 外观的完整示例,并添加了注释:

/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)
      >>
  ]
>>
Run Code Online (Sandbox Code Playgroud)

如果文件没有 PageLabels,请将它们添加到/Type /Catalog. 例如,一个人可能会改变,

1 0 obj
<<
  …
  /Type /Catalog
>>
endobj
Run Code Online (Sandbox Code Playgroud)

进入,

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
Run Code Online (Sandbox Code Playgroud)

可选:从不同的数字开始 /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
Run Code Online (Sandbox Code Playgroud)

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

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

  31
  <<
    /S /D
    /P (A-)     % label appendix pages A-1, A-2, A-3
  >>
Run Code Online (Sandbox Code Playgroud)

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

     0 << /P (Cover) >>        % No number, just "Cover"
Run Code Online (Sandbox Code Playgroud)

第 3 步。

运行fix-qdf以使您的编辑有效 PDF 并将输出放在 bar.qdf 中。

fix-qdf foo.qdf > bar.qdf
Run Code Online (Sandbox Code Playgroud)

第四步。

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

第 5 步。

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

qpdf bar.qdf bar.pdf
Run Code Online (Sandbox Code Playgroud)

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


Pkk*_*kkm 7

pdftk 的 Java 变体从版本 3.1.0 开始支持编辑页面标签。

要使用它,首先创建一个带有标签的文件,假设它的名称为metadata.txt

PageLabelBegin
PageLabelNewIndex: 1
PageLabelStart: 1
PageLabelPrefix: Cover
PageLabelNumStyle: NoNumber
PageLabelBegin
PageLabelNewIndex: 2
PageLabelStart: 1
PageLabelPrefix: Back Cover
PageLabelNumStyle: NoNumber
PageLabelBegin
PageLabelNewIndex: 3
PageLabelStart: 1
PageLabelNumStyle: LowercaseRomanNumerals
PageLabelBegin
PageLabelNewIndex: 27
PageLabelStart: 1
PageLabelNumStyle: DecimalArabicNumerals
Run Code Online (Sandbox Code Playgroud)
  • PageLabelNewIndex是应用编号样式的页面,从一开始计数。
  • PageLabelStart是起始编号。例如,如果您在此处指定 5,则页面编号将为 5, 6, 7, ...
  • PageLabelNumStyle可以是DecimalArabicNumeralsUppercaseRomanNumeralsLowercaseRomanNumeralsUppercaseLettersLowercaseLettersNoNumber

完成编辑后,将元数据应用到您的 PDF 文件:

pdftk book.pdf update_info metadata.txt output book-with-metadata.pdf
Run Code Online (Sandbox Code Playgroud)


Kur*_*fle 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
Run Code Online (Sandbox Code Playgroud)

但是,我似乎记得,上次我尝试这样做时(大约 2 年前),这并不可靠或完全有效。

更新:我的记忆力并没有让我失望。我现在再次尝试并为此提交了一份关于 Ghostscript 的错误报告错误 691889。按照错误报告的链接查看详细信息。


小智 5

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


小智 5

有一个小的 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
Run Code Online (Sandbox Code Playgroud)