刮掉跨越多个页面的大型pdf表

时间:2013-08-06 10:58:15

标签: r perl ms-access pdf-scraping

我正在努力抓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,6     22,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       20,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,4       20,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,9         12,6     17,2     21,9     22,9         24,6       20,3        16
Baix Empordà     UB   la Tallada d'Empordà                   6,1    5,2   10,7         12,3     16,6     21,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,0         24,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,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,6    9,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,4     21,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,1     21,9     22,6          24,6       20,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         14,3     17,9     22,8     24,3          26,2       22,7        18,5
Terra Alta      WD   Batea                           6,3   5,0    11,2         12,1     18,3     23,0     23,3          25,5       20,2        15,9
Terra Alta      XP   Gandesa                         6,6   5,2    11,2         12,2     18,1     22,9     23,4          25,6       20,4        16,0

complete file for download - UTF8

所以,这个输出不是很容易解析。还有哪些其他方法?

我使用的每个工具似乎只能提取有关表格单元格的 layout 的信息,但它不会提取属于特定列的信息。如果单元格为空,则非常明显 - 空单元格不在输出中,您只能获得具有布局的非空“单元格”。 PDF本身是否包含此表格信息?如果没有,则搜索将提取它的工具没有意义。

付费解决方案并非毫无疑问,因为它最终可能比投入我工作的几个工作日更便宜......


我尝试过:

编辑:Ian推荐的Cloud SDK。我注册但我绝对不知道从哪里开始 - 如何上传页面,识别它们等等:

enter image description here

7 个答案:

答案 0 :(得分:7)

好的我拍了一下这个,我觉得它会有所帮助,虽然我不确定你想要的最终输出是什么样的。我很乐意在这方面做更多的工作,所以请告诉我你是否需要帮助。


我首先从CNET下载PDF to Text application

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

PDF to text conversion

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

这给了我们这样的输出:

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,5    5,5   10,9         12,3     16,7     21,6     22,3         24,4       20,1        15,9       11,0        8,5         14,8
Alt Camp         DQ   Vila-rodona                   7,9    5,6   11,0         12,0     16,6     21,6     22,0         24,3       19,9        15,8       11,0        8,6         14,7
Alt Empordà      U1   Cabanes                       8,2    6,5   11,7         12,6     17,5     22,0     23,1         24,4       20,4        16,6       11,8        8,3         15,3
Alt Empordà      W1   Castelló d'Empúries           8,1    6,4   11,6         12,9     17,0     21,1     22,0         23,4       20,1        16,4       12,1        8,5         15,0
Alt Empordà      VZ   Espolla                       9,0    6,7   12,4         12,7     17,8     22,0     23,3         24,8       20,9        16,7       12,0        8,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,6    5,3   10,9         12,6     17,2     21,9     22,9         24,6       20,3        16,6       11,9        7,6         14,9
Baix Empordà     UB   la Tallada d'Empordà                   6,1    5,2   10,7         12,3     16,6     21,3     22,2         23,8       19,7        15,8       11,7        7,6         14,4
Baix Empordà     UC   Monells                                6,1    4,6    9,9         11,4     16,5     21,7     23,0         24,5       19,6        15,7       11,7        7,2         14,3
Baix Empordà     UD   Serra de Daró                          6,3    5,3   10,6         12,3     16,8     21,6     22,7         24,3       20,3        16,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,6        15,1       10,7        7,8         13,9
Maresme           WT   Malgrat de Mar                           7,4    5,4   11,0         13,0     16,7     21,5     22,8         24,6       20,9        17,2       12,9        8,8         15,2
Maresme           DD   Vilassar de Mar                         10,1    7,5   12,6         13,9     17,9     22,4     23,7         25,7       22,1        18,4       13,8       10,8         16,6
Montsià           US   Alcanar                                 10,0    7,6   11,8         14,2     17,9     22,7     24,0         25,8       22,0        18,2       13,7       10,7         16,6
Montsià           UU   Amposta                                  9,6    7,5   12,1         14,3     18,3     22,8     23,5         25,3       21,6        18,0       13,1       10,8         16,4

[......]

您可以看到列排得更好,但我们也有标题和页码。此外,COMARCAi 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, $second_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,5    5,5   10,9         12,3     16,7     21,6     22,3         24,4       20,1        15,9       11,0        8,5         14,8
Alt Camp                                           DQ   Vila-rodona                                    7,9    5,6   11,0         12,0     16,6     21,6     22,0         24,3       19,9        15,8       11,0        8,6         14,7
Alt Empordà                                        U1   Cabanes                                        8,2    6,5   11,7         12,6     17,5     22,0     23,1         24,4       20,4        16,6       11,8        8,3         15,3
Alt Empordà                                        W1   Castelló d'Empúries                            8,1    6,4   11,6         12,9     17,0     21,1     22,0         23,4       20,1        16,4       12,1        8,5         15,0
Alt Empordà                                        VZ   Espolla                                        9,0    6,7   12,4         12,7     17,8     22,0     23,3         24,8       20,9        16,7       12,0        8,9         15,6
Alt Empordà                                        D6   Portbou                                        9,6    5,5   12,7         12,5     17,4     21,5     22,9         24,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(";", unpack( "A" . join("A", @column_lengths), $_)) . "\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格式。

答案 1 :(得分:7)

这是一个R解决方案,但它并非没有缺陷。

第1部分:设置步骤

# Read the lines of your file into R
x <- readLines("EMAtaules2012.txt")

# Make sure it shows up as UTF-8 to get proper accents and so on
Encoding(x) <- "UTF-8"

# Identify the lines where the data starts
Start <- grep("COMARCA", x)

# Grab the names of each table
ListNames <- gsub("\\s+", " ", x[Start-2])

# Figure out the number of rows of data per page
Runs <- rle(diff(cumsum(x != "")))
Nrows <- Runs$lengths[Runs$lengths > 4]+1

# Make our life easier by making this column name
#  a single string
x <- gsub("i NOM EMA", "i_NOM_EMA", x)

# Since these are fixed width files, we need to figure
#  out the widths of each column. This is the sum of
#  the number of characters in the header row plus
#  the number of spaces between each column name
Spaces <- gregexpr(x[Start], pattern="\\s+")
Spaces <- lapply(Spaces, function(x) c(attr(x, "match.length"), 0))
Chars <- lapply(strsplit(x[Start], "\\s+"), nchar)
Widths <- lapply(seq_along(Spaces), 
                 function(x) rowSums(cbind(Spaces[[x]], 
                                           Chars[[x]])))

第2部分:使用read.fwf获取

中的数据
# Now, you can use `read.fwf` to read your data files in
temp <- lapply(seq_along(Start), function(fwf) {
  A <- read.fwf(textConnection(x), 
                widths = c(Widths[[fwf]]), 
                header = FALSE, 
                skip = Start[fwf]+1, 
                n = Nrows[fwf]-2, 
                blank.lines.skip = TRUE,
                strip.white = TRUE,
                stringsAsFactors = FALSE)
  # Add in the column names
  names(A) <- scan(what = "character", 
                   file = textConnection(x[Start[fwf]]), 
                   quiet = TRUE)
  A
})

# Assign the table names
names(temp) <- ListNames

# Some more cleanup. The original tables span multiple pages
#  in the PDF, but we can `rbind` them together in R
Tables <- unique(ListNames)
final <- lapply(seq_along(Tables), function(final) {
  A <- do.call(rbind, temp[names(temp) %in% Tables[final]])
  rownames(A) <- NULL
  A
})
# Add the names back in
names(final) <- Tables

第3部分:它有效吗?

# View the first few rows and columns of the first three tables
lapply(final[1:3], function(y) head(y[1:5], 3))
# $` TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012`
#       COMARCA CODI           i_NOM_EMA GEN FEB
# 1    Alt Camp   DQ         Vila-rodona 7,9 5,6
# 2 Alt Empordà   U1             Cabanes 8,2 6,5
# 3 Alt Empordà   W1 Castelló d'Empúries 8,1 6,4
# 
# $` TEMPERATURA MÀXIMA MITJANA MENSUAL ( ºC ) - 2012`
#       COMARCA CODI           i_NOM_EMA  GEN  FEB
# 1    Alt Camp   DQ         Vila-rodona 13,1 11,7
# 2 Alt Empordà   U1             Cabanes 15,1 12,4
# 3 Alt Empordà   W1 Castelló d'Empúries 14,4 11,7
# 
# $` TEMPERATURA MÍNIMA MITJANA MENSUAL ( ºC ) - 2012`
#       COMARCA CODI           i_NOM_EMA GEN FEB
# 1    Alt Camp   DQ         Vila-rodona 3,8 0,5
# 2 Alt Empordà   U1             Cabanes 2,4 0,9
# 3 Alt Empordà   W1 Castelló d'Empúries 2,1 0,5

# Some tables, like those on page 76 (for the table "DIRECCIÓ DOMINANT DEL VENT"), had more columns than others. 
# Did our script take care of that?
names(final$` DIRECCIÓ DOMINANT DEL VENT`)
#  [1] "COMARCA"   "CODI"      "i_NOM_EMA" "vent"      "GEN"       "FEB"      
#  [7] "MAR"       "ABR"       "MAI"       "JUN"       "JUL"       "AGO"      
# [13] "SET"       "OCT"       "NOV"       "DES"       "ANY"    

有点 有效。但是,您的输入文件并不完美,这意味着仍然会有很多清理。例如,PDF中的某些列似乎有多个值。不知道你将如何对这些进行任何分析。

希望上面代码中的注释可以帮助您开始找出如何以更好的方式抓取数据。


更新:仅提取数据

在上面的“第1部分”之后继续,这是一个依赖于( gasp )Excel的解决方案。基本思想是,如果将文本导入为“固定宽度”,Excel实际上可以很好地检测列断点的位置。

因此,我们使用R将文本分解为单独的页面,每页一个文件,只有数据(不是列名或行名,在所有数据集中大致相同)。

有了这个,这是最后一个R步骤:

# Output just the data
temp <- lapply(seq_along(Widths), function(y) {
  DEL <- sum(Widths[[y]][1:3])-2
  A <- substring(x[(Start[y]+1):(sum(Start[y], Nrows[y]))], DEL)
  writeLines(A, paste("temp_", y, ".txt", collapse = ""))
  A
})

让我们打开文件“temp_9.txt”,这是一个缺少列的文件:

enter image description here

^^确保选择“固定宽度” - 默认情况下应该是该文件没有分隔符。

enter image description here

^^ Excel会显示预览列的位置。

enter image description here

^^我已经突出显示了“问题行”,以便了解它是如何运作的。

答案 2 :(得分:5)

过去我使用pdftohtml可以用来生成xml,描述为here。列通常分离得很好,因此您可以使用定位来提取列。

我写了pdftables的很大一部分,为不透明道歉!对于您显示的文档的某些页面,它可以正常工作,例如第2页给出了此回复底部的输出。例如,对于其他页面,它会在第33页上失效。这里的问题是在一个列标题下有两个数字,它们被pdftables粘在一起。在任何一种情况下,“COMARCA,CODI i,NOM EMA”列都不会分开。您可以在GitHub上提交pdftables问题,目前我还没有积极开展工作。它可以通过pip install获得。

如果您想进入商业路线,那么Abbyy FineReader非常好,他们会产生cloud SDK,这将为您提供30个左右的免费页面。他们有多种语言的示例代码,但他们的支持不是很好。

     14 columns, 39 rows
                                      0    1    2    3    4    5    6    7    8    9   10   11   12   13
    -----------------------------------------------------------------------------------------------------
  0 |             COMARCACODI i NOM EMA| GEN| FEB| MAR| ABR| MAI| JUN| JUL| AGO| SET| OCT| NOV| DES| ANY|
  1 |                  VYNullesAlt Camp| 7,5| 5,5|10,9|12,3|16,7|21,6|22,3|24,4|20,1|15,9|11,0| 8,5|14,8|
  2 |             DQVila-rodonaAlt Camp| 7,9| 5,6|11,0|12,0|16,6|21,6|22,0|24,3|19,9|15,8|11,0| 8,6|14,7|
  3 |              Alt EmpordàU1Cabanes| 8,2| 6,5|11,7|12,6|17,5|22,0|23,1|24,4|20,4|16,6|11,8| 8,3|15,3|
  4 |  Alt EmpordàW1Castelló d'Empúries| 8,1| 6,4|11,6|12,9|17,0|21,1|22,0|23,4|20,1|16,4|12,1| 8,5|15,0|
  5 |              Alt EmpordàVZEspolla| 9,0| 6,7|12,4|12,7|17,8|22,0|23,3|24,8|20,9|16,7|12,0| 8,9|15,6|
  6 |              D6PortbouAlt Empordà| 9,6| 5,5|12,7|12,5|17,4|21,5|22,9|24,4|19,8|17,0|12,3|10,1|15,5|
  7 |                D4RosesAlt Empordà| 9,3| 7,2|13,0|13,6|18,2|22,6|23,9|25,7|21,3|17,5|13,2| 9,9|16,3|
  8 |   Alt EmpordàU2Sant Pere Pescador| 7,8| 6,3|11,5|12,9|16,8|21,2|22,2|23,6|20,2|16,5|12,3| 8,5|15,0|
  9 |  Alt EmpordàW2Torroella de Fluvià| 7,4| 6,0|11,2|12,6|16,4|21,2|22,3|23,7|19,9|16,1|11,7| 8,0|14,7|
 10 |             Alt EmpordàW3Ventalló| 7,3| 6,2|11,4|12,8|16,9|21,8|22,8|24,3|20,4|16,5|12,0| 8,1|15,1|
 11 |            Alt PenedèsWPCanaletes| 7,0| 5,2|11,3|11,9|16,7|21,5|22,0|24,2|19,7|15,6|10,7| 8,1|14,5|
 12 |            Alt PenedèsDIFont-rubí| 8,1| 6,2|12,0|11,9|16,9|21,8|22,0|24,4|20,0|15,9|11,4| 8,9|15,0|
 13 |           Alt PenedèsW4la Granada| 7,0| 5,5|11,2|12,6|17,2|21,9|22,4|24,3|20,0|16,0|11,1| 8,3|14,8|
 14 |   Alt PenedèsU3Sant Martí Sarroca| 6,4| 5,1|10,9|12,4|17,0|21,8|22,3|24,3|19,9|15,7|10,8| 8,0|14,6|
 15 | Alt PenedèsWYSant Sadurní d'Anoia| 6,4| 5,1|11,0|12,8|17,6|22,6|23,2|25,0|20,5|16,2|10,9| 7,8|15,0|
 16 |       CDla Seu d'UrgellAlt Urgell| 3,6| 2,5| 8,5| 8,4|14,6|20,3|21,0|23,4|16,9|12,2| 7,0| 3,2|11,8|
 17 |                W5OlianaAlt Urgell| 2,0| 2,7| 9,8|10,2|16,8|23,0|22,9|25,6|19,1|13,9| 8,6| 3,1|13,2|
 18 |               Alt UrgellCJOrganyà| 2,6| 3,5| 9,8| 9,9|16,1|22,0|22,6|25,3|18,8|13,5| 8,2| 2,9|13,0|
 19 |     Alta RibagorçaZ2Boí (2.535 m)|-2,4|-7,5|-1,3|-3,4| 3,8| 8,6| 9,4|12,0| 6,3| 2,7|-1,1|-3,2| 2,0|
 20 |  Alta RibagorçaCTel Pont de Suert| 0,5| 1,6| 6,9| 7,9|14,1|18,0|19,1|20,4|15,7|10,7| 6,1| 1,3|10,2|
 21 |   CEels Hostalets de PierolaAnoia| 7,3| 5,5|11,7|12,1|17,4|22,4|22,9|25,2|20,3|16,2|11,1| 8,3|15,1|
 22 |                 XBla LlacunaAnoia| 5,4| 3,3| 9,3|10,3|15,6|20,8|20,9|23,3|18,0|14,1| 9,1| 6,9|13,1|
 23 |               AnoiaXAla Panadella| 3,6| 1,7| 9,2| 8,7|14,9|20,5|20,4|23,2|17,2|13,3| 7,9| 5,1|12,2|
 24 |                      H1Ã’denaAnoia| 5,1| 3,3| 9,4|11,5|16,3|21,7|22,5|24,6|19,4|15,2| 9,3| 6,0|13,7|
 25 |                      WWArtésBages| 3,5| 2,8| 9,2|11,2|16,6|22,4|23,2|25,1|19,3|15,0| 9,1| 4,3|13,5|
 26 |        U4Castellnou de BagesBages| 4,8| 3,8|10,5|10,9|16,3|22,0|22,5|25,0|19,3|15,0| 9,6| 5,9|13,9|
 27 |        R1el Pont de VilomaraBages| 3,8| 3,1| 9,9|12,3|17,4|22,9|23,5|25,4|20,0|15,7| 9,7| 5,0|14,1|
 28 |    BagesWNMontserrat - Sant Dimes| 6,2| 3,3| 9,7| 8,6|14,8|19,5|19,5|22,4|16,9|13,5| 9,0| 7,1|12,6|
 29 | CLSant Salvador de GuardiolaBages| 3,3| 2,8| 9,1|11,5|16,4|22,0|22,4|24,6|19,2|14,9| 9,1| 4,8|13,4|
 30 |   U5Prades - los HortalsBaix Camp| 2,8| 0,0| 6,4| 7,4|13,0|18,4|18,0|21,3|15,0|11,3| 6,5| 4,1|10,4|
 31 |                W6RiudomsBaix Camp| 9,7| 7,1|12,0|13,4|17,6|22,4|23,1|25,2|21,2|17,1|12,3|10,1|16,0|
 32 |     U6Vinyols i els ArcsBaix Camp|10,2| 7,6|12,0|13,8|17,6|22,5|24,0|25,9|22,3|18,2|13,2|11,1|16,6|
 33 |                Baix EbreU7Aldover|10,0| 8,5|13,2|14,8|19,7|24,6|25,2|27,1|22,7|18,3|12,9|11,1|17,4|
 34 |             DBel PerellóBaix Ebre| 8,7| 7,0|12,0|13,3|17,9|22,6|23,3|25,3|21,4|17,2|11,9|10,3|15,9|
 35 |                U9l'AldeaBaix Ebre| 9,9| 8,1|12,5|14,3|18,5|23,3|24,1|26,0|22,1|17,9|13,1|10,7|16,8|
 36 |       UAl'Ametlla de MarBaix Ebre| 9,6| 7,8|12,3|13,8|18,0|22,9|23,9|25,8|22,0|17,6|12,5|10,6|16,4|
 37 |          Baix EbreX5PN dels Ports| 3,4|-0,2| 6,5| 6,8|13,4|18,7|17,8|21,2|15,2|11,3| 6,1| 4,9|10,5|
 38 |       Baix EmpordàDOCastell d'Aro| 6,7| 5,1|10,6|12,0|16,2|20,9|21,8|23,8|20,1|16,3|12,2| 8,1|14,5|
    -----------------------------------------------------------------------------------------------------  

unicode问题归咎于我的开发环境(Spyder)。

答案 3 :(得分:4)

如果您对深入研究Python或其他基于代码的解决方案持谨慎态度,那么针对少量pdf的快速而肮脏的解决方案的完全不同的方法是将任务外包给MechanicalTurk

每列拥有多个用户允许您仔细检查提交的答案,并且您还可以发布生成的.csv表,并为工作人员可以找到的每个错误支付大量(例如,5美元)。通常最终会比您或其他人编写解决方案的时间更便宜。

答案 4 :(得分:2)

虽然使用pdftotext时页面的布局不同,但请注意,各个页面上的列标题(COMARCA,CODI等)似乎与该页面上的数据对齐

此外,您的pdf中有许多不同类型的数据 - 风向,风力,湿度,降水等。因此,不仅相同数据的页面布局不同,但布局也不同,因为也有不同的数据集。

仅仅为了完整性 - 原始PDF中存在“Solsonès”(作为一个示例)的缺失数据。似乎pdftotext做了一个合理的工作 - 缺少的数据是空白,就像在原始PDF中一样。

因此,与pdftotext保持一致并将页面(由换页符分隔)视为列数据并使用struct进行解析可能是有意义的,如下所示:

How to efficiently parse fixed width files?

使这项工作的一种方法是检测换页,查找以“COMARCA”开头的下一行,并使用该行中的间距来设置struct的列。

答案 5 :(得分:2)

为此构建索引的努力(可能是格式的变化与不同的子报告有关。这些似乎都适用于加泰罗尼亚:

heads <- grep("                                                                .+2012", txt)
notheads <- grep("                                                                .+Anuari de", txt)
 headtxt <-  unique(trim(txt[1:length(txt) %in% heads & !1:length(txt) %in% notheads]))

 [1] "TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012"                            
 [2] "TEMPERATURA MÀXIMA MITJANA MENSUAL ( ºC ) - 2012"                     
 [3] "TEMPERATURA MÍNIMA MITJANA MENSUAL ( ºC ) - 2012"                     
 [4] "TEMPERATURA MÀXIMA ABSOLUTA MENSUAL ( ºC ) - 2012"                    
 [5] "TEMPERATURA MÍNIMA ABSOLUTA MENSUAL ( ºC ) - 2012"                    
 [6] "AMPLITUD TÈRMICA MITJANA MENSUAL ( ºC ) - 2012"                       
 [7] "AMPLITUD TÈRMICA MÀXIMA MENSUAL ( ºC ) - 2012"                        
 [8] "NOMBRE DE DIES DE GLAÇADA ( TN ≤ 0 ºC ) - 2012"                       
 [9] "PRECIPITACIÓ MENSUAL ( mm ) - 2012"                                   
[10] "PRECIPITACIÓ MENSUAL MÀXIMA EN 24 HORES ( mm ) - 2012"                
[11] "PRECIPITACIÓ MENSUAL MÀXIMA EN 1 HORA ( mm ) - 2012"                  
[12] "PRECIPITACIÓ MENSUAL MÀXIMA EN 30 MINUTS ( mm ) - 2012"               
[13] "PRECIPITACIÓ MENSUAL MÀXIMA EN UN 1 MINUT ( mm ) - 2012"              
[14] "NOMBRE DE DIES DE PRECIPITACIÓ (PPT ≥ 0,1 mm) - 2012"                 
[15] "NOMBRE DE DIES DE PRECIPITACIÓ (PPT > 0,2 mm) - 2012"                 
[16] "VELOCITAT MITJANA DEL VENT MENSUAL ( m/s ) - 2012"                    
[17] "DIRECCIÓ DOMINANT DEL VENT - 2012"                                    
[18] "MITJANA MENSUAL DE LA RATXA MÀXIMA DIÀRIA DEL VENT ( m/s ) - 2012"    
[19] "RATXA MÀXIMA ABSOLUTA DEL VENT MENSUAL ( m/s ) - 2012"                
[20] "HUMITAT RELATIVA MITJANA MENSUAL ( % ) - 2012"                        
[21] "MITJANA MENSUAL DE LA HUMITAT RELATIVA MÀXIMA DIÀRIA ( % ) - 2012"    
[22] "MITJANA MENSUAL DE LA HUMITAT RELATIVA MÍNIMA DIÀRIA ( % ) - 2012"    
[23] "MITJANA MENSUAL DE LA IRRADIACIÓ SOLAR GLOBAL DIÀRIA ( MJ/m2 ) - 2012"
[24] "PRESSIÓ ATMOSFÈRICA MITJANA MENSUAL, A NIVELL DE L'EMA ( hPa ) - 2012"
[25] "PRESSIÓ ATMOSFÈRICA MÀXIMA ABSOLUTA MENSUAL ( hPa ) - 2012"           
[26] "PRESSIÓ ATMOSFÈRICA MÍNIMA ABSOLUTA MENSUAL ( hPa ) - 2012"           
[27] "GRUIX MÀXIM MENSUAL DE NEU AL TERRA ( cm ) - 2012"  

parens和破折号干扰了grepping。因此尝试通过grep(val, txt)删除"\\(.+$"匹配并使用单个异常(我决定“手动修复”)来尝试进入可以使用这些值来标识页眉位置的表单:< / p>

 headtxt[14:15]
#[14] "NOMBRE DE DIES DE PRECIPITACIÓ (PPT ≥ 0,1 mm) - 2012"                 
#[15] "NOMBRE DE DIES DE PRECIPITACIÓ (PPT > 0,2 mm) - 2012"  

headtxt <- gsub("\\(.+$", "", headtxt)

pagedivs <- lapply(headtxt, grep, txt)
# Seemed reasonable that the first 5 (of 10) should be the first section
pagedivs[[14]] <- pagedivs[[14]][1:5]
pagedivs[[15]] <- pagedivs[[15]][6:10]

因此寻找结束页面的标记看起来像4个空行是可靠的

> length(notheads)
[1] 113
> rl.lens <- rle( nchar(txt) )
> table(rl.lens$lengths[rl.lens$values==0])
#  1   4 
#226 113 

删除所有“Ô因为他们正在创建非固定宽度列:

txt <- gsub("Ã", "", txt)
write(txt, "txt_noAs.txt)

有趣的是,我的文本编辑器现在显示“à”的“Ô曾出现的位置。在在pagedivs + 4 4个空行的位置,并使用read.fwf从“utils的”包这一点一个可以遍历页型起始内的页面。剩下要支持的是一个布局定义,你说你已经有了一个句柄,但也可以使用pkg:gsubfn的strapply或正则表达式解决方案来推断。

寻找开发正则表达式解决方案的方法:

> numfields <- gregexpr("[-[:digit:].]+ ", txt)
> table( sapply( numfields,  length))

   1    2    3    5    6    7    8   11   12   13   14   15 
1201  193    8    1   13   15    2    4 1162  869  308   32 
  16   17   19   20   21   23   24   25   26   27   28   30 
   1    3    1    1    1    7   10  688  481  168   13    1 

很明显,这些页面分为两类:数字列数为12-14的页面和数字为23-28的页面。我原本预计这会有所不同,但我猜“任何”专栏都会让我失望。

答案 6 :(得分:0)

很明显,原始Excel电子表格由使用不同列宽的不同表格组成。

因此PDF表格也使用不同的列宽。如果查看PDF,可以看到以下页面范围组,每个页面范围具有相同的列宽。每个小组还描述了不同的内容,从每个小组的起始页面的更改标题可以看出(即使无法理解西班牙语,我也可以识别这些差异):

  1. 第2-6页(5页)
  2. 第7-11页(5页)
  3. 第12-16页(5页)
  4. 第17-21页(5页)
  5. 第22-26页(5页)
  6. 第27-31页(5页)
  7. 第32-36页(5页)
  8. 第37-41页(5页)
  9. 第42-46页(5页)
  10. 第47-51页(5页)
  11. 第52-56页(5页)
  12. 第57 + 58页(2页)
  13. 第59-62页(4页)
  14. 第63-67页(5页)
  15. 第68-72页(5页)
  16. 第73-76页(4页)
  17. 第77-80页(4页)
  18. 第81-84页(4页)
  19. 第85-88页(5页)
  20. 第89-93页(5页)
  21. 第84-98页(5页)
  22. 第99-103页(5页)
  23. 第104-107页(4页)
  24. 第108 + 109页(2页)
  25. 第110 + 111页(2页)
  26. 第112 + 113页(2页)
  27. 最后,第114页(仅限1页)
  28. 因此,您可以让pdftotext通过这些页面组提取表格数据。如果结果不是每个页面范围内的完美对齐列,则必须逐页提取表。这些应该很容易导入Excel作为“固定宽度”表数据。

    为了向您展示一个示例(使用Poppler的 pdftotext 版本创建):

    pdftotext \ -layout \ -enc UTF-8 \ -f 22 -l 26 \ -nopgbrk \ -x 20 -y 82 \ -W 810 -H 450 \ EMAtaules2012.pdf \ -

    • -f 22 -l 26
      这告诉工具将页面22提取为范围中的第一个,将第26页提取为最后一个。
    • -nopgbrk
      告诉工具不要插入分页符。
    • -x 20 -y 82
      设置从中提取表数据的区域的左上角(以像素为单位)。注意,我在这里使用了这些值,它们也排除了列标题,而不仅仅是页眉和表名。
    • -W 810 -H 450 :设置用于表格数据提取的区域的宽度和高度(以像素为单位)。

    注意,如果您使用XPDF的 pdftotext 版本(可在 www.foolabs.com/xpdf/download.html 下找到)的命令行选项> -x -y -W -H 不支持。但是如果您使用 -table 而不是 -layout 使用XPDF-pdftotext,那么结果应该类似(但是您仍然需要删除手动填写页面和列标题。

    上面的命令为你提供了这个输出(我只显示前两页的输出,宽度跳跃在页面边框的正确位置,Baix Ebre条目后面的两行):

    Alt Camp         VY   Nulles                        -1,4   19    -4,9   12     1,1   07     4,0   07    4,8   01   11,2   13   12,0   02   12,7   31    8,3   27     0,7   29     0,1   30    -1,7   01    -4,9   12/02
    Alt Camp         DQ   Vila-rodona                   -0,5   30    -4,5   03     1,3   07     3,4   17    5,5   02   13,0   14   12,8   02   14,6   31    8,9   27     2,6   28     0,2   30     0,6   12    -4,5   03/02
    Alt Empordà      U1   Cabanes                       -3,0   15    -6,0   09    -0,3   02     2,9   25    3,6   01   12,2   11   10,5   24   12,6   27    6,6   27     2,8   30     2,0   30    -4,3   12    -6,0   09/02
    Alt Empordà      W1   Castelló d'Empúries           -2,7   15    -6,2   09     0,3   02     3,2   07    6,0   01   12,1   16   11,1   24   13,3   27    7,5   27     0,7   30     2,2   23    -3,7   12    -6,2   09/02
    Alt Empordà      VZ   Espolla                       -1,8   15    -6,8   09     1,5   19     2,9   07    5,7   01   12,2   12   10,3   24   13,7   07    7,6   20     2,5   30     2,5   07    -4,8   12    -6,8   09/02
    Alt Empordà      D6   Portbou                        1,7   29    -4,5   04     4,8   06     3,3   16    9,4   01   12,6   11   13,3   01   15,3   06   12,4   26     4,7   28     4,0   30     1,4   12    -4,5   04/02
    Alt Empordà      D4   Roses                         -1,6   15    -4,2   09     2,9   16     4,6   07    7,0   01   13,5   12   13,5   24   15,7   27    8,7   27     2,1   30     3,5   23    -2,5   12    -4,2   09/02
    Alt Empordà      U2   Sant Pere Pescador            -3,5   15    -6,1   09    -0,2   02     2,6   07    5,8   01   10,3   12    9,6   24   12,7   27    8,0   27    -0,2   30     1,9   23    -3,5   12    -6,1   09/02
    Alt Empordà      W2   Torroella de Fluvià           -4,0   15    -6,7   09    -1,3   02     1,6   07    3,4   02    9,5   12    9,5   24   12,6   27    6,4   27    -0,6   30     0,9   30    -4,2   12    -6,7   09/02
    Alt Empordà      W3   Ventalló                      -5,0   15    -6,8   09    -0,7   02     1,9   07    4,3   01   10,2   12   10,6   24   12,5   27    6,9   27    -0,7   30    -0,8   30    -5,2   12    -6,8   09/02
    Alt Penedès      WP   Canaletes                     -1,0   14    -5,3   12     1,6   07     3,1   17    5,7   03   11,2   13   12,1   02   13,7   31    9,0   27     1,8   29    -0,8   30    -0,6   02    -5,3   12/02
    Alt Penedès      DI   Font-rubí                     -1,1   29    -4,9   12     2,0   08     4,4   17    6,9   01   11,6   09   11,8   02   15,1   31   10,0   26     0,3   29    -0,3   30    -0,3   02    -4,9   12/02
    Alt Penedès      W4   la Granada                    -0,9   31    -5,4   13     1,0   07     3,7   17    5,9   01   11,1   13   12,1   02   13,5   31    9,0   26     1,7   29    -0,9   30    -0,3   02    -5,4   13/02
    Alt Penedès      U3   Sant Martí Sarroca            -4,1   14    -7,2   13    -0,3   08     3,0   07    4,6   03   11,2   12   11,4   02   13,2   31    8,2   26    -0,6   29    -1,1   30    -4,3   02    -7,2   13/02
    Alt Penedès      WY   Sant Sadurní d'Anoia          -2,7   31    -5,7   13    -0,3   08     2,4   07    4,7   01   10,7   12   12,0   02   13,8   31    8,0   27     1,6   30    -2,2   30    -2,8   02    -5,7   13/02
    Alt Urgell       CD   la Seu d'Urgell               -6,9   15   -10,7   12    -4,6   06    -1,5   17    2,1   01    6,3   12    7,5   02    7,2   31    3,1   27    -3,0   29    -4,0   30    -8,4   12   -10,7   12/02
    Alt Urgell       W5   Oliana                        -6,6   31   -12,0   12    -4,3   08    -1,1   14    1,4   01    7,8   12    9,6   02   11,2   26    7,4   26    -3,1   29    -4,5   30    -6,8   10   -12,0   12/02
    Alt Urgell       CJ   Organyà                       -8,2   14    -8,8   05    -2,4   19    -0,9   20    1,1   01    6,6   12    9,9   02   10,4   31    5,6   27    -2,2   30    -1,7   30    -7,8   12    -8,8   05/02
    Alta Ribagorça   Z2   Boí (2.535 m)                -14,3   29   -23,0   03   -13,6   06   -11,5   16   -7,2   01   -1,8   12    0,7   01   -2,0   31   -3,5   26   -14,2   28   -12,9   29   -11,5   06   -23,0   03/02
    Alta Ribagorça   CT   el Pont de Suert             -10,3   15   -11,8   21    -6,4   07    -3,4   17   -0,1   01    3,5   12    5,4   15    5,2   31    1,5   27    -4,9   29    -6,7   30    -9,6   12   -11,8   21/02
    Anoia            CE   els Hostalets de Pierola      -2,0   14    -5,1   13     1,3   07     3,4   17    5,8   01   12,4   12   12,2   02   13,1   31   10,0   27     1,2   29    -0,2   30    -1,9   02    -5,1   13/02
    Anoia            XB   la Llacuna                    -6,2   14    -8,2   12    -2,8   07     1,1   17    2,4   03    6,4   13    9,8   24   10,2   31    5,0   27    -1,5   29    -3,2   30    -3,9   01    -8,2   12/02
    Anoia            XA   la Panadella                  -3,9   30   -10,1   03    -2,2   06    -1,4   17    4,2   01    8,3   12    8,5   02    9,5   31    7,5   27    -1,2   28    -2,0   30    -4,4   02   -10,1   03/02
    Anoia            H1   Òdena                         -5,6   14    -8,7   13    -4,2   07     0,3   17    2,3   01    7,9   13   10,4   02   12,2   31    5,0   27    -0,7   30    -3,3   30    -4,8   02    -8,7   13/02
    Bages            WW   Artés                         -5,9   14   -10,3   11    -4,9   06    -2,1   17    2,2   01    9,0   12   10,4   24   10,6   31    5,0   27    -2,6   29    -5,0   30    -5,6   02   -10,3   11/02
    Bages            U4   Castellnou de Bages           -5,5   14    -7,5   03    -1,7   06     1,3   17    3,8   01    9,6   12   11,3   02   11,6   31    6,7   27    -0,3   29    -2,9   30    -3,8   02    -7,5   03/02
    Bages            R1   el Pont de Vilomara           -5,3   14    -9,6   13    -3,0   07    -0,6   17    2,9   01    9,6   13   11,3   02   12,3   31    6,0   27    -1,2   29    -3,4   30    -5,0   02    -9,6   13/02
    Bages            WN   Montserrat - Sant Dimes       -0,3   29    -7,4   12     0,4   19     1,8   17    5,3   21    9,5   12    9,5   02   11,5   31    8,6   26     2,4   29    -0,1   30    -1,0   06    -7,4   12/02
    Bages            CL   Sant Salvador de Guardiola    -6,3   30   -10,1   13    -4,2   07     0,3   17    1,6   01    7,8   13    9,9   24    9,9   31    4,7   27    -1,5   30    -5,0   30    -6,4   02   -10,1   13/02
    Baix Camp        U5   Prades - los Hortals          -6,6   30   -12,9   12    -5,8   09    -2,7   17    0,7   01    6,8   09    4,9   02    7,8   31    3,8   02    -3,1   29    -5,0   30    -6,6   01   -12,9   12/02
    Baix Camp        W6   Riudoms                        0,0   13    -3,2   03     2,7   01     4,9   07    6,3   01   13,9   13   14,8   02   16,1   31   10,7   26     4,1   28     3,7   30     1,6   10    -3,2   03/02
    Baix Camp        U6   Vinyols i els Arcs            -1,1   15    -2,1   03     1,9   15     4,7   07    6,9   01   15,6   02   15,1   01   17,3   31   11,7   26     6,4   28     4,6   30     2,4   10    -2,1   03/02
    Baix Ebre        U7   Aldover                        0,4   31    -2,0   03     3,7   01     4,0   07    6,6   01   13,4   09   14,8   02   17,1   31   12,2   27     4,5   30     3,7   30     1,0   10    -2,0   03/02
    Baix Ebre        DB   el Perelló                    -0,2   15    -2,8   03     3,2   07     6,0   17    7,4   01   15,5   09   15,3   02   16,9   31   12,0   29     5,0   30     3,5   30     1,7   01    -2,8   03/02
    Baix Ebre        U9   l'Aldea                       -1,3   13    -1,2   04     3,5   01     5,2   07    7,1   01   14,3   09   15,5   01   18,2   31   11,4   27     6,0   30     5,6   30     0,6   10    -1,3   13/01
    Baix Ebre        UA   l'Ametlla de Mar               1,1   15    -2,2   03     4,5   23     5,0   07    6,6   01   14,9   09   15,2   01   17,1   31   11,7   27     4,8   30     4,1   30     2,4   12    -2,2   03/02
    Baix Ebre        X5   PN dels Ports                 -4,5   30   -11,3   04    -4,0   07    -2,8   17    0,2   01    5,8   09    7,4   01    8,0   31    4,8   27    -2,6   29    -4,6   30    -5,8   01   -11,3   04/02
    Baix Empordà     DO   Castell d'Aro                 -1,7   15    -7,4   05    -0,4   06     2,2   17    4,9   01   11,2   12   12,1   24   13,6   31    9,1   27    -0,7   29    -1,5   30    -3,0   12    -7,4   05/02
    Baix Empordà     DF   la Bisbal d'Empordà                    -3,2   15    -6,8   12    -2,4   06    0,5   17    4,6   01   11,1   12   10,3   24   11,6   31    7,7   27    -1,0   29    -2,2   30    -4,2   12    -6,8   12/02
    Baix Empordà     UB   la Tallada d'Empordà                   -4,1   15    -7,1   12    -2,0   06    1,8   17    4,8   01   11,9   12   10,8   24   12,4   31    7,2   27    -0,5   30    -2,2   30    -5,1   12    -7,1   12/02
    Baix Empordà     UC   Monells                                -3,7   15    -8,0   13    -3,2   06   -1,2   17    2,7   01   10,5   13   10,5   24    8,8   31    6,2   27    -2,1   29    -2,5   30    -4,8   12    -8,0   13/02
    Baix Empordà     UD   Serra de Daró                          -3,2   15    -6,8   12    -1,7   06    0,9   17    4,6   01   11,7   12   10,1   24   11,5   31    7,3   27     0,5   30    -1,7   30    -3,8   12    -6,8   12/02
    Baix Empordà     UE   Torroella de Montgrí                   -1,8   15    -5,6   12    -1,1   02    2,5   07    5,5   01   12,6   12   11,8   24   14,3   27    8,4   27     1,0   30    -0,5   30    -3,4   12    -5,6   12/02
    Baix Llobregat   UF   Begues - PN del Garraf                  0,1   29    -5,8   04     2,5   06    3,1   17    6,4   21   11,8   12   12,3   01   14,2   31   10,1   26     1,8   28     0,1   30    -0,4   02    -5,8   04/02
    Baix Llobregat   XL   el Prat de Llobregat                    0,6   30    -4,6   05     2,1   06    5,5   07    8,5   01   12,4   12   14,8   02   16,8   31    9,9   26     3,3   29     1,9   30     0,9   09    -4,6   05/02
    Baix Llobregat   D3   Vallirana                               0,6   29    -3,1   03     4,1   07    5,4   17    6,7   01   12,9   12   13,9   02   15,9   31   11,3   27     4,7   29     1,9   30     0,4   01    -3,1   03/02
    Baix Llobregat   UG   Viladecans                              1,2   30    -4,1   05     3,8   08    6,2   11    8,4   01   15,0   16   15,4   02   17,5   31   12,1   26     4,2   29     2,2   30     1,1   02    -4,1   05/02
    Baix Penedès     WZ   Cunit                                  -1,9   30    -4,7   13     3,1   10    2,2   17    7,1   01   13,0   12   13,5   02   14,4   31   11,3   26     1,8   29     1,4   30    -1,6   02    -4,7   13/02
    Baix Penedès     UH   el Montmell                            -0,7   29    -4,7   03     1,9   07    3,9   17    5,4   01   11,4   12   10,0   01   13,8   31    9,8   27     1,5   29     0,4   30     0,4   02    -4,7   03/02
    Baix Penedès     D9   el Vendrell                            -1,4   30    -4,2   12     1,2   10    5,3   07    6,4   02   12,9   12   13,2   02   17,7   08   10,7   26     4,3   29     1,1   30     0,1   11    -4,2   12/02
    Baix Penedès     WO   la Bisbal del Penedès                  -5,4   14    -5,9   13    -1,3   10    4,5   02    3,8   01   11,6   15   12,9   24   14,6   08    7,0   27     0,9   30    -2,1   30    -2,9   01    -5,9   13/02
    Barcelonès       WU   Badalona - Museu                        2,2   14    -0,8   04     4,9   07    6,7   17    9,9   01   16,7   12   15,9   02   17,2   31   14,2   27     5,6   29     2,9   30     2,4   02    -0,8   04/02
    Barcelonès       X4   Barcelona - el Raval                    5,5   30     0,6   04     7,9   09    9,1   17   11,6   01   17,6   12   16,6   01   19,4   30   16,3   29     7,6   29     5,6   30     4,5   02     0,6   04/02
    Barcelonès       D5   Barcelona - Observatori Fabra           1,0   30    -4,7   03     4,5   07    4,5   17    7,7   21   12,7   12   13,4   02   15,2   31   12,4   27     3,2   28     1,9   30     0,5   02    -4,7   03/02
    Barcelonès       X8   Barcelona - Zona Universitària          1,9   14    -1,8   04     4,8   06    6,1   17    7,6   01   14,5   12   14,6   01   16,8   31   13,3   27     5,4   29     2,3   30     2,1   02    -1,8   04/02
    Barcelonès       X2   Barcelona - Zoo                         3,1   13    -2,3   05     5,1   10    8,5   07   10,1   01   15,9   12   16,6   02   18,0   31   14,8   02     6,8   29     4,3   30     2,2   02    -2,3   05/02
    Berguedà         UI   Gisclareny                             -5,1   16   -12,5   04    -4,1   05   -2,7   17   -0,6   01    5,7   13    7,4   02    6,1   31    3,2   26    -2,8   29    -5,1   30    -5,6   12   -12,5   04/02
    Berguedà         WV   Guardiola de Berguedà                  -7,4   14   -11,7   12    -5,8   07   -2,9   14    0,6   02    5,7   12    6,3   02    6,3   31    0,9   27    -4,4   30    -5,7   30    -8,4   01   -11,7   12/02
    Berguedà         CR   la Quar                                -3,5   29   -11,5   12    -1,8   07   -2,3   17    1,2   01    5,7   12   10,0   15    8,9   31    5,0   27    -1,9   29    -2,7   30    -4,7   01   -11,5   12/02
    Berguedà         WM   Santuari de Queralt                    -2,4   29    -9,1   04    -0,8   06   -0,2   11    2,9   01    6,2   12    9,2   02    9,7   31    7,2   26    -1,0   28    -1,3   30    -2,8   12    -9,1   04/02
    Cerdanya         Z9   Cadí Nord (2.143 m) - Prat d'Aguiló   -11,5   30   -19,6   03   -10,4   06   -9,0   17   -4,5   01    1,8   12    2,9   01    0,9   31   -1,0   26   -10,5   28   -11,4   30    -9,2   02   -19,6   03/02
    Cerdanya         DP   Das                                   -12,9   14   -16,6   12    -9,7   10   -5,5   14   -2,2   14    0,6   12    2,3   02    3,6   27   -2,8   27    -6,9   30    -8,3   30   -13,5   12   -16,6   12/02
    Cerdanya         Z3   Malniu (2.230 m)                      -12,2   29   -20,6   03   -10,7   06   -9,6   16   -5,4   01    0,4   12    2,9   01   -0,2   31   -0,4   27   -12,1   28   -11,3   30    -9,1   02   -20,6   03/02
    Conca de B.      W8   Blancafort                             -3,1   19    -8,2   11    -2,8   07    1,9   17    2,9   01   10,7   13   11,8   02   12,5   31    6,2   27    -0,3   30    -1,2   30    -3,1   11    -8,2   11/02
    Conca de B.      CW   l'Espluga de Francolí                  -2,0   16    -5,9   04    -0,9   07    2,5   17    2,8   01   11,5   04   10,4   02   13,2   31    6,5   27    -0,3   30    -1,0   30    -3,2   12    -5,9   04/02
    Conca de B.      UJ   Santa Coloma de Queralt                -3,4   14    -8,9   03    -1,1   07   -0,4   17    3,4   01    8,3   13    9,2   02   10,7   31    6,7   27    -0,3   28    -1,6   30    -3,4   02    -8,9   03/02
    Garraf           UK   Sant Pere de Ribes - PN del Garraf     -0,3   29    -3,8   04     2,8   06    4,2   17    7,1   01   12,9   12   12,4   02   13,2   31   12,0   27     2,6   29     0,3   30     0,2   02    -3,8   04/02
    Garrigues        UL   Castelldans                            -4,9   26    -7,0   06    -1,9   10    1,7   07    3,2   01   11,5   15   12,8   03   13,6   31    5,8   27    -0,5   30    -1,5   30    -5,1   12    -7,0   06/02
    Garrigues        UM   la Granadella                          -3,4   11    -7,6   03    -2,5   10    0,6   17    2,7   01   10,9   13   10,8   02   11,5   31    6,2   02     1,1   29    -0,9   30    -3,4   12    -7,6   03/02
    Garrotxa         W9   la Vall d'en Bas                       -6,3   14   -10,9   13    -5,8   07   -2,2   17    1,7   01    8,8   12    6,7   24    8,5   31    4,3   27    -4,3   29    -5,0   30    -6,6   09   -10,9   13/02
    Garrotxa         DC   Olot                                   -4,9   15    -9,9   12    -3,6   07   -1,8   17    2,6   01    9,0   12    9,9   24    9,6   31    5,5   27    -3,3   29    -3,9   30    -5,9   12    -9,9   12/02
    Gironès          UN   Cassà de la Selva                      -4,2   15   -10,7   05    -3,0   06    0,5   17    1,9   01    8,8   12   11,0   24   10,5   31    6,7   27    -3,2   29    -4,4   30    -5,3   12   -10,7   05/02
    Gironès          UO   Fornells de la Selva                   -5,8   15   -10,4   13    -4,9   07   -1,5   17    2,2   01    9,3   12    9,2   24   10,3   31    6,1   27    -3,5   29    -4,3   30    -6,3   12   -10,4   13/02
    Gironès          XJ   Girona                                 -5,1   15    -9,6   13    -4,0   07   -1,6   17    3,1   01   10,2   12    9,7   24   10,4   31    5,7   27    -3,1   29    -3,8   30    -5,7   12    -9,6   13/02
    Gironès          WF   Vilablareix                            -5,2   15    -9,9   13    -4,3   07   -1,7   17    3,0   02    9,0   12    9,7   24   11,7   31    5,7   27    -2,8   29    -2,8   30    -4,6   12    -9,9   13/02
    Maresme          UP   Cabrils                                 1,6   30    -2,6   11     3,2   07    6,7   17    8,5   01   13,9   12   15,1   02   15,9   31   13,3   26     3,7   28     3,0   30     2,6   12    -2,6   11/02
    

    如果您知道如何正确操作文本编辑器,则可以非常轻松快速地修复此文本输出,以便Excel可以顺利导入...