ฉันจะรวมไฟล์ pdf เพื่อให้แต่ละไฟล์เริ่มต้นด้วยหมายเลขหน้าคี่ได้อย่างไร


11

ฉันต้องการรวมไฟล์ PDF ที่มี dozed สองสามตัวและฉันต้องการให้อินพุต pdf ทั้งหมดเริ่มต้นด้วยหน้าคี่ในรูปแบบไฟล์ PDF เอาท์พุท

ตัวอย่าง: A.pdfมี 3 หน้าB.pdfมี 4 หน้า ฉันไม่ต้องการให้ผลลัพธ์ของฉันมี 7 หน้า สิ่งที่ฉันต้องการเป็นไฟล์ PDF 8 หน้าในหน้าเว็บที่ 1-3 จากA.pdf, หน้า 4 เป็นที่ว่างเปล่าและหน้า 5-8 B.pdfจาก ฉันจะทำสิ่งนี้ได้อย่างไร

ฉันรู้เกี่ยวกับ pdftk แต่ฉันไม่พบตัวเลือกดังกล่าวในหน้า man

คำตอบ:


6

ห้องสมุด PyPdfทำให้การจัดเรียงของสิ่งนี้ง่ายถ้าคุณยินดีที่จะเขียนบิตของงูหลาม บันทึกรหัสด้านล่างในสคริปต์ที่เรียกว่าpdf-cat-even(หรือสิ่งที่คุณต้องการ) ทำให้เป็น executable ( chmod +x pdf-cat-even) และเรียกใช้เป็นตัวกรอง ( ./pdf-cat-even a.pdf b.pdf >concatenated.pdf) คุณต้องใช้ pyPdf 131.13 สำหรับaddBlankPageวิธีการนี้

#!/usr/bin/env python
import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
output = PdfFileWriter()
output_page_number = 0
alignment = 2           # to align on even pages
for filename in sys.argv[1:]:
    # This code is executed for every file in turn
    input = PdfFileReader(open(filename))
    for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
        # This code is executed for every input page in turn
        output.addPage(p)
        output_page_number += 1
    while output_page_number % alignment != 0:
        output.addBlankPage()
        output_page_number += 1
output.write(sys.stdout)

ขอบคุณสิ่งนี้ใช้ได้สำหรับฉัน! ในฐานะที่ฉันชอบที่จะอ่านชื่อของไฟล์ PDF จากไฟล์ที่ผมได้แก้ไขโค้ดของคุณเล็กน้อยและโพสต์เป็นคำตอบที่แยกต่างหาก
ม.ค. Warchoł

@JanekWarchol หากชื่อไฟล์ของคุณไม่มีอักขระพิเศษของเชลล์เช่นช่องว่าง:./pdf-cat-even $(cat list-of-file-names.txt) >concatenated.pdf
Gilles 'SO- หยุดเป็นคนชั่ว'

น่าเสียดายที่พวกเขามีช่องว่าง แต่ขอบคุณ - ฉันไม่ได้ตระหนักว่ามันสามารถทำได้
ม.ค. Warchoł

@JanekWarchol จากนั้นคุณสามารถใช้<list-of-file-names.txt tr '\n' '\0' | xargs -0 ./pdf-cat-even >concatenated.pdf
Gilles 'SO- หยุดความชั่วร้าย'

3

ขั้นตอนแรกคือการสร้างไฟล์ PDF ที่มีหน้าว่าง คุณสามารถทำสิ่งนี้ได้อย่างง่ายดายด้วยโปรแกรมมากมาย (LibreOffice / OpenOffice, inkscape, (La) TeX, scribus เป็นต้น)

จากนั้นให้รวมหน้าว่างนี้เมื่อจำเป็น:

pdftk A.pdf empty_page.pdf B.pdf output result.pdf 

หากคุณต้องการทำสิ่งนี้โดยอัตโนมัติด้วยสคริปต์คุณสามารถใช้เช่นpdftk file.pdf dump_data | grep NumberOfPages | egrep -o '[0-9]*'เพื่อแยกจำนวนหน้า


รู้สึกเหมือนแฮ็คอยู่สักหน่อย แม้ว่ามันจะได้ผล แต่ฉันก็ใช้งานได้
Sam Whited

วิธีนี้ใช้ได้ผลกับฉันเกือบทั้งหมด: ฉันเขียนสคริปต์ที่สร้างรายการไฟล์ pdf ด้วย epmtyPage.pdf เพิ่มเมื่อจำเป็น แต่ฉันไม่สามารถรับ pdftk เพื่อแยกรายการนี้อย่างถูกต้องหากชื่อไฟล์มีช่องว่าง ฉันได้ลองเปลี่ยนค่า IFS โดยใช้เครื่องหมายคำพูด แต่ก็ไม่มีประโยชน์บางทีอาจเป็นความผิดของ pdftk อย่างไรก็ตามคำตอบที่ใช้ pypdf นั้นเหมาะกับฉัน
ม.ค. Warchoł

@JanekWarchol pdftk รุ่นไหนที่คุณใช้? อย่างน้อย pdftk 1.44 และใหม่กว่านั้นดูเหมือนจะรองรับช่องว่างในชื่อไฟล์
jofel

@jofel pdftk --versionส่งคืน pdftk 1.44 ฉันจำได้ว่าเพื่อนที่ใช้ทักษะทุบตีมากขึ้นใช้เวลาอย่างน้อย 15 นาทีเพื่อลองทำสิ่งต่าง ๆ เพื่อให้ได้งานนี้และยอมแพ้
ม.ค. Warchoł

1

คำตอบของ Gilles นั้นเหมาะกับฉัน แต่เมื่อฉันต้องรวมหลายไฟล์มันจะสะดวกกว่าถ้าฉันสามารถอ่านชื่อพวกมันจากไฟล์ข้อความ ฉันได้แก้ไขโค้ดของ Gilles เล็กน้อยเพื่อทำอย่างนั้นอาจจะช่วยคนอื่นได้:

#!/usr/bin/env python

# requires PyPdf library, version 1.13 or above -
# its homepage is http://pybrary.net/pyPdf/
# running: ./this-script-name file-with-pdf-list > output.pdf

import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
output = PdfFileWriter()
output_page_number = 0

# every new file should start on (n*alignment + 1)th page
# (with value 2 this means starting always on an odd page)
alignment = 2

listoffiles = open(sys.argv[1]).read().splitlines()
for filename in listoffiles:
    # This code is executed for every file in turn
    input = PdfFileReader(open(filename))
    for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
        # This code is executed for every input page in turn
        output.addPage(p)
        output_page_number += 1
    while output_page_number % alignment != 0:
        output.addBlankPage()
        output_page_number += 1
output.write(sys.stdout)

1

คุณสามารถใช้ LaTeX เพื่อทำสิ่งนี้ได้ (แม้ว่าฉันรู้ว่าอาจไม่ใช่สิ่งที่คุณต้องการ) สิ่งต่อไปนี้ควรใช้งานได้:

\documentclass{book}

\usepackage{pdfpages}

\begin{document}

\includepdf[pages=-]{A}
\cleardoublepage % Make sure we clear to an odd page
\includepdf[pages=-]{B} % This inserts all pages. Or you can specify specific pages, a range, or `{}` for a blank page

\end{document}

โปรดทราบว่า\cleardoublepageจะแทรกเฉพาะหน้าเปล่าที่มีคลาสที่สร้างขึ้นสำหรับการพิมพ์สองด้าน (เช่นหนังสือ)

ตัวเลือกเพิ่มเติมและข้อมูลเกี่ยวกับpdfpagesสามารถพบได้บนCTAN


2
\includepdf[pages=-]{...}ที่จะรวมทุกหน้าโดยอัตโนมัติคุณสามารถใช้
jofel

@jofel ขอบคุณแก้ไขคำถาม ฉันคิดว่ามันเป็นค่าเริ่มต้นสำหรับทุกหน้าเช่นกันฉันเพิ่งใส่เข้าไปในนั้นเพื่อแสดงว่ามันเป็นไปได้ที่จะเลือกบางหน้า
Sam Whited

@jofel นอกจากนี้\cleardoublepageแทรกเฉพาะหน้าเปล่าหากคุณใช้คลาสที่สร้างขึ้นสำหรับการพิมพ์สองด้าน ฉันใช้บทความที่ไม่ได้ผล ฉันแก้ไขแล้วและอัปเดตคำถามเพื่อแสดงว่า
Sam Whited

\includepdfรวมเฉพาะหน้าแรกตามค่าเริ่มต้น (ไม่ใช่ทุกหน้า) \documentclass[twoside]{article}ยังใช้งานได้
jofel

จากสิ่งที่ฉันเห็นฉันต้องเขียนไฟล์ทั้งหมดที่ต้องรวมอย่างชัดเจนดังนั้นมันจึงไม่ดีพอสำหรับฉัน แต่ขอบคุณล่ะค่ะ
ม.ค. Warchoł

0

นี่คือรหัสที่มี PyPDF2 และ python3

#!/usr/bin/env python


# requires PyPdf2 library, version 1.26 or above -
# its homepage is https://pythonhosted.org/PyPDF2/index.html
# running: ./this-script-name output.pdf file-with-pdf-list

import copy, sys
from PyPDF2 import PdfFileWriter, PdfFileReader
output = PdfFileWriter()
output_page_number = 0

# every new file should start on (n*alignment + 1)th page
# (with value 2 this means starting always on an odd page)
alignment = 2

for filename in sys.argv[2:]:
    # This code is executed for every file in turn
    input = PdfFileReader(open(filename, "rb"))
    output.appendPagesFromReader(input)
    output_page_number += input.getNumPages()

    while output_page_number % alignment != 0:
        output.addBlankPage()
        output_page_number += 1

output.write(open(sys.argv[1], "wb"))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.