Как сделать PDF с помощью Perl - PullRequest
1 голос
/ 14 января 2012

Возможно ли сделать PDF в браузере, используя PERL?У меня есть флэш-приложение, которое отправляет визуализированный PDF-файл в Perl.PDF создается из AlivePDF.

#!C:\Perl\bin\perl.exe
##
BEGIN { $ENV{PATH} = ''; delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; }
use strict;
use warnings;
no warnings qw (redefine closure);
use CGI;
my $CGI = new CGI();

#name=generated.pdf&method=inline these are passed via the URL and are in the environmental variable QUERY_STRING
my %nv_pairs = map{my @tmp = split(/=/,$_);$tmp[0] => $tmp[1] }split(/&/,$ENV{QUERY_STRING});
my $name = $nv_pairs{name};
my $method = $nv_pairs{method};

#Raw Data is stored in the POST Parameter POSTDATA
my $pdf = $CGI->param('POSTDATA');

print "Content-Type: application/pdf\r\n";
print "Content-Length: " . length($pdf) . "\r\n";
print "Content-Disposition :$method\n\n";
print $pdf;

Проблема заключается в том, что я хочу на самом деле визуализировать, как будет выглядеть PDF.Я могу сохранить этот двоичный код и открыть его вручную в Adobe Reader, и он будет правильно отображаться.

Я хотел бы, чтобы он отображался в браузере, но я не знаю, как его получить.

В настоящее время вывод (отображаемый браузером) выглядит следующим образом:

Content-Type: application/pdf
Content-Length: 432785
Content-disposition:inline; filename="test.pdf"

%PDF-1.5
1 0 obj
<</Type /Pages
/Kids [3 0 R 5 0 R]
/Count 2>>
endobj
3 0 obj
<</Type /Page
/Parent 1 0 R
/MediaBox [0 0 612.00 792.00]
/Resources 2 0 R

Это только часть отображаемого файла, но я надеюсь, что это поможет.Я не хочу, чтобы код отображался, я хочу, чтобы он выглядел графически.Если я загружаю этот файл и изменяю расширение на .pdf, он отлично работает.

Ответы [ 2 ]

0 голосов
/ 15 января 2012

У меня нет приложения Flash, которое создает PDF в теле запроса, но я проверил его по выходу статического ресурса с такими же заголовками ответа. Content-Disposition является решающим. Это было протестировано в Konqueror с Okular KPart и работает, я полностью ожидаю, что другие комбинации браузеров / плагинов также будут работать.

#!/usr/bin/perl -T
# ↑↑↑↑↑
# on Windows you can just write …
#!perl -T
# … instead, using the Unix shebang however does no harm
use strict;
use warnings FATAL => 'all';
use CGI qw();
use IO::File qw();

# delete @ENV{qw(BASH_ENV CDPATH ENV IFS PATH)};
# ↑↑↑↑↑
# Cleaning path is required for taint-checked programs
# that want to run other programs. It does not affect anything here,
# so I commented it out.

my $c = CGI->new;

# untaint data coming from outside
my ($name) = defined $c->url_param('name') ?
    $c->url_param('name') =~ /\A ([a-zA-Z_-]{1,40}\.pdf) \z/msx : ();
my ($method) = defined $c->url_param('method') ?
    $c->url_param('method') =~ /\A (attachment|inline) \z/msx : ();
die 'invalid parameters' unless $name or $method;

# FIXME: untaint blindly because I don't know how to validate PDF
my ($pdf) = $c->param('POSTDATA') =~ /(.*)/msx;

STDOUT->binmode(':raw');
STDOUT->print($c->header(
    -Content_Type        => 'application/pdf',
    -Content_Length      => length($pdf),
    -Content_Disposition => qq($method; filename="$name"),
));
STDOUT->print($pdf);

Имейте в виду, что вы смешиваете параметры GET и POST . Узнайте, как писать безопасные программы CGI.

0 голосов
/ 14 января 2012

Вам необходимо добавить следующий HTTP-заголовок

print "Content-Transfer-Encoding: binary\n";

Следующее работает для меня, чтобы прочитать PDF-файл и отобразить его:

use strict;
use warnings;

my $file = "discover.pdf"; # a pdf I happen to have
my $pdf;

open (my $fh, $file);
binmode $fh; # set the file handle to binary mode
while (<$fh>){ $pdf .= $_; } # read it all into a string;
close ($fh);

showPdf($pdf); # call the display function

sub showPdf {

        my $pdf = shift;
        my $file = shift || "new.pdf"; # if no name is given use this
        my $method = shift || "Content-disposition:inline; filename='$file'"; # default method
        my $size = length($pdf);

        print "Content-Type: application/pdf\n";
        print "Content-Length: $size\n";
        print "$method\n";
        print "Content-Transfer-Encoding: binary\n\n"; # blank line to separate headers

        print $pdf;

}

Та же функция может быть добавлена ​​к исходному коду и должна работать следующим образом:

#!C:\Perl\bin\perl.exe
##
BEGIN { $ENV{PATH} = ''; delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; }
use strict;
use warnings;
no warnings qw (redefine closure);
use CGI;
my $CGI = new CGI();

#name=generated.pdf&method=inline these are passed via the URL and are in the environmental variable QUERY_STRING
my %nv_pairs = map{my @tmp = split(/=/,$_);$tmp[0] => $tmp[1] }split(/&/,$ENV{QUERY_STRING});
my $name = $nv_pairs{name};
my $method = $nv_pairs{method};

#Raw Data is stored in the POST Parameter POSTDATA
my $pdf = $CGI->param('POSTDATA');

showPdf($pdf, $name, $method);

sub showPdf {

    my $pdf = shift;
    my $file = shift || "new.pdf"; # if no name is given use this
    my $method = shift || "Content-disposition:inline; filename='$file'"; # default method
    my $size = length($pdf);

    print "Content-Type: application/pdf\n";
    print "Content-Length: $size\n";
    print "$method\n";
    print "Content-Transfer-Encoding: binary\n\n"; # blank line to separate headers

    print $pdf;

}
...