如何将页码添加到Postscript / PDF

时间:2009-10-21 20:10:55

标签: pdf postscript

如果你在Postscript中有一个大文件(500页+)并想要添加页码,有人知道怎么做吗?

14 个答案:

答案 0 :(得分:22)

根据rcs提出的解决方案,我做了以下内容:

将文档转换为example.pdf并运行pdflatex addpages,其中addpages.tex读取:

\documentclass[8pt]{article}
\usepackage[final]{pdfpages}
\usepackage{fancyhdr}

\topmargin 70pt
\oddsidemargin 70pt

\pagestyle{fancy}
\rfoot{\Large\thepage}
\cfoot{}
\renewcommand {\headrulewidth}{0pt}
\renewcommand {\footrulewidth}{0pt}

\begin{document}
\includepdfset{pagecommand=\thispagestyle{fancy}}
\includepdf[fitpaper=true,scale=0.98,pages=-]{example.pdf}
% fitpaper & scale aren't always necessary - depends on the paper being submitted.
\end{document}

或者,对于双面页面(即页面编号始终在外面):

\documentclass[8pt]{book}
\usepackage[final]{pdfpages}
\usepackage{fancyhdr}

\topmargin 70pt
\oddsidemargin 150pt
\evensidemargin -40pt

\pagestyle{fancy}
\fancyhead{} 
\fancyfoot{} 
\fancyfoot[LE,RO]{\Large\thepage}

\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}

\begin{document}
\includepdfset{pages=-,pagecommand=\thispagestyle{fancy}}
\includepdf{target.pdf}
\end{document}

更改标题边距的简便方法:

% set margins for headers, won't shrink included pdfs
% you can remove the topmargin/oddsidemargin/evensidemargin lines
\usepackage[margin=1in,includehead,includefoot]{geometry}

答案 1 :(得分:15)

你可以简单地使用

<强> pspdftool

以这种方式:

pspdftool 'number(x=-1pt,y=-1pt,start=1,size=10)' input.pdf output.pdf

看到这两个例子(无编号和编号 pdf与pspdftool)

无编号的pdf

http://ge.tt/7ctUFfj2

编号为pdf

http://ge.tt/7ctUFfj2

将此作为第一个命令行参数:

number(start=1, size=40, x=297.5 pt, y=10 pt)

答案 2 :(得分:13)

这可能是一个解决方案:

  1. 使用ps2pdf
  2. 将postscript转换为pdf
  3. 创建一个LaTeX文件并使用 pdfpages 包(\includepdf
  4. 插入页面
  5. pagecommand={\thispagestyle{plain}}
  6. 的参数中使用 fancyhdr 包中的\includepdf或其他内容
  7. 如果需要postscript输出,请通过pdf2ps
  8. 将pdflatex输出转换回postscript

答案 3 :(得分:13)

我曾经使用胶乳在我的pdf中添加页码,就像在接受的答案中一样。

现在我发现了一种更简单的方法: 使用enscript创建包含页码的标题的空白页面,然后使用pdftkmultistamp选项将标题放在您的文件中。

此bash脚本需要pdf文件作为唯一参数:

#!/bin/bash
input="$1"
output="${1%.pdf}-header.pdf"
pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
enscript -L1 --header='||Page $% of $=' --output - < <(for i in $(seq "$pagenum"); do echo; done) | ps2pdf - | pdftk "$input" multistamp - output $output

答案 4 :(得分:5)

除了captaincomic的解决方案之外,我还扩展了它以支持在任何页面上开始页码编号。

需要enscript,pdftk 1.43或更高版本以及pdfjam(用于pdfjoin实用程序)

#!/bin/bash
input="$1"
count=$2
blank=$((count - 1))
output="${1%.pdf}-header.pdf"
pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
(for i in $(seq "$blank"); do echo; done) | enscript -L1 -B --output - | ps2pdf - > /tmp/pa$$.pdf
(for i in $(seq "$pagenum"); do echo; done) | enscript -a ${count}- -L1 -F Helvetica@10 --header='||Page $% of $=' --output - | ps2pdf - > /tmp/pb$$.pdf
pdfjoin --paper letter --outfile /tmp/join$$.pdf /tmp/pa$$.pdf /tmp/pb$$.pdf &>/dev/null
cat /tmp/join$$.pdf | pdftk "$input" multistamp - output "$output"
rm /tmp/pa$$.pdf
rm /tmp/pb$$.pdf
rm /tmp/join$$.pdf

例如..将它放在/usr/local/bin/pagestamp.sh中并执行如下:

pagestamp.sh doc.pdf 3

这将在第3页开始页码..当你有封面,标题页和目录等时很有用。

不幸的是,enscript的--footer选项被破坏了,所以你无法使用这种方法在底部获得页码。

答案 5 :(得分:2)

哦,自从我使用postscript以来已经很长时间了,但是快速浏览蓝皮书会告诉你:) www-cdf.fnal.gov/offline/PostScript/BLUEBOOK.PDF

另一方面,Adobe Acrobat和一些javascript也会创造奇迹;)

或者,我确实找到了这个:http://www.ghostscript.com/pipermail/gs-devel/2005-May/006956.html,这似乎符合要求(我没试过)

答案 6 :(得分:2)

我尝试了pspdftool(http://sourceforge.net/projects/pspdftool)。

我最终得到了它的工作,但起初我得到了这个错误:

pspdftool: xreftable read error

源文件是使用来自pdfjam的pdfjoin创建的,其中包含来自我的Epson Workforce的一系列扫描以及生成的标记页。我无法找到修复外部参照表的方法,因此我使用pdf2ps转换为ps并使用pdf2ps转换为pdf。然后我可以使用它在右下角获得不错的页码:

pspdftool 'number(start=1, size=20, x=550 pt, y=10 pt)' input.pdf output.pdf

不幸的是,这意味着任何可搜索文本的页面都不再可搜索,因为文本在ps转换中被栅格化了。幸运的是,就我而言,这没关系。

有没有办法修复或清空pdf文件的外部参照表而不会丢失哪些页面可搜索?

答案 7 :(得分:2)

我喜欢使用pspdftoolman page)的想法,但我所追求的是第x页y 格式以及与其余部分相匹配的字体样式页。

要了解文档中使用的字体名称:

$ strings input.pdf | grep Font

获取页数:

$ pdfinfo input.pdf | grep "Pages:" | tr -s ' ' | cut -d" " -f2

将它与一些pspdftool命令一起粘贴:

$ in=input.pdf; \
out=output.pdf; \
indent=30; \
pageNumberIndent=49; \
pageCountIndent=56; \
font=LiberationSerif-Italic; \
fontSize=9; \
bottomMargin=40; \
pageCount=`pdfinfo $in | grep "Pages:" | tr -s ' ' | cut -d" " -f2`; \
pspdftool "number(x=$pageNumberIndent pt, y=$bottomMargin pt, start=1, size=$fontSize, font=\"$font\")" $in tmp.pdf; \
pspdftool "text(x=$indent pt, y=$bottomMargin pt, size=$fontSize, font=\"$font\", text=\"page \")" tmp.pdf tmp.pdf; \
pspdftool "text(x=$pageCountIndent pt, y=$bottomMargin pt, size=$fontSize, font=\"$font\", text=\"out of $pageCount\")" tmp.pdf $out; \
rm tmp.pdf;

结果如下:

enter image description here

答案 8 :(得分:2)

您可以使用免费且开源的pdftools通过单个命令行将页码添加到PDF文件中。

您可以使用的命令行是:

pdftools --input-file input.pdf --output output.pdf --text $page/$pages 0.9 0.9 --fitpaper

关于--text选项:

  • 第一个参数是要添加的文本。一些占位符可用。 $page代表当前页码,而$pages代表PDF文件中的总页数。因此,这样制定的选项将在10页的PDF文档的第一页中添加“ 1/10”之类的内容,在随后的页面中以此类推。
  • 第二个参数是文本的水平位置占页面大小的百分比
  • 第三个参数选项是文本的垂直位置占页面大小的百分比

--fitpaper选项用于在输出pdf文件中保持输入pdf文件的尺寸。

免责声明:我是pdftools的作者

答案 9 :(得分:1)

我假设您正在寻找基于PS的解决方案。 PS中没有页面级操作符允许您执行此操作。您需要在每个页面的PageSetup部分添加页脚类型的东西。任何脚本语言都应该能够帮助您。

答案 10 :(得分:1)

我采用了captaincomic的解决方案并添加了对包含空格的文件名的支持,并提供了一些有关进度的更多信息

#!/bin/bash
clear
echo
echo This skript adds pagenumbers to a given .pdf file.
echo 
echo This skript needs the packages pdftk and enscript
echo if not installed the script will fail.
echo use the command sudo apt-get install pdftk enscript
echo to install.
echo 
input="$1"
output="${1%.pdf}-header.pdf"
echo input file is $input
echo output file will be $output
echo 
pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
enscript -L1 --header='||Page $% of $=' --output - < <(for i in $(seq "$pagenum"); do echo; done) | ps2pdf - | pdftk "$input" multistamp - output "$output"
echo done.

答案 11 :(得分:1)

我编写了以下shell脚本来解决LaTeX beamer样式幻灯片使用inkscape生成的内容(我pdftk cat幻灯片放在最后的演示文稿中PDF&amp;然后使用下面的脚本添加幻灯片编号:

#!/bin/sh

# create working directory
tmpdir=$(mktemp --directory)

# read un-numbered beamer slides PDF from STDIN & create temporary copy
cat > $tmpdir/input.pdf

# get total number of pages
pagenum=$(pdftk $tmpdir/input.pdf dump_data | awk '/NumberOfPages/{print $NF}')

# generate latex beamer document with the desired number of empty but numbered slides
printf '%s' '
\documentclass{beamer}
\usenavigationsymbolstemplate{}
\setbeamertemplate{footline}[frame number]
\usepackage{forloop}
\begin{document}
 \newcounter{thepage}
  \forloop{thepage}{0}{\value{thepage} < '$pagenum'}{
    \begin{frame}
    \end{frame}
  }
\end{document}
' > $tmpdir/numbers.tex

# compile latex file into PDF (2nd run needed for total number of pages) & redirect output to STDERR
pdflatex -output-directory=$tmpdir numbers.tex >&2 && pdflatex -output-directory=$tmpdir numbers.tex >&2

# add empty numbered PDF slides as background to (transparent background) input slides (page by
# page) & write results to STDOUT
pdftk $tmpdir/input.pdf multibackground $tmpdir/numbers.pdf output -

# remove temporary working directory with all intermediate files
rm -r $tmpdir >&2

该脚本显示STDIN&amp;将STDOUT打印诊断pdflatex输出写入STDERR

因此,只需将上述代码复制粘贴到文本文件中,例如enumerate_slides.sh,将其设为可执行文件(chmod +x enumerate_slides.sh)&amp;这样称呼:

./enumerate_slides.sh < input.pdf > output.pdf [2>/dev/null]

通过调整LaTeX模板以使用正确的documentclass,纸张尺寸和尺寸,可以很容易地将其调整为任何其他类型的文档。风格选择。

<强> 编辑: 我将echo替换为$(which echo),因为在ubuntu符号链接/bin/shdash,它会通过shell内部解释转义序列来覆盖echo命令&安培;没有提供-E选项来覆盖此行为。请注意,您也可以将LaTeX模板中的所有\转义为\\

<强> 编辑: 我将$(which echo)替换为printf '%s',因为在zsh中,which echo返回echo: shell built-in command而不是/bin/echo。 有关我最终决定使用printf的详细信息,请参阅this question

答案 12 :(得分:1)

我一直在寻找使用ghostscript的仅Postscript的解决方案。我需要合并多个PDF并在每个页面上放置一个计数器。我发现的唯一解决方案是an old gs-devel posting,我对其进行了简化:

%!PS
% add page numbers document bottom right (20 units spacing , harcoded below)
% Note: Page dimensions are expressed in units of the default user space (72nds of an inch).
% inspired by https://www.ghostscript.com/pipermail/gs-devel/2005-May/006956.html

globaldict /MyPageCount 1 put % initialize page counter

% executed at the end of each page. Before calling the procedure, the interpreter
% pushes two integers on the operand stack:
% 1. a count of previous showpage executions for this device
% 2. a reason code indicating the circumstances under which this call is being made:
%    0: During showpage or (LanguageLevel 3) copypage
%    1: During copypage (LanguageLevel 2 only)
%    2: At device deactivation
% The procedure must return a boolean value specifying whether to transmit the page image to the
% physical output device.
<< /EndPage {
  exch pop % remove showpage counter (unused)
  0 eq dup { % only run and return true for showpage
    /Helvetica 12 selectfont % select font and size for following operations
    MyPageCount =string cvs % get page counter as string
    dup % need it twice (width determination and actual show)
    stringwidth pop % get width of page counter string ...
    currentpagedevice /PageSize get 0 get % get width from PageSize on stack
    exch sub 20 sub % pagewidth - stringwidth - some extra space
    20 moveto % move to calculated x and y=20 (0/0 is the bottom left corner)
    show % finally show the page counter
    globaldict /MyPageCount MyPageCount 1 add put % increment page counter
  } if
} bind >> setpagedevice

如果将其保存到名为pagecount.ps的文件中,则可以在命令行上使用它,如下所示:

gs \
  -dBATCH -dNOPAUSE \
  -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
  -sOutputFile=/path/to/merged.pdf \
  -f pagecount.ps -f input1.pdf -f input2.pdf

请注意,必须首先给定pagecount.ps(从技术上讲,应该恰好在输入页面计数开始的输入文件之前)。

如果您不想使用额外的.ps文件,也可以使用最小化形式,如下所示:

gs \
  -dBATCH -dNOPAUSE \
  -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
  -sOutputFile=/path/to/merged.pdf \
  -c 'globaldict /MyPageCount 1 put << /EndPage {exch pop 0 eq dup {/Helvetica 12 selectfont MyPageCount =string cvs dup stringwidth pop currentpagedevice /PageSize get 0 get exch sub 20 sub 20 moveto show globaldict /MyPageCount MyPageCount 1 add put } if } bind >> setpagedevice'
  -f input1.pdf -f input2.pdf

根据您的输入,您可能必须在if块的开头/结尾使用gsave / grestore

答案 13 :(得分:0)

也许pstops(psutils的一部分)可以用于此吗?