2012-04-12 11 views
1

私は一緒にマージするPDF文書がたくさんあるので、私はそれを行うためにこのコードを書いた。私は2つのpdf文書をマージするだけの場合に動作しますが、2つ以上与えると余分な文書が文字化けして出てきます。何が間違っているのかを教えてもらえますか?PDF :: API2を使用して複数のpdfsをPerlで1つにマージするには?

#!/usr/bin/perl 

use PDF::API2; 
use List::Util qw(reduce); 


# Given two pdfs and a page number, appends the given page of the second pdf to the first pdf 
sub append_page_to_pdf { 
    my ($pdf1, $pdf2, $pg) = @_; 
    $pdf1->importpage($pdf2, $pg); 
} 

# Given two pdfs, appends the second to the first. Closes pdf2 
sub merge_2_pdfs { 
    my ($pdf1, $pdf2) = @_; 
    map &append_page_to_pdf($pdf1, $pdf2, $_), 1..$pdf2->pages; 
    $pdf2->end; 
    return $pdf1; 
} 

# does what it says 
sub open_pdf { 
    my $file = $_[0]; 
    my $pdf = PDF::API2->open($file); 
    print "Opened pdf ($file)\n"; 
    return $pdf; 
} 

# reduces merge_2_pdfs over an array of pdfs 
sub merge_pdfs { 
    my @files = @_; 
    my $starting_filename = shift @files; 
    my $start_pdf = &open_pdf($starting_filename); 
    my $final_pdf = reduce { &merge_2_pdfs($a, &open_pdf($b)) } $start_pdf, @files; 
    return $final_pdf; 
} 

# Get the arguments ie save_name, file1, file2, file3, ... 
my @files = @ARGV; 
my $save_name = shift @files; 
my $save = &merge_pdfs(@files); 
$save->saveas($save_name); 
+1

http://p3rl.org/appendpdf.pl – daxim

+0

はい、私はそれを見ました他のSOスレッドに関する同様の質問に対する答えとして与えられます。問題は、appendpdf.plは2つのpdfドキュメントのみをマージすることです。 appendpdf.plを使ってシェルスクリプトを実行しますが、それは間違っています:ファイルごとに発生する不必要なファイルio(余分な読み書き)があります。 – user787747

+1

私はappendpdf.plの著者です。これは、CAM :: PDFを中心とした単純なラッパースクリプトです。大量のPDFを追加するのは簡単です。 appendpdf.plのソースコードを見れば分かります。 –

答えて

2

コードの実際の問題は、ファイルをマージする前にshiftのファイルがオフになっているためです。

my $save_name = shift @files; 
# which should be 
my $save_name = $files[0]; 

それ以外の場合、コードは実際に動作し、文字化けしたものは見つかりませんでした。

いくつかのヒント:

  1. use strictuse warnings

  2. が一般的で、今お使いのサブルーチンコールで&を省略することです。そのルールに対する例外の場合はSee hereです。

  3. この場合、サブルーチンはあなたのコードを冗長にします。ここにはもっと簡潔なものがあります。

    use strict; 
    use warnings; 
    use List::Util 'reduce'; 
    use PDF::API2; 
    
    my $new 
        = reduce { $a->importpage($b, $_) foreach 1 .. $b->pages; $a } 
        map { PDF::API2->open($_) } 
        @ARGV; 
    $new->saveas('new.pdf'); 
    
  4. 単純なループ

    はもう少しstraighforward reduceを使用するよりも読むことです。

    use PDF::API2; 
    
    my $new = PDF::API2->new; 
    foreach my $filename (@ARGV) { 
        my $pdf = PDF::API2->open($filename); 
        $new->importpage($pdf, $_) foreach 1 .. $pdf->pages; 
    } 
    $new->saveas('new.pdf'); 
    
+0

恐ろしい答え、男!質問があります。 &merge_2_pdfsの戻り値が元のコードの次の反復に供給されないのはなぜですか? – user787747

+0

私は間違っていた。 'merge_2_pdfs()'からの戻りは次の反復にフィードバックされます。エラーは上記のようなものでした。 – stevenl

1

もう一つの可能​​性は、CAM::PDF私のライブラリです。

my $pdf1 = CAM::PDF->new($file1) or die; 
my $pdf2 = CAM::PDF->new($file2) or die; 
my $pdf3 = CAM::PDF->new($file3) or die; 
$pdf1->appendPDF($pdf2); 
$pdf1->appendPDF($pdf3); 
$pdf1->cleanoutput($outfile); 

おそらく@ARGVを超えるループでラップしてください。ちょうど2つのPDFファイルのために、私は同じことを行うためのシンプルなコマンドラインパラメータラッパーを持っている:

appendpdf.pl file1.pdfのfile2.pdfのout.pdfを

関連する問題