如何使用 Qpdf 编辑 PDF 页码

如何使用 Qpdf 编辑 PDF 页码

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

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

不管怎样,我使用 Windows,尽管我也可以使用 Mac。

答案1

你想要的确实叫做页面标签并且可以轻松地直接添加到 PDF 的源代码中。将文件扩展名从pdf重命名为txt并在文本编辑器中打开文件(这可能很慢,具体取决于文件大小,请耐心等待)。有关页面标签的信息存储在名为文档目录看起来像这样:

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

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

您可以在PDF 1.7 标准

答案2

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

笔记2:不习惯使用文本编辑器?尝试使用 GUI 编辑器,例如pdftweak首先。有时 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. 测试条形图.qdf
  5. qpdf bar.qdf bar.pdf

详细步骤

步骤1。

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

qpdf -qdf foo.pdf foo.qdf

笔记:如果你尚未安装 qpdf,可以从以下位置下载 Microsoft Windows 可执行文件https://github.com/qpdf/qpdf/releasesUnix 系统(例如 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)
      >>
  ]
>>

如果文件没有 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) 的前缀将为您提供只包含单词而不包含任何数字的页面。例如,如果您希望封面页只带有标签“封面”,这将非常有用。

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

步骤3.

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

fix-qdf foo.qdf > bar.qdf

步骤4。

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

步骤5.

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

qpdf bar.qdf bar.pdf

好了。您完成了。现在您有了一个带有正确标记页码的文档(bar.pdf)。

答案3

有一个小的 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

答案4

如果我理解正确的话,应该工作:

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

但是,我似乎请记住,上次我尝试这个(大约两年前)时,它并不可靠或完全起作用。

更新:我的记忆力没有衰退。我现在再次尝试并为 Ghostscript 提交了一份错误报告错误 691889关于此问题。请点击错误报告链接查看详细信息。

相关内容