導讀:本人初次寫部落格,有不足之處,請多多指教 。
因為專案中有需求,要動態的生成一些圖片,圖片的格式要求也比較嚴格就像是這樣的
表格中的資料如 單價 數量都是動態的資料, 剛開始準備用 GD庫
來操作,後來想想不太現實所以去找了找有沒有比較成熟的 php
類庫。有不少的類庫,可以實現直接生成 PDF
而沒有可以直接生成 Image
的擴充套件包。
後來發現了一個 開源的軟體 wkhtmltox
該軟體支援讀取本地和網路端的網頁,直接在本地生成 pdf
或 image
。wkhtmltox官方地址
- 該軟體有 Window 版本和 Linux 版本(具體支援詳情可以檢視其官網)
- 下載之後需要將可執行檔案的路徑新增到環境變數中
具體的使用大概是這樣的
$ D:/wktopdf/wkhtmltopdf/bin/wkhtmltoimage --format "jpg" "./1-夏天/夏天.html" "./1-夏天/夏天.jpg"
$ wkhtmltopdf --format "pdf" "./1-夏天/夏天.html" "./1-夏天/夏天.pdf"
支援中文路徑和中文檔名, 但是使用者可不會這種操作,所以需要一些封裝(將執行流程抽象化),有一個哥們已經為我們做了,所以不需要我們去造輪子了。
KnpLabs/snappy
一個基於 wkhtmltox
的 php
擴充套件包 擴充套件包GitHup地址
使用方式
$ composer require knplabs/knp-snappy
<?php
require __DIR__ . '/vendor/autoload.php';
use Knp\Snappy\Image;
$snappy = new Image('D:/wktopdf/wkhtmltopdf/bin/wkhtmltoimage'); // 如果你是window環境, 需要將該路徑新增到環境變數中
$snappy = new Image(__DIR__ . '/vendor/h4cc/wkhtmltoimage-amd64/bin/wkhtmltoimage-amd64'); // 如果你是linux環境
$str = <<<'EOD'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
@font-face {
font-family: myFirstFont;
src: url('C:/Users/Administrator/Desktop/snopy/Microsoft Yahei.ttf');
}
body {
font-family: myFirstFont;
}
</style>
<body>
</body>
</html>
EOD;
$path = __DIR__ .'/我的/';
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
// 實際生產環境中為了不報錯,需要進行異常處理
try {
// 第一個引數是需要轉換的 html
// 第二個引數是檔案儲存路徑
$result = $snappy->generateFromHtml($str, $path . '夏天.jpg');
} catch( Exception $e) {
var_dump($e->getMessage());
}
你也可以從 compoer
中安裝需要的 wkhtmltox
依賴,
由於
wkhtmltox
是基於QtWebKit rendering engine
, 所以理論上是可以,生成比較複雜的Css
寫的夠好。同時也支援網路協議,可以從網頁中生成Image
。
如果要引入一些外部的css
字型
圖片
請使用 絕對路徑, 生成的
重點該擴充套件包會使用 proc_open
函式 去執行生成的 shell
指令碼,所以對生產環境的安全有一定的威脅,最後被砍掉了。
由於安全原因,自己做的東西被砍了以後,也嘗試了別的方式去實現這個功能,但是都不太如意,因為需要生成的
Image
比較複雜,要麼是css
支援的不是很好,要麼就是字型和圖片無法引入的錯亂。最後想到了在服務端window
的批處理檔案.bat
檔案來實現。後來也實現了,可是使用的複雜程度就上去了。
最後在php
的官方文件中發現了這個
檢視了一下也是基於 wkhtmltox
的一個 php 的擴充套件包,於是就動手去實現了一下。
依賴項
wkhtmltox
軟體 liunx 版本(目前個人只是編譯了linux的擴充套件,如果有興趣的可以嘗試去編譯 window版本的)
具體步驟(linux環境)
- 首先需要到官網去下載軟體 軟體下載地址
- 擴充套件需要編譯的原始碼 原始碼下載地址
- 請注意
wkhtmltox
區分作業系統是32位還是64位的 - 個人伺服器環境是centos7, 使用的
wkhtmltox
的版本是0.124
0.124版軟體包下載地址
開始編譯需要的php擴充套件
git clone https://github.com/krakjoe/wkhtmltox
cd wkhtmltox
phpize
// 這裡因為每個人安裝環境不一樣 /path/to/wkhtmltox/installation 請將這個地址替為wkhtmltox真實的安裝路徑
/// PATH 替換為真實的php配置路徑
./configure --with-wkhtmltox=/path/to/wkhtmltox/installation --with-php-config = PATH
make
make install
- 修改配置檔案 ,將生成的
wkhtmltox.so
新增到php.ini
的配置中,重啟php - 安裝成功效果
- 然後就可以 開始愉快的使用這個強大的工具了
HELLO PDF
use wkhtmltox\PDF\Converter as PDFConverter;
use wkhtmltox\PDF\Object as PDFObject;
$converter = new PDFConverter([
"out" => "test.pdf"
]);
$converter->add(new PDFObject(
file_get_contents("http://www.baidu.com")));
$converter->convert();
HELLO IMAGE
use wkhtmltox\Image\Converter as ImageConverter;
// 這裡第一個引數可以傳入 ` html ` 的字串
$converter = new ImageConverter(null, [
"fmt" => "png",
"in" => "http://www.baidu.com",
"out" => "test.png"
]);
$converter = new ImageConverter($str, [
"fmt" => "jpg",
"out" => "test.jpg"
]);
$converter->convert();
這個安全的實現方式,不會使用到一些會威脅到伺服器安全的函式
本作品採用《CC 協議》,轉載必須註明作者和本文連結