在 R 中每 2 页将 PDF 文件拆分为多个文件
Split PDF files in multiples files every 2 pages in R
我有一个 300 页的 PDF 文档。我需要将此文件拆分为 150 个文件,每个文件包含 2 页。例如,第一个文档将包含原始文件的第 1 页和第 2 页,第二个文档将包含第 3 页和第 4 页等等。
也许我可以使用“pdftools”包,但我不知道如何。
pdftools
和 qpdf
(第一个依赖)都不支持除“每一页”之外的其他分割 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
,计算起始页码和结束页码的st
和en
向量,并重复调用pdf_subset
。请注意,pdf_length
和 pdf_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
,然后计算起始页码和结束页码 st
和 en
,然后重复调用 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)
}
我有一个 300 页的 PDF 文档。我需要将此文件拆分为 150 个文件,每个文件包含 2 页。例如,第一个文档将包含原始文件的第 1 页和第 2 页,第二个文档将包含第 3 页和第 4 页等等。
也许我可以使用“pdftools”包,但我不知道如何。
pdftools
和 qpdf
(第一个依赖)都不支持除“每一页”之外的其他分割 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
,计算起始页码和结束页码的st
和en
向量,并重复调用pdf_subset
。请注意,pdf_length
和 pdf_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
,然后计算起始页码和结束页码 st
和 en
,然后重复调用 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)
}