35

我尝试使用 Ghostscript 拆分多页 PDF,我在更多网站甚至ghostscript.com上找到了相同的解决方案,即:

gs -sDEVICE=pdfwrite -dSAFER -o outname.%d.pdf input.pdf

但这似乎对我不起作用,因为它会生成一个文件,其中包含所有页面,并且名称为outname.1.pdf

当我添加开始页面和结束页面时,它工作正常,但我希望它在不知道这些参数的情况下工作。

在 gs-devel 存档中,我找到了一个解决方案: http: //ghostscript.com/pipermail/gs-devel/2009-April/008310.html - 但我觉得没有pdf_info.

例如,当我使用不同的设备但参数相同时,它可以正常工作,生成与我的input.pdf包含pswrite的一样多的 ps 文件 。

使用时这样正常pdfwrite吗?难道我做错了什么?

4

7 回答 7

28

我发现 Weimer 先生编写的这个脚本非常有用:

#!/bin/sh
#
# pdfsplit [input.pdf] [first_page] [last_page] [output.pdf] 
#
# Example: pdfsplit big_file.pdf 10 20 pages_ten_to_twenty.pdf
#
# written by: Westley Weimer, Wed Mar 19 17:58:09 EDT 2008
#
# The trick: ghostscript (gs) will do PDF splitting for you, it's just not
# obvious and the required defines are not listed in the manual page. 

if [ $# -lt 4 ] 
then
        echo "Usage: pdfsplit input.pdf first_page last_page output.pdf"
        exit 1
fi
gs -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$4" -dFirstPage=$2 -dLastPage=$3 -sDEVICE=pdfwrite "$1"

来源:http ://www.cs.virginia.edu/~weimer/pdfsplit/pdfsplit

将其另存为pdfsplit.sh,看看奇迹发生了。

PDFSAM也可以完成这项工作。在 Windows 和 Mac 上可用。

于 2012-05-09T04:34:59.997 回答
14

您看到的是“正常”行为:当前版本的 Ghostscriptpdfwrite输出设备不支持此功能。这也在Use.htm中记录(诚然,不知何故含糊其辞) :

“但请注意,并非所有设备都支持每个文件一页功能......”

我似乎记得在 IRC 上提到的 Ghostscript 开发人员之一,他们可能会在未来的某个版本中将此功能添加到 pdfwrite,但似乎需要一些主要的代码重写,这就是为什么他们还没有这样做......


更新:正如 Gordon 的评论已经暗示的那样,从9.06 版(2012 年 7 月 31 日发布)开始,Ghostscript 现在支持问题中引用的命令行也用于pdfwrite. (Gordon 一定已经在 9.05 中发现了对此的非官方支持,或者他从尚未标记为 9.06 的预发布源编译了自己的可执行文件)。

于 2012-04-19T14:53:42.027 回答
5
 #!/bin/bash
#where $1 is the input filename

ournum=`gs -q -dNODISPLAY -c "("$1") (r) file runpdfbegin pdfpagecount = quit" 2>/dev/null`
echo "Processing $ournum pages"
counter=1
while [ $counter -le $ournum ] ; do
    newname=`echo $1 | sed -e s/\.pdf//g`
    reallynewname=$newname-$counter.pdf
    counterplus=$((counter+1))
    # make the individual pdf page
    yes | gs -dBATCH -sOutputFile="$reallynewname" -dFirstPage=$counter -dLastPage=$counter -sDEVICE=pdfwrite "$1" >& /dev/null
    counter=$counterplus
done
于 2013-11-10T02:40:43.297 回答
5

假设您安装了 Ghostscript,以下是 Windows 命令提示符的脚本(也可用于拖放):

@echo off
chcp 65001
setlocal enabledelayedexpansion

rem Customize or remove this line if you already have Ghostscript folders in your system PATH
set path=C:\Program Files\gs\gs9.22\lib;C:\Program Files\gs\gs9.22\bin;%path%

:start

echo Splitting "%~n1%~x1" into standalone single pages...
cd %~d1%~p1
rem getting number of pages of PDF with GhostScript
for /f "usebackq delims=" %%a in (`gswin64c -q -dNODISPLAY -c "(%~n1%~x1) (r) file runpdfbegin pdfpagecount = quit"`) do set "numpages=%%a"

for /L %%n in (1,1,%numpages%) do (
echo Extracting page %%n of %numpages%...
set "x=00%%n"
set "x=!x:~-3!"
gswin64c.exe -dNumRenderingThreads=2 -dBATCH -dNOPAUSE -dQUIET -dFirstPage=%%n -dLastPage=%%n -sDEVICE=pdfwrite -sOutputFile="%~d1%~p1%~n1-!x!.pdf" "%1"
)

shift
if NOT x%1==x goto start

pause

将此脚本命名为类似的名称split PDF.bat并将其放在您的桌面上。将一个(甚至更多)多页 PDF 拖放到其上,它将为您的 PDF 的每一页创建一个独立的 PDF 文件-001-002并在名称后附加 suffix 等以区分页面。

set path=...如果您的系统 PATH 环境变量中已有 Ghostscript 文件夹,您可能需要自定义(使用相关的 Ghostscript 版本)或删除该行。

它适用于带有 Ghostscript 9.22 的 Windows 10 下的我。请参阅评论以使其与 Ghostscript 9.50+ 一起使用。

享受。

于 2018-07-11T11:56:06.397 回答
2

这是一个简单的python脚本:

#!/usr/bin/python3

import os

number_of_pages = 68
input_pdf = "abstracts_rev09.pdf"

for i in range(1, number_of_pages +1):
    os.system("gs -q -dBATCH -dNOPAUSE -sOutputFile=page{page:04d}.pdf"
              " -dFirstPage={page} -dLastPage={page}"
              " -sDEVICE=pdfwrite {input_pdf}"
              .format(page=i, input_pdf=input_pdf))
于 2015-08-27T21:33:53.807 回答
0

更新了仅依赖的答案pdftk.exe,而不调用 Ghostscript

用户@mmj 提供的答案过去对我来说很好用,但不知何故在 GS 版本 9.20 和 9.50 之间的某个地方停止了工作。我也知道@Adobe 提供的解决方案。但是,我喜欢通过选择一个或多个文件并右键单击 → 发送到,从 Windows (10) 资源管理器中完成重复性任务。这是一个 Python 脚本(与 3.8 兼容),它使用pdftk.exe(用 2.02 测试)来计算页面总数并将所有页面提取到单个文件中。它应该接受多个 PDF 作为输入。确保你有 Python 并且pdftk.exe在 PATH 中。

将其命名extract-pdf-pages-py.cmdshell:sendto

python %APPDATA%\Microsoft\Windows\SendTo\extract-pdf-pages-py.py %*

将以下内容放在extract-pdf-pages-py.py同一文件夹中:

#!/usr/bin/python3
# put as extract-pdf-pages-py.py to shell:sendto

import os
import subprocess
import re
import sys
import mimetypes


def is_tool(name):
    from shutil import which
    return which(name) is not None


if not is_tool('pdftk'):
    input('pdftk.exe not within PATH. Aborting...')
    raise SystemExit("pdftk.exe not within PATH.")

sys.argv.pop(0)

for j in range(len(sys.argv)):
    input_pdf = sys.argv[j]

    if 'application/pdf' not in mimetypes.guess_type(input_pdf):
        input(f"File {input_pdf} is not a PDF. Skipping...")
        continue

    savefile = input_pdf.rstrip('.pdf')

    numpages = subprocess.Popen(f"pdftk \"{input_pdf}\" dump_data", shell=True, stdout=subprocess.PIPE)
    output1 = str(numpages.communicate()[0])
    output2 = re.search("NumberOfPages: ([0-9]*)", output1)
    number_of_pages = int(output2.group(1))

    for i in range(1, number_of_pages + 1):
        os.system(f"pdftk \"{input_pdf}\" cat {i} output \"{savefile}\"{i:04d}.pdf")

我使用了这个答案中的代码(@Adobe 编写的脚本)和那个is_tool)。

于 2020-09-23T18:54:04.813 回答
0

gs 只接受升序页面。对于从源代码中洗牌(即第 7、第 8、第 5)页,我为 ~/.bashrc 创建了函数:

function expdf
{
local str=""
local arr=($(echo $1 | tr "," "\n"))
#          splitting
for i in "${arr[@]}";do
  gs -dBATCH -sDEVICE=pdfwrite -sPageList=$i -dNOPAUSE -sOutputFile=$i.tmp $2
#          reordering for combining
  str="$str $i.tmp"
done
#          combining to combine.pdf
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=combine.pdf -dBATCH $str
#          removing temporary files
for i in "${arr[@]}";do rm $i.tmp;done
}

用法示例:expdf 7-8,5 source.pdf

于 2021-12-21T16:45:21.233 回答