抓住跨越多个页面的大型pdf表

前端之家收集整理的这篇文章主要介绍了抓住跨越多个页面的大型pdf表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图刮擦 PDF tables which span across multiple pages.我尝试了很多东西,但最好的似乎是pdftotext -layout为 advised here.问题是结果文本文件不容易使用,因为表格布局在页面之间不同,所以列是不对齐还要注意以“Solsonès”开头的行中缺少值:
TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012

COMARCA          CODI i NOM EMA                    GEN    FEB    MAR         ABR       MAI      JUN      JUL          AGO        SET        OCT        N

Alt Camp         VY   Nulles                        7,5    5,5   10,9         12,3     16,7     21,6     22,3         24,4       20,1        15,9
Alt Camp         DQ   Vila-rodona                   7,9    5,6   11,0         12,0     16,6     21,0         24,3       19,9        15,8
Alt Empordà      U1   Cabanes                       8,2    6,5   11,7         12,6     17,5     22,0     23,1         24,4        16,6
Alt Empordà      W1   Castelló d'Empúries           8,1    6,4   11,6         12,9     17,0     21,1     22,0         23,1        16,4

[...]
                                                                                 TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012

COMARCA          CODI i NOM EMA                             GEN    FEB    MAR         ABR       MAI      JUN      JUL          AGO        SET        OCT

Baix Empordà     DF   la Bisbal d'Empordà                    6,6    5,3   10,2     21,9     22,9         24,6       20,3        16
Baix Empordà     UB   la Tallada d'Empordà                   6,1    5,2   10,3     22,2         23,8       19,7        15
Baix Empordà     UC   Monells                                6,1    4,6    9,9         11,4     16,5     21,7     23,5       19,6        15

[...]

                                                                        TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012

COMARCA         CODI i NOM EMA                      GEN    FEB    MAR         ABR       MAI      JUN      JUL           AGO        SET        OCT
[...]

Solsonès        CA   Clariana de Cardener            4,6    3,3         10,2     16,7     22,3      d.i.
Solsonès        Z8   el Port del Comte (2.316 m)    -0,9   -6,3   -0,2         -2,0      5,3     10,5     10,9          13,8        7,8         4,2
Solsonès        VO   Lladurs                         3,0    2,5          9,0     15,3     21,4     21,6          24,3       17,5        13,0
Solsonès        VP   Pinós                           3,0    1,6    8,9          9,2     15,1     21,3          23,8       17,6        13,3
Solsonès        XT   Solsona                                                                               d.i.         24,3       18,0        13,5
Tarragonès      VQ   Constantí                       7,9   6,0    11,2         13,1     17,6        16,6
Tarragonès      XE   Tarragona - Complex Educatiu   10,2   7,8    12,3         14,6     18,3     23,0     24,2          26,2       23,0 *      18,4
Tarragonès      DK   Torredembarra                   9,7   7,7    12,3     17,8     24,3          26,2       22,7        18,5
Terra Alta      WD   Batea                           6,3   5,2         12,1     18,3          25,5       20,2        15,9
Terra Alta      XP   Gandesa                         6,6   5,2    11,2     18,9     23,4          25,0

complete file for download – UTF8

所以,这个输出不是很容易解析.还有哪些方法可用?

看来我使用的每个工具只能提取关于表单元格布局的信息,但是它不能提取属于特定列的信息.如果单元格为空 – 这些空单元格不在输出中,那么这一点非常明显,您只能在布局中获得非空的“单元格”. PDF本身是否包含此表格信息?如果没有,搜索将解压缩的工具没有任何意义.

付费解决方案不是没有问题的,因为它可能最终比投入我的时间的几个工作日更便宜…

我试过了

>复制粘贴 – 使缺少值出现问题(第5页)
>从Acrobat保存为文本(比拷贝粘贴更糟糕的结果)
>在Excel中打开外部数据源 – 不会识别表
> https://www.pdftoexcelonline.com/ – 导致错误
> http://www.pdftoexcel.org/以及他们对Able2Extract – they messed up some columns的审判.他们在预览中正确识别了列,但在excel输出中他们被搞砸了
> http://www.pdftoword.com/ – 只需要我的电子邮件,永远不会发送任何东西
>使用python on scraperwiki http://schoolofdata.org/2013/06/18/get-started-with-scraping-extracting-simple-tables-from-pdf-documents/
似乎非常复杂,特别是对于非python用户https://scraperwiki.com/不是免费的
>我曾经遇到过像pdftables这样的python库,但是像我这样的非python开发人员并不容易使用(我甚至不能运行这些东西).有没有办法完成任务?
>我试图在R中使用tm库为recommended here,但是I have encountered some problems

编辑:Ian推荐的Cloud SDK.我注册了,但我绝对不知道从这里去哪里 – 如何上传页面,识别他们等等:

解决方法

好的,我拍了一下,我认为这将有所帮助,虽然我不知道你想要什么,你的最终输出看起来像.我很高兴为此工作,所以让我知道如果有部分需要帮助.

我从CNET下载了一个PDF to Text application.

安装完成后,我检查了这些设置:

这里的重要部分是我们正在使用物理布局选项.

这给我们的输出看起来像这样:

Taules de Dades de la Xarxa d’Estacions
    Meteorològiques Automàtiques
            2                                                                                                   Anuari de dades meteorològiques 2012 / Servei Meteorològic de Catalunya
            2                                                           TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012

COMARCA          CODI i NOM EMA                    GEN    FEB    MAR         ABR       MAI      JUN      JUL          AGO        SET        OCT        NOV         DES         ANY

Alt Camp         VY   Nulles                        7,9       11,0        8,5         14,8
Alt Camp         DQ   Vila-rodona                   7,8       11,6         14,7
Alt Empordà      U1   Cabanes                       8,6       11,8        8,3         15,3
Alt Empordà      W1   Castelló d'Empúries           8,4       12,1        8,5         15,0
Alt Empordà      VZ   Espolla                       9,0    6,7   12,4         12,7     17,8     22,8       20,9        16,7       12,9         15,6

[......]

             3                                                                                                           Anuari de dades meteorològiques 2012 / Servei Meteorològic de Catalunya
             2                                                                   TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012

COMARCA          CODI i NOM EMA                             GEN    FEB    MAR         ABR       MAI      JUN      JUL          AGO        SET        OCT        NOV         DES         ANY

Baix Empordà     DF   la Bisbal d'Empordà                    6,3        16,9        7,9
Baix Empordà     UB   la Tallada d'Empordà                   6,7        15,7        7,4
Baix Empordà     UC   Monells                                6,6        15,7       11,2         14,3
Baix Empordà     UD   Serra de Daró                          6,3    5,8     21,7         24,3       20,6       12,2        7,7         14,8

[......]

             4                                                                                                              Anuari de dades meteorològiques 2012 / Servei Meteorològic de Catalunya
             2                                                                      TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012

COMARCA           CODI i NOM EMA                               GEN    FEB    MAR         ABR       MAI      JUN      JUL          AGO        SET        OCT        NOV         DES         ANY

Maresme           UQ   Dosrius - PN Montnegre Corredor          7,2    4,6   10,8         10,7     15,8     20,4     20,8         23,4       18,1       10,8         13,9
Maresme           WT   Malgrat de Mar                           7,4    5,0         13,8         24,9        17,2       12,9        8,8         15,2
Maresme           DD   Vilassar de Mar                         10,1    7,5   12,6         13,4     23,7         25,7       22,1        18,4       13,8       10,8         16,6
Montsià           US   Alcanar                                 10,0    7,8         14,2     17,7     24,0         25,8       22,0        18,2       13,7       10,7         16,6
Montsià           UU   Amposta                                  9,6    7,1         14,3     18,8     23,5         25,3       21,6        18,0       13,4

[......]

您可以看到列排列得更好,但是我们也有标题页码. COMARCA和i NOM EMA色谱柱的长度也是变化的.我们希望将其归一化为固定宽度的列.

我写了一个Perl程序来进行规范化,并且它还结合了具有相同标题的表,并且只打印顶部的标题.它创建一个输出文件夹,其中所有文件标题文件名.

以下是代码

#!/bin/perl

use strict;
use warnings;
use open qw(:std :utf8);
use utf8;

my $comarca;
my $nom;
my $print_headers;
my $title = "";
my $fh;

while(<>) {

    if (    !/Xarxa d’Estacions/
        and !/Meteorològiques Automàtiques/
        and !/Servei/
        and !/^\s*\d+\s*$/
        and !/^\s*$/ ) {

        chomp($_);


        if ( /^\s*2/ ) { #title
            s/^\s*2\s*//;
            if ( $title ne $_ ) {
                $title = $_;
                $print_headers = 1;
            }

        } elsif ( /COMARCA/ ) { #column headers

            my ($first_col,$second_col,@the_rest) = split(/(CODI +i NOM EMA *)/,$_);


            $comarca = length $first_col;
            $nom = length $second_col;

            if ( $print_headers ) {
                my $str = sprintf "%-50s %-50s %s\n",$first_col,join("",@the_rest);
                write_string($str);
                $print_headers = 0;
            }

        } else { #data

            my ($one,$two,$three) = unpack("A${comarca}A${nom}A*",$_);
            my $str = sprintf "%-50s %-50s $three\n",$one,$two;
            write_string($str);
        }

    }
}

sub write_string {

    my $string = shift;
    my $file_name = $title;
    $file_name =~ s/[\/\\]//g;

    open ($fh,'>>',".\/output_folder\/${file_name}.txt") or die "Couldn't open: $!";
    print $fh $string;
    close ($fh);
}

输出中仍然存在一些缺陷(运行时您会看到这些),但是我想获得一些关于什么输出对您最有效的反馈.我们可以做更多的改进代码输出目录树如下所示:

Matt@MattPC ~/perl/pdftotext
$find .
.
./convert.pl
./EMAtaules2012.txt
./output.txt
./output_folder
./output_folder/AMPLITUD TÈRMICA MITJANA MENSUAL ( ºC ) - 2012?.txt
./output_folder/AMPLITUD TÈRMICA MÀXIMA MENSUAL ( ºC ) - 2012?.txt
./output_folder/DIRECCIÓ DOMINANT DEL VENT - 2012?.txt
./output_folder/GRUIX MÀXIM MENSUAL DE NEU AL TERRA ( cm ) - 2012?.txt
./output_folder/HUMITAT RELATIVA MITJANA MENSUAL ( % ) - 2012?.txt
./output_folder/MITJANA MENSUAL DE LA HUMITAT RELATIVA MÀXIMA DIÀRIA ( % ) - 2012?.txt
./output_folder/MITJANA MENSUAL DE LA HUMITAT RELATIVA MÍNIMA DIÀRIA ( % ) - 2012?.txt
[......]

文件可能如下所示:

COMARCA                                            CODI i NOM EMA                                     GEN    FEB    MAR         ABR       MAI      JUN      JUL          AGO        SET        OCT        NOV         DES         ANY
Alt Camp                                           VY   Nulles                                         7,8
Alt Camp                                           DQ   Vila-rodona                                    7,7
Alt Empordà                                        U1   Cabanes                                        8,3
Alt Empordà                                        W1   Castelló d'Empúries                            8,0
Alt Empordà                                        VZ   Espolla                                        9,6
Alt Empordà                                        D6   Portbou                                        9,5     17,4       19,8        17,0       12,3       10,1         15,5
[......]

标题只在顶部,所有列排列.这是TEMPERATURA MITJANA MENSUAL(ºC) – 2012.

我一直在考虑将更多的输出上传到一个文件托管网站,但我不知道哪一个是好的,建议?

希望这可以帮助你Tomas!

编辑:AMPLITUDTÈRMICAMÀXIMAMENSUAL(ºC)缺少条目的示例 – 2012:

Solsonès                                           VP   Pinós                          1              3,1   26   16,9   13   16,7   15   16,6   17   19,2   11   19,6   24   20,4    17      19,1   01   17,5   16   16,5   06   13,1   08   13,9   24   20,4    17/07
Solsonès                                           XT   Solsona                                                                                                              22,2    25      22,2   09   20,1   16   18,6   06   15,3   07   18,2   23   22,2    09/08
Tarragonès                                         VQ   Constantí                      1              6,4   19   21,9   23   19,7   11   12,9   07   17,4   23   17,2   21   15,1    18      14,2   18   18,0   15   15,1   02   14,9   07   16,0   10   21,9    23/02

更新

用于处理输入文件的更新脚本:

#!/bin/perl

use strict;
use warnings;
use open qw(:std :utf8);
use utf8;
use charnames ':full';

my @column_lengths;
my $print_headers;
my $title = "";
my $fh;

while(<>) {

    if (    !/Xarxa d’Estacions/
        and !/Meteorològiques Automàtiques/
        and !/Servei/
        and !/^\s*\d+\s*$/
        and !/^\s*$/ ) {

        s/[\r\n]+//g;
        s/ +\d+$//;
        if ( /^\s*2/ ) { #title
            s/^\s*2\s*//;
            if ( $title ne $_ ) {
                $title = $_;
                $print_headers = 1;
            }

        } elsif ( /COMARCA/ ) { #column headers

            my $comarca = (split(/(COMARCA *)/,$_))[1];
            my $codi = (split(/(CODI *)/,$_))[1];
            my $inomema = (split(/(i NOM EMA *)  /,$_))[1];

            my $the_rest = (split(/(i NOM EMA *)  /,$_))[2];

            my @rest = split(/( \w+ *)/,$the_rest);

            undef @column_lengths;

            push @column_lengths,length $comarca;
            push @column_lengths,length $codi;
            push @column_lengths,length $inomema;

            for (@rest) {
                if ( $_ ) {
                    push @column_lengths,length $_;
                }
            }

            $column_lengths[-1] = "*";

            if ( $print_headers ) {
                $print_headers = 0;
                write_string(join(";",unpack( "A" . join("A",@column_lengths),$_)) . "\n");
            }

        } else { #data

            write_string(join(";",$_)) . "\n");

        }

    }
}

sub write_string {

    my $string = shift;
    my $file_name = $title;
    $file_name =~ s/[º]//g;
    $file_name =~ s/[^\w ]//g;
    $file_name =~ s/ +/ /g;
    $file_name =~ s/È/E/g;
    $file_name =~ s/À/A/g;
    $file_name =~ s/Ó/O/g;
    $file_name =~ s/Í/I/g;
    $file_name =~ s/Ç/C/g;

    open ($fh,".\/output_folder\/${file_name}.txt") or die "Couldn't open: $!";
    print $fh $string;
    close ($fh);
}

这一个结合了线条与d.i.在下一行.

#!/bin/perl -i

use strict;
use warnings;

my $last = <>;

while(<>) {

    my @current_array = split(";",$_);

    if ( /^;+[ \t]+.d\.i\./ ) {

        my @last_array = split(";",$last);
        my @combined_array;

        #print "matches\n";

        for my $element (@current_array) {

            if ( $element =~ /d\.i\./ ) {
                push @combined_array,$element;
                shift @last_array;
            } else {
                push @combined_array,$last_array[0];
                shift @last_array;
            }

        }
        undef @current_array;
        @current_array = @combined_array;
    }
    $last = join ";",@current_array;
    print $last;

}

输出为csv格式,分号分隔符.

猜你在找的Perl相关文章