วิธีการรวมไฟล์ PDF 2 ไฟล์พร้อมลำดับการแทรกระหว่างหน้า


13

ฉันมีเอกสารหลายหน้าพิมพ์สองด้านเพื่อสแกนด้วยเครื่องสแกนเชิงเส้นจำนวนมาก ดังนั้นด้วยเหตุนี้ฉันจึงได้รับไฟล์ PDF 2 ไฟล์: ไฟล์หนึ่งมีหน้าคี่ทั้งหมดและไฟล์ที่สองมีหน้าคู่ทั้งหมด ฉันต้องรวมพวกเขาด้วยวิธีธรรมชาติ:

1. <- 1.1. (odd.pdf page 1 to result.pdf page 1)
2. <- 2.1. (even.pdf page 1 to result.pdf page 2)
3. <- 1.2. (odd.pdf page 2 to result.pdf page 3)
4. <- 2.2. (even.pdf page 2 to result.pdf page 4)

เป็นต้น


เพียงค้นหา parser PDF และทำสิ่งที่ผสานให้เหมือนกัน
เดซี่

1
หาก Stephane ไม่สามารถแก้ปัญหาของคุณคุณสามารถลองโมดูล perl CAM::PDFฉันจะให้สคริปต์ของคุณในภายหลัง pdf ทั้งสองมีจำนวนหน้าเท่ากันหรือไม่
เดซี่

คำตอบ:


7

ดูpdfseparateและคำสั่งจากpdfunite poppler-utilsขั้นตอนแรกในการแยกหน้าจากแต่ละเอกสารเป็นไฟล์เดี่ยว ๆ และรายการที่สองเพื่อรวมหน้าเอกสารตามลำดับที่คุณต้องการในเอกสารใหม่

โปรดทราบว่าเนื่องจากสแกนเนอร์ให้ภาพแรสเตอร์ให้กับคุณ (ซึ่งบางอย่างเช่นคุณสามารถเชื่อมต่อกันเป็นไฟล์ PDF) คุณอาจกำหนดค่าให้เป็นภาพที่ส่งออก (png, tiff ... ) แทนและทำการเชื่อมต่อเป็น PDF ด้วยตัวคุณเอง ImageMagick


ดูเหมือนว่าสิ่งที่ฉันต้องการลองทำ ...
อีวาน

1
จริง ยอดเยี่ยม ง่ายต่อการใช้เพื่อทำสิ่งที่ฉันต้องการ โดยวิธีการที่ฉันมีแน่นอน googled ก่อนถามและวิธีการแก้ปัญหาที่ฉันได้พบว่าเหมือนกันมีความซับซ้อนที่สะดุดตามากขึ้น
อีวาน

ฉันลองสิ่งนี้บน Ubuntu 18.04 (ด้วยสคริปต์ที่เป็นประโยชน์ด้านล่างจาก @TCF) และเปลี่ยนไฟล์สอง ~ 5.5Mb เป็นไฟล์ 197Mb หนึ่งไฟล์ดังนั้นในขณะที่ทำงานได้มันก็ใช้ไม่ได้ (ฉันต้องการส่งอีเมลผลลัพธ์!) .
รูเบนโทมัส

12

pdftk มีคำสั่ง shuffle ที่เรียงหน้า:

pdftk A=odd.pdf B=even.pdf shuffle A B output collated.pdf

1
สิ่งนี้ทำงานได้ดีสำหรับฉัน แต่ด้วยการปรับแต่งเพื่อย้อนกลับหน้าคู่ pdf
รูเบนโทมัส

เยี่ยมมากขอบคุณ - มันทำงานได้อย่างสมบูรณ์แบบ
infomaniac

2

เพียงแค่bashยิงอย่างรวดเร็วโดยใช้pdfjam:

สร้างอาร์เรย์ของอินพุตอาร์กิวเมนต์:

for k in $(seq 1 ${N_PAGES}); do
    PAGES+=(odd.pdf);
    PAGES+=($k);
    PAGES+=(even.pdf);
    PAGES+=($k);
done

สิ่งนี้จะอนุญาตให้คุณใช้เป็นรายการอินพุตสำหรับpdfjoin:

 pdfjoin ${PAGES[@]} --outfile shuffled.pdf

2
ควรสังเกตว่าpdfjoinเป็นสคริปต์ wrapper pdfjamซึ่งเป็นสคริปต์ wrapper รอบpdfpagesแพคเกจ LaTeX (และ pdflatex) ดังนั้นจึงหมายความว่ามันจะทำให้ LaTeX เป็นการพึ่งพา
Stéphane Chazelas

1

คุณสามารถใช้โมดูล Mix ในPDFsam Basic (ฟรีและโอเพ่นซอร์ส) หรือทำออนไลน์โดยใช้คุณสมบัติAlternate & Mixใน Sejda


1
มอบโซลูชันที่ดีที่สุด: โอเพ่นซอร์สไม่จำเป็นต้องติดตั้ง 2 คลิกและเสร็จแล้ว)
ธาน

0

ฉันต้องการทำสิ่งเดียวกันโดยพื้นฐานและคำตอบของStéphane Chazelas ก็มีประโยชน์มาก ฉันทำสิ่งนี้บ่อยครั้งพอที่ฉันเขียนสคริปต์ Python แบบง่าย ๆ เพื่อทำสิ่งต่าง ๆ โดยอัตโนมัติโดยใช้คำสั่งที่เขาแนะนำ โดยค่าเริ่มต้นมันกลับคำสั่งของหน้าคู่ แต่สิ่งนี้สามารถระงับได้ด้วยการตั้งค่าสถานะบรรทัดคำสั่ง

คำถามนั้นค่อนข้างเก่าดังนั้นฉันคาดหวังว่าความต้องการของผู้ถามดั้งเดิมจะได้พบกันแล้ว อย่างไรก็ตามเป็นไปได้ว่าสคริปต์จะมีประโยชน์กับคนที่มาถึงที่นี่ในอนาคตดังนั้นฉันจึงวางไว้ด้านล่าง

#!/usr/bin/python
"""A simple script to merge two PDFs."""

import argparse
from os import listdir
from os.path import join as opjoin
import shutil
from subprocess import check_call, CalledProcessError
import tempfile

SEPARATE = 'pdfseparate %s %s'
MERGE = 'pdfunite %s %s'

def my_exec(command):
    """Execute a command from a shell, ignoring errors."""
    try:
        check_call(command, shell=True)
    except CalledProcessError:
        pass

def run(odd, even, out, reverse_odd=False, reverse_even=True):
    """Interleave odd and even pages from two PDF files."""
    folder = tempfile.mkdtemp()
    my_exec(SEPARATE % (odd, opjoin(folder, 'odd%d.pdf')))
    my_exec(SEPARATE % (even, opjoin(folder, 'even%d.pdf')))
    odd_files = []
    even_files = []
    for curr_file in listdir(folder):
        filepath = opjoin(folder, curr_file)
        if curr_file.startswith('odd'):
            odd_files.append((filepath, int(curr_file[3:-4])))
        elif curr_file.startswith('even'):
            even_files.append((filepath, int(curr_file[4:-4])))
    func = lambda x: x[1]
    odd_files.sort(key=func, reverse=reverse_odd)
    even_files.sort(key=func, reverse=reverse_even)
    parts = []
    for line in zip(odd_files, even_files):
        parts.append(line[0][0])
        parts.append(line[1][0])
    my_exec(MERGE % (' '.join(parts), out))
    shutil.rmtree(folder)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Merge two PDF files.')
    parser.add_argument('odd_pages', help='PDF containing the odd pages.')
    parser.add_argument('even_pages', help='PDF containing the even pages.')
    parser.add_argument('output_file', help='The target output file.')
    parser.add_argument('--reverse-odd', action='store_true', 
                        help='Insert the odd pages in reverse order.')
    parser.add_argument('--no-reverse-even', action='store_true',
                        help='Suppress reversal of the even pages.')
    args = parser.parse_args()
    run(args.odd_pages, args.even_pages, args.output_file,
        args.reverse_odd, not args.no_reverse_even)

0

ฉันเจอสคริปต์ทุบตีนี้การทำเช่นนี้จะถือว่าคุณสแกนหน้าคู่ในลำดับย้อนกลับ แต่คุณสามารถเปลี่ยนการลบ-rในบรรทัดที่บอกว่าevenpages=($(ls "$evenbase-$key-"* | sort -r))(นี่คือบรรทัดที่ 46)

#!/bin/bash
# Copyright Fabien André <fabien.andre@xion345.info>
# Distributed under the MIT license
# This script interleaves pages from two distinct PDF files and produces an
# output PDF file. The odd pages are taken from a first PDF file and the even
# pages are taken from a second PDF file passed respectively as first and second
# argument.
# The first two pages of the output file are the first page of the
# odd pages PDF file and the *last* page of the even pages PDF file. The two
# following pages are the second page of the odd pages PDF file and the
# second to last page of the even pages PDF file and so on.
#
# This is useful if you have two-sided documents scanned each side on a
# different file as it can happen when using a one-sided Automatic Document
# Feeder (ADF)
#
# It does a similar job to :
# https://github.com/weltonrodrigo/pdfapi2/blob/46434ab3f108902db2bc49bcf06f66544688f553/contrib/pdf-interleave.pl
# but only requires bash (> 4.0) and poppler utils.
# Print usage/help message
function usage {
echo "Usage: $0 <PDF-even-pages-file> <PDF-odd-pages-file>"
exit 1
}
# Add leading zeros to pad numbers in filenames matching the pattern
# $prefix$number.pdf. This allows filenames to be easily sorted using
# sort.
# $1 : The prefix of the filenames to consider
function add_leading_zero {
prefix=$1
baseprefix=$(basename $prefix | sed -e 's/[]\/()$*.^|[]/\\&/g')
dirprefix=$(dirname $prefix)
for filename in "$prefix"*".pdf"
do
base=$(basename "$filename")
index=$(echo "$base" | sed -rn "s/$baseprefix([0-9]+).pdf$/\1/p")
newbase=$(printf "$baseprefix%04d.pdf" $index)
mv $filename "$dirprefix/$newbase"
done
}
# Interleave pages from two distinct PDF files and produce an output PDF file.
# Note that the pages from the even pages file (second file) will be used in
# the reverse order (last page first).
# $1 : Odd pages filename
# $2 : Odd pages filename with extension removed
# $3 : Even pages filename
# $4 : Even pages filename with extension removed
# $5 : Unique key used for temporary files
# $6 : Output file
function pdfinterleave {
oddfile=$1
oddbase=$2
evenfile=$3
evenbase=$4
key=$5
outfile=$6
# Odd pages
pdfseparate $oddfile "$oddbase-$key-%d.pdf"
add_leading_zero "$oddbase-$key-"
oddpages=($(ls "$oddbase-$key-"* | sort))
# Even pages
pdfseparate $evenfile "$evenbase-$key-%d.pdf"
add_leading_zero "$evenbase-$key-"
evenpages=($(ls "$evenbase-$key-"* | sort -r))
# Interleave pages
pages=()
for((i=0;i<${#oddpages[@]};i++))
do
pages+=(${oddpages[i]})
pages+=(${evenpages[i]})
done
pdfunite ${pages[@]} "$outfile"
rm ${oddpages[@]}
rm ${evenpages[@]}
}
if [ $# -lt 2 ]
then
usage
fi
if [ $1 == $2 ]
then
echo "Odd pages file and even pages file must be different." >&2
exit 1
fi
if ! hash pdfunite 2>/dev/null || ! hash pdfseparate 2>/dev/null
then
echo "This script requires pdfunite and pdfseparate from poppler utils" \
"to be in the PATH. On Debian based systems, they are found in the" \
"poppler-utils package"
exit 1
fi
oddbase=${1%.*}
evenbase=${2%.*}
odddir=$(dirname $oddbase)
oddfile=$(basename $oddbase)
evenfile=$(basename $evenbase)
outfile="$odddir/$oddfile-$evenfile-interleaved.pdf"
key=$(tr -dc "[:alpha:]" < /dev/urandom | head -c 8)
if [ -e $outfile ]
then
echo "Output file $outfile already exists" >&2
exit 1
fi
pdfinterleave $1 $oddbase $2 $evenbase $key $outfile
# SO - Bash command that prints a message on stderr
# http://stackoverflow.com/questions/2643165/bash-command-that-prints-a-message-on-stderr
# SO - Check if a program exists from a bash script
# http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script
# SO - How to debug a bash script?
# http://stackoverflow.com/questions/951336/how-to-debug-a-bash-script
# SO - Escape a string for sed search pattern
# http://stackoverflow.com/questions/407523/escape-a-string-for-sed-search-pattern

แหล่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.