获取外部 PDF 的页数

获取外部 PDF 的页数

是否有可能获取 LaTeX 文档中的外部 PDF 文件的总页数?

假设在保存我的 LaTeX 文件的同一目录中存在一个test.pdf包含 8 页的 PDF 文件。这是我的基本方法:

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{xparse}

\DeclareDocumentCommand \pdfnumberofpages { m } {
  % Do some magic
}

\begin{document}

\texttt{test.pdf}: \pdfnumberofpages{test.pdf} pages

\end{document}

生成的文档应该包含

test.pdf:8页

我知道这应该是可能的(pdfpages必须做这样的事情),但我不知道如何实现它。

答案1

\tracingmacros1使用选项之后pages=last-1,好像pdfpages使用了功能来pdf(la)tex获取数字。

\documentclass{minimal}
\begin{document}
    \pdfximage{test-29.pdf}
    \the\pdflastximagepages\ pages
\end{document}

答案2

pdfTeX、LuaTeX

\pdflastximageages,参见回答符号 1。

评论:

  • \pdfximage不能在 DVI 模式下使用。

LuaTeX

不幸的是,LuaTeX 一直在不断更改其接口。 \luatexluaescapestring已重命名为\luaescapestring,并且库epdf已被库 取代pdfe。 以下示例是使用 1.15.0 开发和测试的。

也可以通过 Lua 库检索页面数量pdfe

\documentclass{article}

\newcommand*{\pdfnumberofpages}[1]{%
  \directlua{%
    local doc = pdfe.open("\luaescapestring{#1}")
    local pages
    if (doc) then
      pages = pdfe.getnofpages(doc)
    else
      pages = 0
    end
    tex.write(pages)
  }%
}

\begin{document}
Number of pages: \pdfnumberofpages{test.pdf}
\end{document}

评论:

  • 如果该文档不存在,宏\pdfnumberofpages将返回零。
  • \pdfnumberofpages是完全可扩展的。因此,它可以用于计数器分配,可以写入文件,...
  • 它也可以在 DVI 模式下工作。

较旧的 LuaTeX

也可以通过 Lua 库检索页面数量epdf

\documentclass{article}

\newcommand*{\pdfnumberofpages}[1]{%
  \directlua{%
    local doc = epdf.open("\luatexluaescapestring{#1}")
    local pages
    if (doc) then
      pages = doc:getCatalog():getNumPages()
    else
      pages = 0
    end
    tex.write(pages)
  }%
}

\begin{document}
Number of pages: \pdfnumberofpages{test.pdf}
\end{document}

评论:

  • 如果该文档不存在,宏\pdfnumberofpages将返回零。
  • \pdfnumberofpages是完全可扩展的。因此,它可以用于计数器分配,可以写入文件,...
  • 它也可以在 DVI 模式下工作。

特克斯

XeTeX 提供\XeTeXpdfpagecount

\documentclass{article}

\newcommand*{\numberofpages}[1]{%
  \the\XeTeXpdfpagecount"#1" %
}

\begin{document}
Number of pages: \numberofpages{test.pdf}
\end{document}

评论:

  • 如果该文件不存在,结果为零。
  • 此版本也可完全扩展。

概括

以下示例将不同的版本放在一起:

\documentclass{article}

\usepackage{ifpdf}
% XeTeX check
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname XeTeXpdfpagecount\endcsname\relax
  % pdfTeX check
  \begingroup\expandafter\expandafter\expandafter\endgroup
  \expandafter\ifx\csname pdflastximagepages\endcsname\relax
    \newcommand*{\numberofpages}[1]{%
      0%
      \errmessage{\noexpand\numberofpages is unsupported for this driver}%
    }%    
  \else
    % Definition for pdfTeX
    \ifpdf
      \newcommand*{\numberofpages}[1]{%
        \pdfximage{#1}%
        \the\pdflastximagepages
      }%
    \else
      \newcommand*{\numberofpages}[1]{%
        0%
        \errmessage{\noexpand\numberofpages is unsupported in DVI mode}%
      }%
    \fi
  \fi
  % LuaTeX check
  \typeout{LuaTeX check}
  \begingroup\expandafter\expandafter\expandafter\endgroup
  \expandafter\ifx\csname directlua\endcsname\relax
  \else
    \begingroup\expandafter\expandafter\expandafter\endgroup
    \expandafter\ifx\csname luaescapestring\endcsname\relax
      \typeout{luaescapestring is undefined}%
      \begingroup\expandafter\expandafter\expandafter\endgroup
      \expandafter\ifx\csname luatexluaescapestring\endcsname\relax
      \typeout{luatexluaescapestring is undefined}%
      \else
        \newcommand*{\LuaEscapeString}{}%
        \let\LuaEscapeString\luatexluaescapestring
      \fi
    \else
      \newcommand*{\LuaEscapeString}{}%
      \let\LuaEscapeString\luaescapestring
    \fi
    \begingroup\expandafter\expandafter\expandafter\endgroup
    \expandafter\ifx\csname LuaEscapeString\endcsname\relax
    \else
      % Definition for newer LuaTeX
      \ifnum0\directlua{if pdfe then tex.write(1)end}=1 %
        \renewcommand*{\numberofpages}[1]{%
          \directlua{%
            local doc = pdfe.open("\LuaEscapeString{#1}")
            local pages
            if (doc) then
              pages = pdfe.getnofpages(doc)
            else
              pages = 0
            end
            tex.write(pages)
          }%
        }%
      \else
        % Definition for older LuaTeX
        \ifnum0\directlua{if epdf then tex.write(1)end}=1 %
          \renewcommand*{\numberofpages}[1]{%
            \directlua{%
              local doc = epdf.open("\LuaEscapeString{#1}")
              local pages
              if (doc) then
                pages = doc:getCatalog():getNumPages()
              else
                pages = 0
              end
              tex.write(pages)
            }%
          }%
        \fi
      \fi
    \fi
  \fi
\else
  % Definition for XeTeX
  \newcommand*{\numberofpages}[1]{%
    \the\XeTeXpdfpagecount"#1" % space ends the file name scanning
  }%
\fi

\begin{document}
Number of pages: \numberofpages{test.pdf}% Should be different from \jobname.pdf
\end{document}

评论:

  • 如果将\newcommand\renewcommand替换为\def构造,则定义在纯 TeX 中也能起作用。(\luatexluaescapestring可能可用\luaescapestring或必须通过启用tex.enableprimitives。)
  • 如果不支持检索页数,则会抛出错误消息。

答案3

使用当前的 l3graphics(当前处于 l3experimental 中),您可以用来\graphics_get_pagecount:nN检索页数,然后打印它或在命令中将其用作页码\includegraphics\graphics_get_pagecount:nN适用于所有引擎,也适用于 dvi 模式下的 LaTeX。

\documentclass{article}
\usepackage{l3graphics}
\usepackage{graphicx}
\begin{document}

\ExplSyntaxOn
\graphics_get_pagecount:nN {example-image-a4-numbered.pdf}\l_tmpa_tl
\l_tmpa_tl
\includegraphics[scale=0.5,page=\l_tmpa_tl]{example-image-a4-numbered.pdf}
\ExplSyntaxOff

\end{document}

在此处输入图片描述

答案4

如果有人对将页数写入文件的单行命令感兴趣test.pdf.pages(如果test.pdf是所讨论的 PDF 文件),则以下内容(基于接受的答案) 正在命令提示符在 Windows 10 上使用 MikTeX:

pdflatex "\documentclass{minimal}\nofiles\def\pdffile{test.pdf}\begin{document}\pdfximage{\pdffile}\newwrite\myfile\immediate\openout\myfile=\pdffile.pages\makeatletter\immediate\write\myfile{\the\pdflastximagepages}\makeatother\immediate\closeout\myfile\end{document}"

连同一起test.pdf.pages,会生成2个不需要的文件:minimal.pdfminimal.log,编译后可以删除它们。

相关内容