|
|
|
PHP PDF Benchmark mpdf, tcpdf, dompdf |
|
|
|
|
|
|
|
คือผมสงสัยว่าจะเอาตัวสร้าง PDF ตัวไหนดี ไปอ่านๆคนนั้นก็บอกตัวนั้น คนโน้นก็บอกตัวโน้น มันไม่มีใครทำทดสอบมาให้เห็นจะจะเลยสักที เลยเขียนทดสอบเองแม่มเลย
สเป็ค:
ต้องสร้าง PDF จาก HTML ได้เท่านั้น เพราะจะต้องทำหน้า editor ให้แก้ไขได้ ซึ่งไม่มีวิธีอื่น.
PDF library ที่ทดสอบ Mpdf, TCPDF, DomPDF
ติดตั้งโดยใช้ Composer
ทดสอบครั้งที่ 1
ทดสอบโดยใช้การกำหนดค่าต่างๆให้น้อยที่สุดแต่จะต้องแสดงภาษาไทย, อังกฤษ, ตาราง ได้ด้วย.
Code
{
"require": {
"mpdf/mpdf": "^8.0",
"tecnickcom/tcpdf": "^6.3",
"dompdf/dompdf": "^0.8.3"
}
}
composer.json
Code (PHP)
<?php
require_once 'vendor/autoload.php';
$htmlcontent = <<< EOD
<p>ก็ภาษาไทยอะแหละ + English ใช้ตัว generator หรือคัดลอกจากเว็บข่าวที่ไหนก็ได้สักแห่งเอาละกัน เอาตารางมาลงทดลองด้วย</p>
EOD;
// ต้องมีเว้นวรรคบรรทัดล่างด้วย 1 บรรทัด
template-content.php
Code (PHP)
<?php
use Mpdf\Mpdf;
require 'template-content.php';
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];
$defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];
$Mpdf = new Mpdf([
'fontDir' => array_merge($fontDirs, [
__DIR__ . '/fonts',
]),
'fontdata' => $fontData + [
'thsarabun' => [
'R' => 'THSarabunNew.ttf',
'I' => 'THSarabunNew Italic.ttf',
'B' => 'THSarabunNew Bold.ttf',
]
],
'mode' => 'utf-8',
'default_font' => 'thsarabun',
'default_font_size' => 12,
]);
$Mpdf->writeHTML($htmlcontent);
$Mpdf->Output(__FILE__ . '.pdf', 'F');
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
test02-mpdf.php
Code (PHP)
<?php
require 'template-content.php';
$TCPDF = new TCPDF();
$TCPDF->AddPage();
$TCPDF->SetFont('thsarabun', '', 12);
$TCPDF->writeHTML($htmlcontent);
$TCPDF->Output(__FILE__ . '.pdf', 'F');
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
test03-tcpdf.php
Code (PHP)
<?php
use Dompdf\Dompdf;
require 'template-content.php';
$Dompdf = new Dompdf();
$Dompdf->loadHtml('<meta charset="utf-8"><style>@font-face {font-family: \'thsarabun\'; src: url(fonts/THSarabunNew.ttf) format(\'truetype\');}* {font-family: thsarabun; font-size: 12pt;}</style>' . $htmlcontent);
$Dompdf->render();
$pdfContent = $Dompdf->output();
file_put_contents(__FILE__ . '.pdf', $pdfContent);
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
test04-dompdf.php
ผลการทดสอบ
test02-mpdf.php ใช้เวลาประมาณ 0.99347114562988 วินาที, ความจำประมาณ 14771320 ไบต์
test03-tcpdf.php ใช้เวลาประมาณ 1.5527780056 วินาที, ความจำประมาณ 9036680 ไบต์
test04-dompdf.php ใช้เวลาประมาณ 1.2879600524902 วินาที, ความจำประมาณ 6538728 ไบต์
ทดสอบครั้งที่ 2
รอบที่สองนี้จะเป็นการวัดประสิทธิภาพสำหรับการสร้างเอกสารจำนวนหน้ามากๆ.
Code
{
"require": {
"mpdf/mpdf": "^8.0",
"tecnickcom/tcpdf": "^6.3",
"dompdf/dompdf": "^0.8.3"
}
}
composer.json
Code (PHP)
<?php
require_once 'vendor/autoload.php';
$htmlcontent = <<< EOD
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
@font-face {
font-family: 'thsarabun';
src: url(fonts/THSarabunNew.ttf) format(\'truetype\');
}
body {
font-family: 'thsarabun';
font-size: 12pt;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 10px;
}
table {
border: 1px solid #999;
border-collapse: collapse;
}
table td,
table th {
border: 1px solid #999;
text-align: left;
}
</style>
</head>
<body>
{body}
</body>
</html>
EOD;
$bodycontent = <<< EOD
<h1>Demo PDF</h1>
ใส่ตาราง table เอานะตรงนี้ ไม่อยากก๊อปมามันเยอะ กระทู้จะยาวโดยไม่จำเป็น.
{page}
EOD;
// ต้องมีเว้นวรรคบรรทัดล่างด้วย 1 บรรทัด
template-content-multipages.php
Code (PHP)
<?php
use Mpdf\Mpdf;
require 'template-content-multipages.php';
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];
$defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];
$Mpdf = new Mpdf([
'fontDir' => array_merge($fontDirs, [
__DIR__ . '/fonts',
]),
'fontdata' => $fontData + [
'thsarabun' => [
'R' => 'THSarabunNew.ttf',
]
],
'mode' => 'utf-8',
'format' => [203.2, 139.7],//8.0*5.5 inch
'margin_bottom' => 4,// 0.15 inch
'margin_left' => 4,
'margin_right' => 4,
'margin_top' => 4,
'orientation' => 'P',
'default_font' => 'thsarabun',
'default_font_size' => 12,
]);
for ($i = 1; $i <= 100; $i++) {
$Mpdf->AddPage();
$Mpdf->writeHTML(str_replace('{page}', $i, str_replace('{body}', $bodycontent, $htmlcontent)));
}
$Mpdf->Output(__FILE__ . '.pdf', 'F');
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
test06-mpdf-multiple.php
Code (PHP)
<?php
require 'template-content-multipages.php';
$TCPDF = new TCPDF('', 'in', [8, 5.5]);
$fontname = TCPDF_FONTS::addTTFfont(__DIR__ . '/fonts/THSarabunNew.ttf', 'thsarabun', '', 96);
$TCPDF->SetFont($fontname, '', 12);
$TCPDF->setPrintFooter(false);
$TCPDF->setPrintHeader(false);
$TCPDF->SetMargins(0.15, 0.15, 0.15);
$TCPDF->SetAutoPageBreak(true, 0.15);
for ($i = 1; $i <= 100; $i++) {
$TCPDF->AddPage();
$TCPDF->writeHTML(str_replace('{page}', $i, str_replace('{body}', $bodycontent, $htmlcontent)));
}
$TCPDF->Output(__FILE__ . '.pdf', 'F');
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
test07-tcpdf-multiple.php
Code (PHP)
<?php
ini_set('memory_limit','64M');
ini_set('max_execution_time', '300');
use Dompdf\Css\Style;
use Dompdf\Css\Stylesheet;
use Dompdf\Dompdf;
require 'template-content-multipages.php';
$Dompdf = new Dompdf();
$Dompdf->setPaper([0, 0, 576, 396]);
$Stylesheet = new Stylesheet($Dompdf);
$Style = new Style($Stylesheet);
$Style->set_margin('10.8pt');
$Stylesheet->add_style('html', $Style);
unset($Style);
$Style = new Style($Stylesheet);
$Style->set_page_break_before('always');
$Stylesheet->add_style('.body-page', $Style);
$Dompdf->setCss($Stylesheet);
$bodyPages = '';
for ($i = 1; $i <= 100; $i++) {
$bodyPages .= '<div' . ($i > 1 ? ' class="body-page"' : '') . '>' . str_replace('{page}', $i, $bodycontent) . '</div>';
}
$Dompdf->loadHtml(str_replace('{body}', $bodyPages, $htmlcontent));
$Dompdf->render();
$pdfContent = $Dompdf->output();
file_put_contents(__FILE__ . '.pdf', $pdfContent);
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
test08-dompdf-multiple.php
ผลการทดสอบ
mPDF ใช้เวลาประมาณ 21.168452978134 วินาที หน่วยความจำประมาณ 15691296 ไบต์
TCPDF ใช้เวลาประมาณ 18.786734104156 วินาที หน่วยความจำประมาณ 10454648 ไบต์
Dompdf ใช้เวลาประมาณ 39.982146978378 วินาที หน่วยความจำประมาณ 37230408 ไบต์
สรุป
TCPDF มีอิสระในการกำหนดขนาดของหน่วยต่างๆ เช่น ขนาดกระดาษ, ขนาดขอบกระดาษ แม้เรื่องของขอบกระดาษจากโค้ดที่ใช้ทดสอบนี้จะมีพื้นที่ว่างด้านบนมากจนเกินไป แต่แก้ไขได้โดยกำหนด method setHtmlVSpace() หรือใช้ HTML แค่เฉพาะที่อยู่ภายใน body และแท็ก style เท่านั้น. แต่ TCPDF ก็ไม่ค่อยรองรับการใช้งาน style sheet มากนักจากตัวอย่างปัญหาเรื่องพื้นที่ว่างด้านบนของแท็ก h1 ซึ่งต้องใช้การแก้ผ่านการกำหนด method ทั้งที่ใน style sheet ก็กำหนดไว้อยู่แล้ว.
mPDF กำหนดหน่วยขนาดได้เพียง"มิลลิเมตร"เท่านั้น ซึ่งจะต้องมาแปลงค่าอีกวุ่นวายพอสมควร แต่ว่า mPDF นั้นรองรับการทำงานของ style sheet ได้ดีกว่ากันมาก อีกทั้งยังสามารถใช้ HTML ได้เต็มตั้งแต่ doctype ลงมา. ดู HTML ที่รองรับเพิ่มเติมได้ที่เว็บของ mPDF.
ดูเพิ่มเติม https://rundiz.com/?p=622
Tag : PHP, PDF
|
ประวัติการแก้ไข 2019-12-17 21:27:25 2019-12-18 22:12:36
|
|
|
|
|
Date :
2019-12-17 17:29:21 |
By :
mr.v |
View :
4505 |
Reply :
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ควรลงบทความเป็นอย่างยิ่งครับ
แต่ส่วนตัวแล้วเคยใช้ DOM ใน MVC Laravel 5.0-5.8 แล้วเกิดปัญหากับ Bootstrap เลยเปลี่ยนมาใช้ TCPDF ซึ่งใช้งานได้ดีพอสมควรเลย
|
|
|
|
|
Date :
2019-12-17 19:40:42 |
By :
Genesis™ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
เข้ามาอัพเดทการทดสอบวัดประสิทธิภาพรอบ 2 โดยทดสอบจำนวน 100 หน้า ผลที่ได้กลับกันคนละเรื่องกลับการทดสอบแบบง่ายๆเลยครับ.
แล้วก็มาเพิ่มเติมตัวอย่างโค้ดทดสอบการกำหนด CSS แบบง่ายๆเพื่อทดลองดูปัญหาพื้นที่ว่างของ <h1> ใน TCPDF ด้วย.
Code (PHP)
<?php
use Mpdf\Mpdf;
require 'vendor/autoload.php';
$htmlcontent = <<< EOD
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html {
background-color: green;
}
body {
background-color: teal;
}
h1 {
background-color: red;
border-bottom: 1px solid #000;
margin: 0px;
padding: 0px;
}
p {
background-color: yellow;
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<h1>Hello</h1>
<p>World</p>
</body>
</html>
EOD;
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];
$defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];
$Mpdf = new Mpdf([
'fontDir' => array_merge($fontDirs, [
__DIR__ . '/fonts',
]),
'fontdata' => $fontData + [
'thsarabun' => [
'R' => 'THSarabunNew.ttf',
]
],
'mode' => 'utf-8',
'format' => [203.2, 139.7],//8.0*5.5 inch
'margin_bottom' => 4,// 0.15 inch
'margin_left' => 4,
'margin_right' => 4,
'margin_top' => 4,
'orientation' => 'P',
'default_font' => 'thsarabun',
'default_font_size' => 12,
]);
$Mpdf->AddPage();
$Mpdf->writeHTML($htmlcontent);
$Mpdf->Output(__FILE__ . '.pdf', 'F');
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
echo '<a href="' . basename(__FILE__) . '.pdf">view generated PDF</a><br>' . PHP_EOL;
ตัวอย่างโค้ดการกำหนด style sheet และ HTML แบบเต็มบน mPDF
ผลลัพธ์
Code (PHP)
<?php
require 'vendor/autoload.php';
$htmlcontent = <<< EOD
<style>
html {
background-color: green;
}
body {
background-color: teal;
}
h1 {
background-color: red;
border-bottom: 1px solid #000;
margin: 0px;
padding: 0px;
}
p {
background-color: yellow;
margin: 0px;
padding: 0px;
}
</style>
<h1>Hello</h1>
<p>World</p>
EOD;
$TCPDF = new TCPDF('', 'in', [8, 5.5]);
$fontname = TCPDF_FONTS::addTTFfont(__DIR__ . '/fonts/THSarabunNew.ttf', 'thsarabun', '', 96);
$TCPDF->SetFont($fontname, '', 12);
$TCPDF->setPrintFooter(false);
$TCPDF->setPrintHeader(false);
$TCPDF->SetMargins(0.15, 0.15, 0.15);
$TCPDF->SetAutoPageBreak(true, 0.15);
/*$tagvs = array(
'h1' => array(
0 => array(
'h' => '',
'n' => 0
),
1 => array(
'h' => 'px',
'n' => 1
)
)
);*/
//$TCPDF->setHtmlVSpace($tagvs);
$TCPDF->AddPage();
$TCPDF->writeHTML($htmlcontent);
$TCPDF->Output(__FILE__ . '.pdf', 'F');
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
echo 'time spent: ' . $executionTime . ' seconds<br>' . PHP_EOL;
echo 'memory usage: ' . memory_get_peak_usage() . ' bytes<br>' . PHP_EOL;
echo '<a href="' . basename(__FILE__) . '.pdf">view generated PDF</a><br>' . PHP_EOL;
ตัวอย่างการกำหนด style sheet สำหรับ TCPDF ซึ่งดูแล้ว HTML ที่จะใช้ได้โดยไม่ให้แสดงผลพื้นที่ว่างของแท็ก <h1> ต่างกันมากนัก มันต้องใช้แบบนี้... ก็ดูพิกลพิกาลดี
ผลลัพธ์
|
|
|
|
|
Date :
2019-12-18 22:21:00 |
By :
mr.v |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 01
|