5

HTML テンプレートから PDF レポートを生成するために、php の dompdf ライブラリを使用しています。その html テンプレートには、セクションの目次があります。PDF を生成するときに、目次のページ番号を更新する必要があります。PHPのdompdfライブラリでこれを達成する方法を知っている人はいますか?

前もって感謝します。

4

5 に答える 5

2

私は Drupal でこれを達成しましたが、他の php オープンソースやフレームワークでも同様に機能すると思います。このコードをスクリプトタグ内に保持しました

$GLOBALS['entity_page'][] =  $pdf->get_page_number();        

ページ番号を格納するテンプレート。テンプレートの拡張子は tpl.php で、エクスポート用の他のコードを追加した後のモジュールに......

$canvas = $dompdf->get_canvas();
    $font = Font_Metrics::get_font("helvetica", "normal");
    $canvas->page_text(520, 805, "Page {PAGE_NUM}", $font, 9, array(0.4, 0.4, 0.4));

    foreach ($GLOBALS['entity_page'] as $key => $val) {
        $GLOBALS["entity_val"] = 0;
        $GLOBALS["entity_y"] = 110;
        $canvas->page_script('if($PAGE_NUM == 3 && $PAGE_NUM < 4){
                 $font = Font_Metrics::get_font("helvetica", "normal");
                 $x = 380;
                 $y = $GLOBALS["entity_y"];

                 $pdf->text($x, $y, "-------------------------".$GLOBALS["entity_page"][$GLOBALS["entity_val"]]."", $font, 12, array(0, 0, 0, 0.8));
                 $GLOBALS["entity_y"] = $GLOBALS["entity_y"] + 33;
                 $GLOBALS["entity_val"] = $GLOBALS["entity_val"] + 1;

                }');
    }

$pdf->text この部分は、y 軸の位置に一定の増分でページ番号を追加します。他のグローバル変数 entity_y および entity_val は、値を格納するために使用されます。

于 2016-06-30T12:18:32.390 に答える
1

HTML(h1、h2、h3を使用)から目次を生成し、次のことを行いました。

  • 最初にすべてのヘッダーに一意の ID を付けます (PrinceXML を使用しているため)。これは適切な方法です。
  • 次に、OL/LI 構造を作成しますが、そのコードにはバグが含まれている可能性があります。
    $matches = null;
    $smatches = null;
    $had_headers = array();
    preg_match_all('/<h[0-9].*?>.*?<\/h[0-9]>/i', $content, $matches);
    if (!empty($matches[0]) && count($matches[0]) > 0)
    foreach ($matches[0] as $headertag) {
        preg_match('/>(.*?)<\/(h[0-9])>/i', $headertag, $smatches);
    
        if (!empty($smatches[1]) && count($smatches[1]) > 0) {
            $headerid = strip_tags($headertag);
            $headerid = trim(strtolower(preg_replace('/[^a-z0-9]/i', '', $headerid)));
            $smatches[2] = strtolower($smatches[2]);
            $header_depth = intval(trim(str_ireplace('h', '', $smatches[2])));
        
            while (in_array($headerid, $had_headers)) {
                $headerid .= '1';
            }
            $had_headers[] = $headerid;
        
            $content = str_replace($headertag, '<'. $smatches[2] . ' id="' . htmlentities($headerid) . '">' . $smatches[1] . '</' . $smatches[2] . '>', $content);
        }
    }

    $matches = null;
    $smatches = null;
    $toc_html = '<ol id="toc">' . "\n";
    $old_depth = 0;
    $hadfirst = false;
    preg_match_all('/<h[0-9].*?>.*?<\/h[0-9]>/i', $content, $matches);
    if (!empty($matches[0]) && count($matches[0]) > 0)
    for ($i=0; $i < count($matches[0]); $i++) {
        $headertag = $matches[0][$i];
    
        preg_match('/<h[0-9][^>]*?id="(.*?)".*?>(.*?)<\/(h[0-9])>/i', $headertag, $smatches);
    
        if (!empty($smatches[1]) && count($smatches[1]) > 0) {
            $headerid = trim($smatches[1]);
            $header_depth = intval(trim(str_ireplace('h', '', $smatches[3]))) - 1;
        
            // don't take heigher than h3 in TOC
            if ($header_depth > 2)
                continue;
        
            if ($header_depth < $old_depth) {
                $diff = $old_depth - $header_depth; //if going multiple levels up
                $toc_html .= '</li>'.str_repeat('</ol></li>', $diff);
            } elseif ($header_depth > $old_depth) {
                $toc_html .= '<ol>';
            } else {
                $toc_html .= ($hadfirst) ? '</li>' : null;
            }
        
            $toc_html .= '<li><a href="#' . $headerid . '">' . htmlentities(trim(strip_tags($smatches[2]))) . '</a>';
        
            $old_depth = $header_depth;
            $hadfirst = true;
        }
    }
    $toc_html .=  str_repeat('</li></ol>', ($old_depth + 1));
于 2009-10-15T07:38:50.017 に答える
0

あなたはすでにこれを解決したかもしれませんか?私は dompdf を使用したことはありませんが、Zend_Pdf で同様のことを行いました。目次用に空白のページを作成し、その後のすべてのページを作成し、page_number => title の配列を保持しました。最後に戻って、以前に保存した参照を使用して目次ページを更新しました...

于 2009-08-23T07:05:05.550 に答える
0

ここでのヴィッキー・シュレスタの答えの拡張として、複数のページを展開する目次について私が持っているものがあります。

36 は、デザインに収まるアイテムの任意の数です。

foreach ($GLOBALS['entity_page'] as $key => $val) {
    $GLOBALS["entity_y"] = 88;
    $GLOBALS["entity_val"]  = 0;
    $GLOBALS["entity_per_page"] = 36;
    if($val) {
        $canvas->page_script('
        if(isset($GLOBALS["entity_page"][$GLOBALS["entity_val"]])) {
            if($PAGE_NUM == $GLOBALS["entity_page_number"]){
                $x = 505;
                $y = $GLOBALS["entity_y"];
                $font = $fontMetrics->get_font("Open Sans", "Helvetica Neue", "Helvetica, Arial, sans-serif");

                $pdf->text($x, $y, $GLOBALS["entity_page"][$GLOBALS["entity_val"]]."", $font, 7, array(0, 0, 0, 1));
                $GLOBALS["entity_y"] = $GLOBALS["entity_y"] + 19;
                $GLOBALS["entity_val"] = $GLOBALS["entity_val"] + 1;
                if (($GLOBALS["entity_val"] + 1) % $GLOBALS["entity_per_page"] == 0 ) {
                    $GLOBALS["entity_page_number"] = $GLOBALS["entity_page_number"] + 1;
                    $GLOBALS["entity_y"] = 31;
                }
            }
        }');
    }
}

isset は重要です。何らかの理由で foreach がさらに 1 回ループし、最後に範囲外の例外がスローされるためです。

于 2018-12-12T17:49:36.103 に答える