安裝 barryvdh/laravel-dompdf 套件

# 套件安裝
composer require barryvdh/laravel-dompdf
# 產生設定檔
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"

設定

Laravel 部分,修改 config/app.php

//PDF 匯出
'providers' => [
    Barryvdh\DomPDF\ServiceProvider::class,
],

'aliases' => [
    // PDF 匯出
    'PDF' => Barryvdh\DomPDF\ServiceProvider::class,
],

Lumen 部分,複製設定檔到 config 目錄下,並修改 bootstrap/app.php

$app->register(\Barryvdh\DomPDF\ServiceProvider::class);
$app->configure('dompdf');

新增路由,修改 routes\web.php

//將公園資料匯出成PDF
Route::get('pdf', 'ParksController@pdf')->name('pdf');

修改 ParksController 新增一個 pdf function

//別忘記這行
use PDF;
/*
    下載 PDF 檔案
    使用 barryvdh/laravel-dompdf - 匯入匯出 PDF 套件
*/
public function pdf()
{
    // 取出資料
    // $parks = ParkEloquent::all();
    $parks = ParkEloquent::paginate(50);
    //設定為橫式, 使用 wt011 字型
    $pdf = PDF::loadView('parks.pdf_view', compact('parks'))
                ->setPaper('A4', 'landscape')
                ->setOptions(['defaultFont' => 'wt011']);
    //將資料拋出直接下載
    return $pdf->download('臺北市公園基本資料.pdf');
}

新增一個 Template 作為輸出樣板

<!DOCTYPE html>
<html lang="zh-Hant-TW">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>台北公園資訊 (PDF匯出)</title>
</head>
<style>
    body {
        font-family: 'wt011';
    }

    #css_table {
        display: table;
    }

    .css_tr {
        display: table-row;
    }

    .css_td {
        display: table-cell;
        height: auto;
        word-wrap: break-word;
        word-break: break-all;
        overflow: hidden;
        padding-left: 1em;
        padding-right: 1em;
    }
</style>

<body>
    <h3 class="card-title">台北公園資訊 (PDF匯出)</h3>
    <div id="css_table">
        <div class="css_tr">
            <div class="css_td">公園名稱</div>
            <div class="css_td">英文名稱</div>
            <div class="css_td">類型</div>
            <div class="css_td">行政區</div>
            <div class="css_td">位置</div>
            <div class="css_td">管理單位</div>
        </div>
        @foreach ( $parks as $park )
        <div class="css_tr">
            <div class="css_td" style="width:15%">
                <p style="font-size: 14px">{{ $park->name }}</p>
            </div>
            <div class="css_td" style="width:18%">
                <p style="font-size: 14px">{{ $park->engname }}</p>
            </div>
            <div class="css_td" style="width:8%">
                <p style="font-size: 14px">{{ $park->type }}</p>
            </div>
            <div class="css_td" style="width:8%">
                <p style="font-size: 14px">{{ $park->dist }}</p>
            </div>
            <div class="css_td" style="width:34%">
                <p style="font-size: 14px">{{ $park->location }}</p>
            </div>
            <div class="css_td" style="width:17%">
                <p style="font-size: 14px">{{ $park->unit }}</p>
            </div>
        </div>
        @endforeach
    </div>
</body>

</html>

中文字問題

由於 laravel-dompdf 套件預設只有英文字型,並不支援中文字型,輸出成 PDF 檔案後就變成一堆亂碼。參考 官方回報 ISSUE 有人回答,需要使用 dompdf / utils 將中文字型新增到 Laravel 裡面。

使用 load_font.php 安裝中文字型

下載 load_font.php 及 TTF 字型檔 並將檔案放在 Laravel 專案的根目錄下,並修改 load_font.php 的 fonts 目錄。

<?php
// 1. [Required] Point to the composer or dompdf autoloader
require_once "vendor/autoload.php";

// 2. [Optional] Set the path to your font directory
//    By default dompdf loads fonts to dompdf/lib/fonts
//    If you have modified your font directory set this
//    variable appropriately.

//將 fontDir 改成 storage/fonts 目錄,並且在 storage 目錄建立 fonts 目錄
$fontDir = "storage/fonts";
php load_font.php "wt011" wt011.ttf

執行後,會在 storage/fonts 目錄下產生幾個檔案,其中一個 dompdf_font_family_cache.php 檔案中記錄著 匯進來的字型對應。

  'wt011' => array(
    'normal' => $fontDir . '/wt011',
    'bold' => $fontDir . '/wt011',
    'italic' => $fontDir . '/wt011',
    'bold_italic' => $fontDir . '/wt011',
  ),

修改模板的 CSS,在模板中加入 style 設定 font-family,將整個模板的字型改成匯入的字型名稱。 (如此一來,匯出的資料就會正常顯示中文)

<style>
    body {
        font-family: 'wt011';
    }
</style>

註: 我試著想用 OTF 字型檔,但是還是無法正常顯示中文字,所以只能使用 TTF 格式的字型檔案。

換行問題

已經可以正常將中文顯示在 PDF 檔案中,卻碰到 table 內容無法自動換行,找孤狗大神問了一下,由於 laravel-dompdf 套件在生成文件時,是利用判斷空白當作換行依據,若整個字串聯在一起就無法自動對其換行,在英文字部分可以使用 css 來強迫 td 的內容換行,但是中文字卻還是無法換行,只好改用 div 仿成 table 方式,在利用 css 設定換行。 (請參考上面的模板)

最後修改日期: 2020 年 11 月 23 日