PDFJとCGIとUTF8

Linux

はじめに

PerlでPDFJを使ってCGIでPDF(UTF8)を表示させるスクリプトです。
なお、PDFJをPerl5.10で動かすため、patchをあてています。
【追記 2012.12.20】
「CGI.pm」を使ってPDFを出力するように修正。

環境

・Debian squeeze
・Perl 5.10.1
・PDFJ 0.90
・PDFJ 0.90用のPerl 5.10対応patch
・Apache 2.2.16

Perl5.10対応patch

参考文献

http://support.microsoft.com/kb/436605/ja

動作した組み合わせ

・WindowsXP Pro SP3
・Adobe Acrobat Reader X (10.1.2)
・Internet Explorer 8.0.6001.18702

・WindowsXP Pro SP3
・Adobe Acrobat Reader X (10.1.2)
・Firefox 11 beta

・WindowsXP Pro SP3
・Adobe Acrobat Reader X (10.1.2)
・Firefox 10

・WindowsXP Pro SP3
・Adobe Acrobat Reader X (10.1.2)
・Safari 5.1.1

・WindowsXP Pro SP3
・Adobe Acrobat Reader X (10.1.2)
・Goole Chrome 17.0.963.46

・WindowsXP Pro SP3
・Adobe Acrobat Reader X (10.1.2)
・Opera 11.61

CGIサンプル

サンプルと同じ階層に「lib」ディレクトリを作って、その中にPDFJを入れておく。
「use CGI::Carp qw(carpout fatalsToBrowser);」は不要ならば削除する。

使用しているサーバの仕様が貧弱(Pentium4 3.0GHz)のせいか、日本語フォントを埋め込みにするとPDF生成、ブラウザ表示にかなり時間がかかる。また、PDFのサイズが増大する。
仕方がないので、現在は標準のフォントを使用している。

UTF8のエンコーディングはPDFJのソースを見る限り「UniJIS-UCS2-HW-H」しか対応してなさそう。
実際にこれ以外を指定してもエラーになる。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use lib './lib';
use PDFJ 'UTF8';
use CGI::Carp qw(carpout fatalsToBrowser);

{
    # 幅と高さはポイントで指定する。
    my $font;
    my $fontsize;
    my $fontstyle;
    my $text;
    my $textstyle;
    my $page;
    my $pagestyle;
    my $para;
    my $doc;
    my $obj;
    my $shapeobj;
    my $data;
    my @object     = ();
    my @pagesize   = ('595', '842');           # A4(210mm, 297mm) 単位[point]
    my @margin     = ('72', '72', '72', '72'); # 余白(左・右・上・下)
    my $pageheight = $pagesize[1] - $margin[2] - $margin[3];
    my $pagewidth  = $pagesize[0] - $margin[0] - $margin[1];
    my @posbody    = ($margin[0], $pagesize[1] - $margin[3]);
    my @posheader  = ($margin[0], $pagesize[1] - $margin[3] + $margin[2] / 2);
    my @posfooter  = ($margin[0], $margin[3] / 2);
    my @line       = ($margin[0], $pagesize[1] - $margin[3], $pagewidth, 0, '');
    my $code       = 'UniJIS-UCS2-HW-H';
    my $code_e     = 'WinAnsiEncoding';
    my $gothic;
    my $mincho;
    my $gothic_e;
    my $mincho_e;

    $gothic   = 'GothicBBB-Medium';
    $mincho   = 'Ryumin-Light';
    # $gothic   = '/usr/share/fonts/truetype/kochi/kochi-gothic.ttf';
    # $mincho   = '/usr/share/fonts/truetype/kochi/kochi-mincho.ttf';
    # $gothic   = '/usr/share/fonts/truetype/sazanami/sazanami-gothic.ttf';
    # $mincho   = '/usr/share/fonts/truetype/sazanami/sazanami-mincho.ttf';
    $gothic_e = 'Helvetica';
    $mincho_e = 'Helvetica';
    # $mincho_e = 'Courier';

    # PDF 1.2(Acrobat3)
    # PDF 1.3(Acrobat4)
    # PDF 1.4(Acrobat5)
    # PDF 1.5(Acrobat6)
    # PDF 1.6(Acrobat7)
    $doc = new PDFJ::Doc( 1.3, $pagesize[0], $pagesize[1] );

    # Compress::Zlibを使わずにデータの埋め込みを行う
    $doc->filter('a');

    # タイトル
    $font      = $doc->new_font( $gothic, $code, $gothic_e, $code_e );
    $fontsize  = 24;
    $textstyle = TStyle( font => $font, fontsize => $fontsize );
    $text      = Text( "FAX送信", $textstyle );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', preskip => 0, postskip => 10, align => 'm' );
    push @object, Paragraph( $text, $pagestyle );

    # 直線
    push @object, Shape()->line( 0, 0, 460, 0, SStyle( linewidth => 2 ) );

    # 発信元
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', preskip => 10, postskip => 4, align => 'b' );
    $font      = $doc->new_font( $mincho, $code, $gothic_e, $code_e );
    $fontsize  = 12;
    $textstyle = TStyle( font => $font, fontsize => $fontsize );

    $data = "【ふふふのふ】";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', preskip => 0, postskip => 4, align => 'b' );

    $data = "xxxx";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "xxx 様";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "TEL xxxx-xx-xxxx";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "FAX oooo-oo-oooo";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "【送付先】";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', preskip => 0, postskip => 4, align => 'b' );

    $data      = "にゃにゃん";
    $text      = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    # 直線
    push @object, Shape()->line( 0, 0, 460, 0, SStyle( linewidth => 1 ) );

    # 差出人
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', preskip => 10, postskip => 4, align => 'b' );
    $font     = $doc->new_font( $mincho, $code, $gothic_e, $code_e );
    $fontsize  = 12;
    $textstyle = TStyle( font => $font, fontsize => $fontsize );

    $data = "【ほにゃらら】";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', preskip => 0, postskip => 4, align => 'b' );

    $data = "○×部署";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "ななしのたろー";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "TEL xxxx-xx-xxxx";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $data = "FAX oooo-oo-oooo";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    # 直線
    push @object, Shape()->line( 0, 0, 460, 0, SStyle( linewidth => 2, preskip => 20 ) );

    # 挨拶文
    $font     = $doc->new_font( $mincho, $code, $gothic_e, $code_e );
    $fontsize  = 12;
    $textstyle = TStyle( font => $font, fontsize => $fontsize );

    # 改行
    push @object, Text( NewLine(), $textstyle );

    $data = "いつもお世話になっております。";
    $text = Text( $data, $textstyle );
    @object, Paragraph( $text, $pagestyle );

    $data = "PDFJのテストです。";
    $text = Text( $data, $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $font      = $doc->new_font( $mincho, $code, $gothic_e, $code_e );
    $fontsize  = 12;
    $textstyle = TStyle( font => $font, fontsize => $fontsize );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', postskip => 2, align => 'b' );

    # 改行
    push @object, Text( NewLine(), $textstyle );

    $text = Text( "ほにゃにゃ:" . "猫", $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $text = Text( " にゃにゃ:" . "犬", $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    $text = Text( "  にゃ:" . "古荒", $textstyle );
    push @object, Paragraph( $text, $pagestyle );

    # 改行
    push @object, Text( NewLine(), $textstyle );

    # 出力
    for my $block( Block('V', @object, BStyle() )->break( $pageheight ) )
    {
    # 新規ページ
    my $page = $doc->new_page;

    # 本文の表示
    $block->show( $page, @posbody );

    # ヘッダ
    $fontsize  = 9;
    $font      = $doc->new_font( $gothic, $code, $gothic_e, $code_e );
    $textstyle = TStyle( font => $font, fontsize => $fontsize );

    $text      = Text( scalar(localtime) . "(FAX:" . "xxxx-xx-xxxx)", $textstyle );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', align => 'e' );

    my $header = Paragraph( $text, $pagestyle );
    $header->show( $page, @posheader );

    # フッタ
    $text      = Text( "- " . $page->pagenum . " -", $textstyle );
    $pagestyle = PStyle( size => $pagewidth, linefeed => '100%', align => 'm' );

    my $footer = Paragraph( $text, $pagestyle );
    $footer->show($page, @posfooter);
}

#
# use CGI.pm
#
use CGI;
my $q = new CGI;
print $q->header(
    -type => 'application/pdf',
);
$doc->print('-');
exit;

#
# old
#
# PDF出力・サイズ取得
my $pdfname = "pdf$$.pdf";
my $pdfpath = "./$pdfname";
$doc->print("$pdfpath");
my $pdfsize = -s $pdfpath;

# データの表示形式(inline or attachment)
my $format = 'inline';

# 標準出力
print <<"EOF";
Content-type: application/pdf
Content-Disposition: $format; filename="$pdfname"
Content-length: $pdfsize
Content-Transfer-Encoding: binary

EOF

# バイナリモードで開いて出力する
open my $fh, '<', $pdfpath || die "can't open $pdfname";
binmode $fh;
binmode STDOUT;
while ( <$fh> )
{
    print $_;
}
close $fh;

# PDF削除
# unlink $pdfpath;

exit;
}
created by Rinker
¥3,960 (2024/07/06 15:43:54時点 楽天市場調べ-詳細)

Comments