安裝 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 設定換行。 (請參考上面的模板)