11
votes

Diviser un PDF par des signets?

Je dois traiter des pdfs simples qui ont été créés par "Fusionner" plusieurs PDF. Chacun des PDF fusionnés a les lieux où les pièces PDF commencent à être affichées avec un signet.

Y a-t-il un moyen de diviser automatiquement cela par des signets avec un script?

Nous n'avons que les signets pour indiquer les pièces, non les numéros de page, nous devrions donc déduire les numéros de page des signets. Un outil Linux serait le meilleur.


0 commentaires

4 Réponses :


3
votes

Vous avez des programmes construits comme PDF-Split qui peut le faire pour vous :

A-PDF Split est un programme d'utilitaire de bureau Lightning-rapide-rapide qui vous permet de diviser n'importe quel fichier PDF Acrobat en fichiers PDF plus petits. Il fournit une flexibilité complète et un contrôle utilisateur en termes de scission des fichiers et de la manière dont les fichiers de sortie divisés sont nommés de manière unique. A-PDF Split fournit de nombreuses alternatives pour la manière dont vos fichiers volumineux sont scindés - par pages, par des signets et par une page impair / pair. Même vous pouvez extraire ou supprimer une partie d'un fichier PDF. A-PDF Split propose également des divisions définies avancées pouvant être enregistrées et importées ultérieurement pour une utilisation avec des tâches de division de fichiers répétitives. La division A-PDF représente la flexibilité de division ultime dans le fichier en fonction de tous les besoins.

A-PDF Split fonctionne avec des fichiers PDF protégés par mot de passe et peut appliquer diverses fonctionnalités de sécurité PDF aux fichiers de sortie divisés. Si nécessaire, vous pouvez recombiner les fichiers divisés générés avec d'autres fichiers PDF à l'aide d'un utilitaire tel que la fusion A-PDF pour former de nouveaux fichiers PDF composite.

La division A-PDF ne nécessite pas Adobe Acrobat et produit des documents compatibles avec Adobe Acrobat Reader Version 5 et supérieure à Adobe Acrobat Reader.

EDIT *

a également trouvé un programme gratuit Open Source ici si vous ne voulez pas payer.



21
votes

PDFTK peut être utilisé pour diviser le fichier PDF et extraire les numéros de page des signets.

Pour obtenir les numéros de page des signets DO P>

#!/bin/bash

infile=$1 # input pdf
outputprefix=$2

[ -e "$infile" -a -n "$outputprefix" ] || exit 1 # Invalid args

pagenumbers=( $(pdftk "$infile" dump_data | \
                grep '^BookmarkPageNumber: ' | cut -f2 -d' ' | uniq)
              end )

for ((i=0; i < ${#pagenumbers[@]} - 1; ++i)); do
  a=${pagenumbers[i]} # start page number
  b=${pagenumbers[i+1]} # end page number
  [ "$b" = "end" ] || b=$[b-1]
  pdftk "$infile" cat $a-$b output "${outputprefix}"_$a-$b.pdf
done


2 commentaires

Nice :) J'utilise grep -a1 '^ bookarkLevel: 1' | | grep '^ bookmarkPagenumber:' Pour obtenir uniquement des signets de haut niveau. Malheureusement, tous les favoris de niveau inférieur se font perdre de cette façon ...


Je voulais juste mentionner que ce script Bash fonctionne toujours bien sur MacOS Sierra avec PDFTK. Bien fait!



4
votes

Il y a un outil de ligne de commande écrit en Java appelé Sejda où vous pouvez trouver le SplitByBookmarks Commande qui fait exactement ce que vous avez demandé. C'est Java afin qu'il fonctionne de Linux et d'être un outil de ligne de commande que vous pouvez écrire un script pour le faire.

Disclaimer de
Je suis l'un des auteurs


3 commentaires

Ils ont limité de 200 pages.


Non, il n'y a pas de limite .. S'il vous plaît ouvrir un problème si vous faites face à un problème.


SEJDA-Console Nécessite Pro, qui est 2000 $ / an. Certes non une option pour mon cas d'utilisation.



1
votes

Voici un petit programme Perl que j'utilise pour la tâche. Perl n'est pas spécial; C'est juste une enveloppe autour de PDFTK pour interpréter son Sortie DUTP_DATA CODE> pour la transformer en numéros de page pour extraire:

#!perl
use v5.24;
use warnings;

use Data::Dumper;
use File::Path qw(make_path);
use File::Spec::Functions qw(catfile);

my $pdftk = '/usr/local/bin/pdftk';
my $file = $ARGV[0];
my $split_dir = $ENV{PDF_SPLIT_DIR} // 'pdf_splits';

die "Can't find $ARGV[0]\n" unless -e $file;

# Read the data that pdftk spits out.
open my $pdftk_fh, '-|', $pdftk, $file, 'dump_data';

my @chapters;
while( <$pdftk_fh> ) {
    state $chapter = 0;
    next unless /\ABookmark/;

    if( /\ABookmarkBegin/ ) {
        my( $title ) = <$pdftk_fh> =~ /\ABookmarkTitle:\s+(.+)/;
        my( $level ) = <$pdftk_fh> =~ /\ABookmarkLevel:\s+(.+)/;

        my( $page_number ) = <$pdftk_fh> =~ /\BookmarkPageNumber:\s+(.+)/;

        # I only want to split on chapters, so I skip higher
        # level numbers (higher means more nesting, 1 is lowest).
        next unless $level == 1;

        # If you have front matter (preface, etc) then this numbering
        # will be off. Chapter 1 might be called Chapter 3.
        push @chapters, {
            title         => $title,
            start_page    => $page_number,
            chapter       => $chapter++,
            };
        }
    }

# The end page for one chapter is one before the start page for
# the next chapter. There might be some blank pages at the end
# of the split for PDFs where the next chapter needs to start on
# an odd page.
foreach my $i ( 0 .. $#chapters - 1 ) {
    my $last_page = $chapters[$i+1]->{start_page} - 1;
    $chapters[$i]->{last_page} = $last_page;
    }
$chapters[$#chapters]->{last_page} = 'end';

make_path $split_dir;
foreach my $chapter ( @chapters ) {
    my( $start, $end ) = $chapter->@{qw(start_page last_page)};

    # slugify the title so use it as a filename
    my $title = lc( $chapter->{title} =~ s/[^a-z]+/-/gri );

    my $path = catfile( $split_dir, "$title.pdf" );
    say "Outputting $path";

    # Use pdftk to extract that part of the PDF
    system $pdftk, $file, 'cat', "$start-$end", 'output', $path;
    }


0 commentaires