在 R 中每 2 页将 PDF 文件拆分为多个文件

Split PDF files in multiples files every 2 pages in R

我有一个 300 页的 PDF 文档。我需要将此文件拆分为 150 个文件,每个文件包含 2 页。例如,第一个文档将包含原始文件的第 1 页和第 2 页,第二个文档将包含第 3 页和第 4 页等等。

也许我可以使用“pdftools”包,但我不知道如何。

pdftoolsqpdf(第一个依赖)都不支持除“每一页”之外的其他分割 PDF 文件。您可能需要依赖外部程序,我相信您可以 pdftk 通过为每 2 页输出调用一次来做到这一点。

我在当前工作目录中有一个名为 quux.pdf 的 36 页 PDF。

str(pdftools::pdf_info("quux.pdf"))
# List of 11
#  $ version    : chr "1.5"
#  $ pages      : int 36
#  $ encrypted  : logi FALSE
#  $ linearized : logi FALSE
#  $ keys       :List of 8
#   ..$ Producer       : chr "pdfTeX-1.40.24"
#   ..$ Author         : chr ""
#   ..$ Title          : chr ""
#   ..$ Subject        : chr ""
#   ..$ Creator        : chr "LaTeX via pandoc"
#   ..$ Keywords       : chr ""
#   ..$ Trapped        : chr ""
#   ..$ PTEX.Fullbanner: chr "This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) kpathsea version 6.3.4"
#  $ created    : POSIXct[1:1], format: "2022-05-17 22:54:40"
#  $ modified   : POSIXct[1:1], format: "2022-05-17 22:54:40"
#  $ metadata   : chr ""
#  $ locked     : logi FALSE
#  $ attachments: logi FALSE
#  $ layout     : chr "no_layout"

我还安装了 pdftk 并在页面中可用,

Sys.which("pdftk")
#                                        pdftk 
# "C:\PROGRA~2\PDFtk Server\bin\pdftk.exe" 

有了这个,我可以 运行 一个外部脚本来创建 2 页 PDF:

list.files(pattern = "pdf$")
# [1] "quux.pdf"

pages <- seq(pdftools::pdf_info("quux.pdf")$pages)
pages <- split(pages, (pages - 1) %/% 2)
pages[1:3]
# $`0`
# [1] 1 2
# $`1`
# [1] 3 4
# $`2`
# [1] 5 6

for (pg in pages) {
  system(sprintf("pdftk quux.pdf cat %s-%s output out_%02i-%02i.pdf",
         min(pg), max(pg), min(pg), max(pg)))
}

list.files(pattern = "pdf$")
#  [1] "out_01-02.pdf" "out_03-04.pdf" "out_05-06.pdf" "out_07-08.pdf"
#  [5] "out_09-10.pdf" "out_11-12.pdf" "out_13-14.pdf" "out_15-16.pdf"
#  [9] "out_17-18.pdf" "out_19-20.pdf" "out_21-22.pdf" "out_23-24.pdf"
# [13] "out_25-26.pdf" "out_27-28.pdf" "out_29-30.pdf" "out_31-32.pdf"
# [17] "out_33-34.pdf" "out_35-36.pdf" "quux.pdf"     

str(pdftools::pdf_info("out_01-02.pdf"))
# List of 11
#  $ version    : chr "1.5"
#  $ pages      : int 2
#  $ encrypted  : logi FALSE
#  $ linearized : logi FALSE
#  $ keys       :List of 2
#   ..$ Creator : chr "pdftk 2.02 - www.pdftk.com"
#   ..$ Producer: chr "itext-paulo-155 (itextpdf.sf.net-lowagie.com)"
#  $ created    : POSIXct[1:1], format: "2022-05-18 09:37:56"
#  $ modified   : POSIXct[1:1], format: "2022-05-18 09:37:56"
#  $ metadata   : chr ""
#  $ locked     : logi FALSE
#  $ attachments: logi FALSE
#  $ layout     : chr "no_layout"

1) pdftools 假设输入PDF在当前目录,输出要进入同一目录,更改下面的输入,然后得到页数num,计算起始页码和结束页码的sten向量,并重复调用pdf_subset。请注意,pdf_lengthpdf_subset 函数来自 qpdf R 包,但 pdftools R 包也可以通过导入它们并将它们导出回来。

library(pdftools)

# inputs
infile <- "a.pdf"  # input pdf
prefix <- "out_"  # output pdf's will begin with this prefix

num <- pdf_length(infile)
st <- seq(1, num, 2)
en <- pmin(st + 1, num)

for (i in seq_along(st)) {
  outfile <- sprintf("%s%0*d.pdf", prefix, nchar(num), i)
  pdf_subset(infile, pages = st[i]:en[i], output = outfile)
}

2) pdfbox Apache pdfbox 实用程序可以拆分为每个 2 页的文件。从 pdfbox 下载 .jar 命令行实用程序文件并确保安装了 java。然后 运行 这假设您的输入文件是 a.pdf 并且位于当前目录中(或者 运行 直接从命令行引用的部分,没有引号和 R)。如果要使用更高版本,可能需要更改下面的 jar 文件名。下面的名字是目前最新的(不包括alpha版本)。

system("java -jar pdfbox-app-2.0.26.jar PDFSplit -split 2 a.pdf")

3) animation/pdftk 另一种选择是安装 pdftk 程序,更改下面脚本顶部的输入和 运行.这将使用 pdftk 获取输入中的页数 num,然后计算起始页码和结束页码 sten,然后重复调用 pdftk,每个 st/en 将这些页面提取到另一个文件中。

library(animation)

# inputs
PDFTK <- "~/../bin/pdftk.exe"  # path to pdftk
infile <- "a.pdf"  # input pdf
prefix <- "out_"  # output pdf's will begin with this prefix

ani.options(pdftk = Sys.glob(PDFTK))

tmp <- tempfile()
dump_data <- pdftk(infile, "dump_data", tmp)
g <- grep("NumberOfPages", readLines(tmp), value = TRUE)
num <- as.numeric(sub(".* ", "", g))

st <- seq(1, num, 2)
en <- pmin(st + 1, num)

for (i in seq_along(st)) {
  outfile <- sprintf("%s%0*d.pdf", prefix, nchar(num), i)
  pdftk(infile, sprintf("cat %d-%d", st[i], en[i]), outfile)
}