source: branches/comu-ver2/data/class/SC_Pdf.php @ 16741

Revision 16741, 16.3 KB checked in by adachi, 15 years ago (diff)

set eol-style:LF

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2007 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/*----------------------------------------------------------------------
25 * [名称] GC_Pdf
26 * [概要] Pdfファイルを表示する。(PDFLib必須)
27 *----------------------------------------------------------------------
28 */
29
30// グリッドと文字の間隔
31define("GRID_SPACE", 4);
32
33class SC_Pdf {
34    var $arrText;
35    var $arrImage;
36    var $license_key;
37    var $block_option;
38    var $src_code;
39    var $dst_code;
40    var $pdiwarning;
41    var $pdfpath;
42    var $page_close;
43           
44    function SC_Pdf($width = 595, $height = 842, $fontsize = 10) {
45        $this->license_key = "B600602-010400-714251-5851C1";
46        $this->src_code = CHAR_CODE;
47        // UTF-8でないとブロック内で改行できない。
48        $this->dst_code = "UTF-8";
49        // PDF BLOCKのプロパティ
50        $this->block_option = "encoding=UniJIS-UCS2-H textformat=utf8 fontname=HeiseiMin-W3 textflow=true";
51        // 警告表示
52        $this->pdiwarning = "true";
53        // ページサイズ設定
54        $this->width = $width;
55        $this->height = $height;
56        // PDF初期化
57        $this->pdf = PDF_new();
58        PDF_set_parameter($this->pdf, "license", $this->license_key);
59        PDF_set_parameter($this->pdf, "pdiwarning", $this->pdiwarning);
60        // ドキュメント開始
61        PDF_begin_document($this->pdf, NULL, NULL);
62        // ページの状態
63        $this->page_open = false;
64        // テーブルの色設定
65        $this->setTableColor();
66        // フォントサイズの設定
67        $this->fontsize = $fontsize;
68        // グリッド描画の特殊指定
69        $this->arrLines = array();
70        // テーブルタイトルのスタイル
71        $this->arrHeaderColSize = array();
72        $this->arrHeaderAlign = array();
73        // テーブル補正値
74        $this->table_left = 0;
75        // タイトル行の出力
76        $this->title_enable = true;
77        // グリッドの出力
78        $this->grid_enable = true;
79    }
80   
81    // タイトルを出力するか否か
82    function setTitleEnable($flag) {
83        $this->title_enable = $flag;
84    }
85   
86    // グリッドを出力するか否か
87    function setGridEnable($flag) {
88        $this->grid_enable = $flag;
89    }
90       
91       
92    // キー:ブロック名、値:表示テキストのハッシュ配列をセットする。
93    function setTextBlock($list) {
94        unset($this->arrText);
95        $this->arrText[] = $list;
96    }
97   
98    // キー:ブロック名、値:ファイルパスのハッシュ配列をセットする。
99    // ※パスはドキュメントルート以下
100    function setImageBlock($list) {
101        unset($this->arrImage);
102        $this->arrImage[] = $list;
103    }
104   
105    // 表示背景となるテンプレートファイルパス
106    // ※パスはドキュメントルート以下
107    function setTemplate($pdfpath) {
108        if(file_exists($pdfpath)) {
109            $this->pdfpath = $pdfpath;
110        } else {
111            print("指定したPDFテンプレートは存在しません:".$pdfpath);
112            exit;
113        }
114    }
115   
116    // テーブル位置補正値
117    function setTableLeft($table_left) {
118        $this->table_left = $table_left;
119    }
120   
121    // グリッド描画の特殊指定
122    function setGridLines($list) {
123        $this->arrLines = $list;
124    }
125   
126    // テーブルタイトルのスタイル設定
127    function setTableHeaderStyle($arrColSize, $arrAlign) {
128        $this->arrHeaderColSize = $arrColSize;
129        $this->arrHeaderAlign = $arrAlign;
130    }
131   
132    // ブロックデータの書き込み(closeすると次回新規ページ)
133    function writeBlock() {
134        // テンプレートを使用する
135        if(!file_exists($this->pdfpath)) {
136            return;
137        }
138        // 既存PDFのドキュメントを取得
139        $doc = pdf_open_pdi($this->pdf, $this->pdfpath, NULL, 0 );
140        // 既存PDFのドキュメントから指定ページを取得
141        $page = pdf_open_pdi_page($this->pdf, $doc, 1, NULL );
142        // ページを開く
143        $this->openPage();
144       
145        // 既存PDFのページを割り当てる
146        PDF_fit_pdi_page($this->pdf, $page, 0, 0, "adjustpage");
147       
148        // テキストブロックの書き込み
149        $max = count($this->arrText);
150        for($i = 0;$i < $max; $i++) {
151            foreach($this->arrText[$i] as $key => $val) {
152                if($val != "") {
153                    // 文字コードの変換
154                    mb_convert_variables($this->dst_code, $this->src_code, $val);
155                    // 書き込み
156                    $ret = PDF_fill_textblock($this->pdf, $page, $key, $val, $this->block_option);
157                }
158            }
159        }
160       
161        // イメージブロックの書き込み
162        $max = count($this->arrImage);
163        for($i = 0;$i < $max; $i++) {
164            foreach($this->arrImage[$i] as $key => $val) {
165                if($val != "") {
166                    $img = PDF_load_image($this->pdf, "auto", $val, NULL );
167                    $ret = PDF_fill_imageblock($this->pdf, $page, $key, $img, NULL);
168                }
169            }
170        }
171       
172        // 割り当てたページを閉じる
173        PDF_close_pdi_page($this->pdf, $page);
174        // 割り当てたドキュメントを閉じる
175        PDF_close_pdi($this->pdf, $doc);
176    }
177   
178    // ページを閉じる
179    function closePage() {
180        if($this->page_open) {
181            // ページを閉じる
182            PDF_end_page_ext($this->pdf, NULL);
183            $this->page_open = false;
184        }       
185    }
186   
187    // ページを開く
188    function openPage() {
189        if(!$this->page_open) {
190            // 新しいページを開く   
191            PDF_begin_page_ext($this->pdf, $this->width, $this->height, NULL);
192            $this->page_open = true;
193        }
194    }
195   
196    // 新しいページを開く
197    function newPage() {
198        PDF_end_page_ext($this->pdf, NULL);
199        PDF_begin_page_ext($this->pdf, $this->width, $this->height, NULL);
200    }
201   
202    // アクティブなページのサイズを取得する
203    function getSize() {
204        $this->openPage();
205        $x = PDF_get_value($this->pdf, 'pagewidth', 0);
206        $y = PDF_get_value($this->pdf, 'pageheight', 0);
207        return array($x, $y);
208    }
209   
210    // 座標を入れ替えて取得する(左下(0,0)を左上(0,0)に変換)
211    function posTopDown($x, $y) {
212        $width = 0;
213        $height = 0;
214        list($width, $height) = $this->getSize();
215        // x座標は、変更の必要なし
216        $pdf_x = $x;
217        $pdf_y = $height - $y;
218        return array($pdf_x, $pdf_y);
219    }
220   
221    // テーブルカラーの設定
222    function setTableColor($frame_color = "000000", $title_color = "F0F0F0", $line_color = "D1DEFE", $last_color = "FDCBFE") {
223        $this->frame_color = $frame_color;
224        $this->title_color = $title_color;
225        $this->line_color = $line_color;
226        $this->last_color = $last_color;
227    }
228   
229    // テーブルのグリッドを表示する。
230    function writeGrid($x, $y, $arrCol, $line_max, $last_color_flg = true) {
231        // テーブル幅
232        $max = count($arrCol);
233        $width = 0;
234        for($i = 0; $i < $max; $i++) {
235            $width += $arrCol[$i];
236        }
237       
238        if($this->title_enable) {
239            // タイトルグリッド描画
240            $this->writeFrameRect($x, $y + GRID_SPACE, $width + GRID_SPACE, $this->fontsize + GRID_SPACE, $this->title_color, $this->frame_color);
241        }
242       
243        // グリッド特殊指定あり
244        if(count($this->arrLines) > 0) {
245            $count = count($this->arrLines);
246            $pos = 0;
247            for($i = 0; $i < $count; $i++) {
248                if(($i % 2) != 0) {
249                    // 行の間隔
250                    $down = ($pos + 1) * $this->fontsize * 1.5;
251                    // 描画する縦幅を求める
252                    $height = ($this->fontsize + GRID_SPACE) * $this->arrLines[$i] + ($this->arrLines[$i] - 1);
253                    // 行グリッド描画
254                    $this->writeRect($x, $y + GRID_SPACE + $down, $width + GRID_SPACE, $height, $this->line_color);
255                }
256                $pos += $this->arrLines[$i];   
257            }                       
258        } else {
259            for($i = 1; $i <= $line_max; $i++) {
260                if(($i % 2) == 0) {
261                    // 行の間隔
262                    $down = $i * $this->fontsize * 1.5;
263                    // 行グリッド描画
264                    $this->writeRect($x, $y + GRID_SPACE + $down, $width + GRID_SPACE, $this->fontsize + GRID_SPACE, $this->line_color);
265                }
266            }
267            // 最終行に色をつける場合
268            if($last_color_flg) {
269                // 行の間隔
270                $down = $line_max * $this->fontsize * 1.5;
271                // 行グリッド描画
272                $this->writeRect($x, $y + GRID_SPACE + $down, $width + GRID_SPACE, $this->fontsize + GRID_SPACE, $this->last_color);
273            }
274        }
275    }
276   
277    // グリッド用のアンダーラインを引く
278    /*
279        $x          :テーブル開始位置X軸
280        $y          :テーブル開始位置Y軸
281        $arrCol     :カラムサイズの配列
282        $line       :アンダーラインを引く行
283        $start_col  :アンダーライン開始カラム(0:開始カラム)
284     */
285    function writeUnderLine($x, $y, $arrCol, $line, $start_col = 0) {
286        // テーブル幅
287        $max = count($arrCol);
288        $width = 0;
289        for($i = 0; $i < $max; $i++) {
290            $width += $arrCol[$i];
291        }
292       
293        $start_x = 0;
294        for($i = 0; $i < $start_col; $i++) {
295            $start_x += $arrCol[$i];
296        }
297       
298        // アンダーラインのY座標を求める
299        $down = ($line + 1) * $this->fontsize * 1.5;
300        // 行グリッド描画
301        $sx = $x + $start_x + GRID_SPACE + $this->table_left;
302        $sy = $y + GRID_SPACE + $down - 1;
303        $ex = $x + $width + GRID_SPACE;
304        $ey = $sy;
305               
306        $this->writeLine($sx, $sy, $ex, $ey);       
307    }
308   
309    // 真ん中横位置を求める
310    function getXCenter($width) {
311        $page_width = 0;
312        $page_height = 0;
313        list($page_width, $page_height) = $this->getSize();
314        $x = ($page_width - $width) / 2;
315        return $x;
316    }
317   
318    // 自動中央よせ
319    function writeTableCenter($table, $y, $arrCol, $arrAlign, $line_max = 256, $start_no = 1, $last_color_flg = false) {
320        // テーブルサイズ取得
321        $width = 0;
322        foreach($arrCol as $val) {
323            $width += $val;
324        }
325        // 中央よせ位置取得
326        $x = $this->getXCenter($width) + $this->table_left;
327        list($ret_x, $ret_y) = $this->writeTable($table, $x, $y, $arrCol, $arrAlign, $line_max, $start_no, $last_color_flg);
328        // X軸の座標を返す
329        return array($ret_x, $ret_y);
330    }
331   
332    // データの書き込み(closeすると次回新規ページ)
333    // $start_no:1行目(タイトル)を0とする。
334    // $line_max:タイトルを含まない行数
335    function writeTable($table, $x, $y, $arrCol, $arrAlign, $line_max = 256, $start_no = 1, $last_color_flg = false) {
336        $this->openPage();
337       
338        $table = ereg_replace("\n$", "", $table);
339               
340        $arrRet = split("\n", $table);
341                               
342        if($line_max > (count($arrRet) - $start_no)) {
343            $line_max = count($arrRet) - $start_no;
344        }
345       
346        // タイトル有効
347        if($this->grid_enable) {
348            // グリッドの描画
349            $this->writeGrid($x, $y, $arrCol, $line_max, $last_color_flg);
350        }
351       
352        // UnicodeエンコーディングとしてUTF-8を設定
353        PDF_set_parameter($this->pdf, "textformat", "utf8");
354       
355        // タイトル有効
356        if($this->title_enable) {
357            if(count($this->arrHeaderColSize) > 0 && count($this->arrHeaderAlign) > 0 ) {
358                list($linecol, $aligncol, $width) = $this->getTableOption($this->arrHeaderColSize, $this->arrHeaderAlign);
359            } else {
360                list($linecol, $aligncol, $width) = $this->getTableOption($arrCol, $arrAlign);
361            }   
362                       
363            // タイトル行の書き込み
364            $option = "ruler {" . $linecol . "} ";
365            $option.= "tabalignment {" . $aligncol . "} ";
366            $fontsize =  $this->fontsize;
367            $option.= "hortabmethod ruler leading=150% fontname=HeiseiKakuGo-W5 fontsize=$fontsize encoding=UniJIS-UCS2-H";
368           
369            $this->writeTableData($table, $x, $y, $width, 0, 0, $option);
370        }
371       
372        list($linecol, $aligncol, $width) = $this->getTableOption($arrCol, $arrAlign);
373       
374        // データ行の書き込み
375        $option = "ruler {" . $linecol . "} ";
376        $option.= "tabalignment {" . $aligncol . "} ";
377        $option.= "hortabmethod ruler leading=150% fontname=HeiseiMin-W3 fontsize=$this->fontsize encoding=UniJIS-UCS2-H";
378       
379        if($start_no <= 0) {
380            $start_no = 1;
381            $end_no = $line_max;
382        } else {
383            $end_no = $start_no + $line_max - 1;
384        }
385       
386        $y += $this->fontsize * 1.5;
387       
388        list($ret_x, $ret_y) = $this->writeTableData($table, $x, $y, $width, $start_no, $end_no, $option);
389       
390        return array($ret_x, $ret_y);
391    }
392   
393    function getTableOption($arrCol, $arrAlign) {
394        // カラムサイズ
395        $max = count($arrCol);
396        $width = 0;
397        for($i = 0; $i < $max; $i++) {
398            $width += $arrCol[$i];
399            $linecol.= $width . " ";
400        }
401       
402        // カラム位置
403        $max = count($arrAlign);
404        for($i = 0; $i < $max; $i++) {
405            $aligncol.= $arrAlign[$i] . " ";
406        }
407       
408        return array($linecol, $aligncol, $width);
409    }
410   
411    // テーブルデータの書き込み
412    function writeTableData($table, $x, $y, $table_width, $start_no, $end_no, $option) {
413        $arrLine = split("\n", $table);
414        for($i = $start_no; $i <= $end_no; $i++) {
415            $line.=$arrLine[$i] . "\n";
416        }
417               
418        // テーブル位置を求める
419        list($pdf_x, $pdf_y) = $this->posTopDown($x, $y);
420                       
421        // テーブル高さを求める
422        $table_height = $this->fontsize * 1.5 * ($end_no - $start_no + 1);
423        // テーブル右下のy座標を求める
424        $end_y = $pdf_y - $table_height;
425        if($end_y < 0) {
426            $end_y = 0;
427        }
428        $enc_table = mb_convert_encoding($line, "utf-8", CHAR_CODE);
429               
430        $tf = PDF_create_textflow($this->pdf, $enc_table, $option);
431
432        PDF_fit_textflow($this->pdf, $tf, $pdf_x, $pdf_y, $pdf_x + $table_width, $end_y, NULL);
433        PDF_delete_textflow($this->pdf, $tf);
434       
435        // テーブル左下座標を返す
436        return array($x, $y + $table_height);       
437    }
438       
439    // 色の設定
440    function setColor($rgb) {
441        if($rgb != "") {
442            list($r, $g, $b) = sfGetPdfRgb($rgb);
443            PDF_setcolor($this->pdf, "fillstroke", "rgb", $r, $g, $b, 0);   
444        }
445    }
446   
447    // 短形を描画
448    function writeRect($x, $y, $width, $height, $rgb = "") {
449        $this->openPage();
450        list($pdf_x, $pdf_y) = $this->posTopDown($x, $y);
451        $this->setColor($rgb);
452        PDF_rect($this->pdf, $pdf_x,$pdf_y,$width,-$height);
453        PDF_fill($this->pdf);
454    }
455   
456    // 枠付の短形を描画
457    function writeFrameRect($x, $y, $width, $height, $rgb, $frgb) {
458        $this->openPage();
459        list($pdf_x, $pdf_y) = $this->posTopDown($x, $y);
460        $this->setColor($frgb);
461        PDF_rect($this->pdf, $pdf_x,$pdf_y,$width,-$height);
462        PDF_fill($this->pdf);
463       
464        $this->setColor($rgb);
465        PDF_rect($this->pdf, $pdf_x+1,$pdf_y-1,$width-2,-$height+2);
466        PDF_fill($this->pdf);       
467    }
468   
469    // 直線を描画
470    function writeLine($sx, $sy, $ex, $ey, $rgb = "000000") {
471        $this->openPage();
472        list($pdf_sx, $pdf_sy) = $this->posTopDown($sx, $sy);
473        list($pdf_ex, $pdf_ey) = $this->posTopDown($ex, $ey);
474        $this->setColor($rgb);
475        PDF_setlinewidth($this->pdf, 1.0);
476        PDF_moveto($this->pdf, $pdf_sx, $pdf_sy);
477        PDF_lineto($this->pdf, $pdf_ex, $pdf_ey);
478        PDF_stroke($this->pdf);
479    }
480       
481    // ファイルのダウンロード
482    function output($filekey = "") {
483        if(isset($this->pdf)) {
484            // ページを閉じる
485            $this->closePage();
486            // PDFの終了
487            PDF_end_document($this->pdf, NULL);
488            // 出力用データの取得
489            $buf = PDF_get_buffer($this->pdf);
490            $filename = $filekey . date("ymdHis").".pdf";
491                       
492            header("Content-disposition: attachment; filename=$filename");
493            header("Content-type: application/octet-stream; name=$filename");
494                   
495            /*
496             * session_start()を事前に呼び出している場合に出力される以下のヘッダは、
497             * URL直接呼び出し時にエラーを発生させるので空にしておく。
498             *
499             * Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
500             * Progma: no-cache
501             *
502             */
503            header("Cache-Control: ");
504            header("Pragma: ");
505            print $buf;
506           
507            // PDF解放
508            PDF_delete($this->pdf);
509        } else {
510            print("PDFが生成されていません。");
511        }
512        exit;       
513    }
514   
515    // ファイルの表示
516    function display() {
517        if(isset($this->pdf)) {
518            // ページを閉じる
519            $this->closePage();
520            // PDFの終了
521            PDF_end_document($this->pdf, NULL);
522           
523            // 出力用データの取得
524            $buf = PDF_get_buffer($this->pdf);
525            $len = strlen($buf);
526            header("Content-type: application/pdf");
527            header("Content-Length: $len");
528            header("Content-Disposition: inline; filename=". date("YmdHis").".pdf");
529                               
530            /*
531             * session_start()を事前に呼び出している場合に出力される以下のヘッダは、
532             * URL直接呼び出し時にエラーを発生させるので空にしておく。
533             *
534             * Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
535             * Progma: no-cache
536             *
537             */
538            header("Cache-Control: ");
539            header("Pragma: ");
540            print $buf;
541           
542            // PDF解放
543            PDF_delete($this->pdf);
544        } else {
545            print("PDFが生成されていません。");
546        }
547        exit;
548    }
549}
550
551?>
Note: See TracBrowser for help on using the repository browser.