實習時公司需要把一些html頁面中的部分内容生成pdf檔案,然後我就找一些用php把html頁面圍成pdf檔案的類。方法是可謂是找了很多很多,什麼html2pdf,pdflib,FPDF這些都試過了,但是都沒有達到我要的求(主要是不能解決中文亂碼的問題以及樣式排版的問題)。
pdflib,FPDF 這兩個方法是需要編寫程式去生成pdf的,就也是講不支援直接把html頁面轉換成pdf;html2pdf這個雖然可以把html頁面轉換成pdf文 件,但是它隻能轉換一般簡單的html代碼,如果你的html内容要的是通過背景新聞編輯器排版的那肯定不行的。
糾結了半天,什麼百度,谷歌搜尋都用了,搜尋了半天,功夫不負有心人,終于找到一個非常好用的方法了,下面就隆重介紹。
它就 是:wkhtmltopdf,wkhtmltopdf可以直接把任何一個可以在浏覽器中浏覽的網頁直接轉換成一個pdf,首先說明一下它不是一個php 類,而是一個把html頁面轉換成pdf的一個軟體(需要安裝在伺服器上),但是它并不是一個簡單的桌面軟體,而且它直接cmd批處理的,使用php中的 shell_exec()函數就可以調用它。下面就介紹如何用php+js+html來讓它生成pdf檔案的方法(不過有個缺陷就是他需要在伺服器端生成一個緩存檔案,如果你使用thinkphp架構的話就可以将其緩存檔案放在runtime 檔案夾中暫存就行)。
一,下載下傳并安裝wkhtmltopdf
1、下載下傳位址:http://wkhtmltopdf.org/downloads.html 如圖:
2、上面有各種平台下安裝的安裝包,英文不好的直接谷歌翻譯一下。下面以 windows7平台上使用舉例,我的下載下傳的是stable(穩定版)的wkhtmltopdf-0.12.3.2-installer.exe這個版本,我在win7、win8 32位和64位以及win-sever上安裝測試都沒有問題的,系統時幾位就下載下傳幾位的安裝包。下載下傳好以後直接安裝就可以了,注意安裝路徑要知道,下面會用到的。
3、安裝好以後需要在系統環境變量變量名為”Path”的後添加:;D:\wkhtmltopdf\bin 也就是你安裝的目錄。安裝好以後重新開機電腦。
下圖是如何設定環境變量:
打開我的電腦右鍵屬性
點選進階系統設定
找到進階裡面點選環境變量
找到系統變量中的path,點選編輯,将剛剛的安裝位置複制到最後,記得前面加一個分号哦!
二,測試使用效果
直接在cmd裡輸入:wkhtmltopdf http://www.baidu.com/ D:website1.pdf(注意中間有空格哈)
第一個是:運作軟體名稱(這個是不變的) 第二個是網址 第三個是生成後的路徑及檔案名。回車後是不是看生一個生成進度條的提示呢,恭喜您已經成功了,到你的生成目錄裡看看是不是有一個剛生成的pdf檔案呢。
操作方法:1、windows鍵+r打開搜尋框,輸入cmd,點選确定
2、直接在cmd裡輸入:wkhtmltopdf http://www.baidu.com/ D:website1.pdf(注意中間有空格哈)
3、點選回車後,會看到一個進度條,然後就提示轉換成功!
4、之後在相應位置(即剛剛設定的D盤)中會發現多了一個Pdf檔案,就說明成功了
三,php裡調用
php裡調用是很簡單的,用shell_exec這個函數就可以了,如果shell_exec函數不能用看看php.ini裡是否補禁用了(找到php.ini中的shell_exec函數,取消注釋就可以了,一般都是可以直接用的)。簡單舉例:
<?php shell_exec("wkhtmltopdf http://www.shwzzz.cn/ 1.pdf") ?>
你會發現在你php檔案的同級目錄中會生成一個1.pdf的檔案
下面代碼舉例介紹如何在網站開發中使用它:主要功能是截取網頁的部分傳遞到php中處理成pdf文檔
html頁面代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="js/jquery-2.1.4.min.js"></script>
<link rel="stylesheet" href="css/common.css">
<link rel="stylesheet" href="css/myCenter.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>霍蘭德職業測試</title>
</head>
<body>
<!--startprint-->
<div class="right5">
<div class="right_top" style="background-image:url(images/right-di.png);">
<h3>霍蘭德測試報告</h3>
</div>
<div class="print">
<input type="button" value="下載下傳報告" id="down" class="print_btn">
</div>
<div class="Hollander">
<h6>MBTI測試結果:ESTJ</h6>
<div id="chart"></div>
<p>約翰·霍蘭德(John Holland)是美國約翰·霍普金斯大學心理學教授,美國著名的職業指導專家。霍蘭德以職業興趣理論為基礎,先後編制了職業偏好量表(VocatIonaI Preference lnventory)和自我導向搜尋表(Self-directed Search)兩種職業興趣量表,霍蘭德力求為每種職業興趣找出兩種相比對的職業能力。興趣測試和能力測試的結合在職業指導和職業咨詢的實際操作中起到了促進作用。</p>
</div>
<table class="tbl1">
<tbody>
<tr node-type="toolBar">
<td class="tbl11">上司模式:</td>
<td class="tbl12">
<p>①直接上司,快速管理 ②運用過去經驗解決問題 ③直接、明确地識别問題的核心 ④決策和執行決策非常迅速 ⑤傳統型上司,尊重組織内部的等級群組織獲得的成就</p>
</td>
</td>
</tr>
<tr node-type="toolBar">
<td class="tbl11">上司模式:</td>
<td class="tbl12">
<p>①直接上司,快速管理 ②運用過去經驗解決問題 ③直接、明确地識别問題的核心 ④決策和執行決策非常迅速 ⑤傳統型上司,尊重組織内部的等級群組織獲得的成就</p>
</td>
</td>
</tr>
<tr node-type="toolBar">
<td class="tbl11">上司模式:</td>
<td class="tbl12">
<p>①直接上司,快速管理 ②運用過去經驗解決問題 ③直接、明确地識别問題的核心 ④決策和執行決策非常迅速 ⑤傳統型上司,尊重組織内部的等級群組織獲得的成就</p>
</td>
</td>
</tr>
<tr node-type="toolBar">
<td class="tbl11">上司模式:</td>
<td class="tbl12">
<p>①直接上司,快速管理 ②運用過去經驗解決問題 ③直接、明确地識别問題的核心 ④決策和執行決策非常迅速 ⑤傳統型上司,尊重組織内部的等級群組織獲得的成就</p>
</td>
</td>
</tr>
<tr node-type="toolBar">
<td class="tbl11">适合報考專業:</td>
<td class="tbl12">
<a><span>專業定位卡介紹>></span></a>
</td>
</td>
</tr>
</tbody>
</table>
</div>
<!--endprint-->
<form action="pdf.php" method="post" name="hld_res" id="hideform">
<input type="hidden" id="hide_content" name="html"/>
</form>
</body>
<script>
$(function () {
//擷取需要傳遞的Html代碼 通過<!--startprint--><!--endprint-->截取
bdhtml=window.document.body.innerHTML;
sprnstr="<!--startprint-->";
eprnstr="<!--endprint-->";
prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17);
prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr));
//将擷取的html代碼添加到隐藏域中傳給php檔案處理
$("#hide_content").val(""+prnhtml+"");
} );
$("#down").click(function(){
$("#hideform").submit();
});
</script>
</html>
php頁面:
<?php
//轉成pdf
$html=$_POST['html'];
//Turn on output buffering
ob_start();
$html='
<link rel="stylesheet" href="css/common.css">
<link rel="stylesheet" href="css/myCenter.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'.$html;
//這兒可以引入生成的Html的樣式表 路徑可以是絕對路徑也可以是相對路徑,也可以把樣式表檔案複制到臨時html檔案的目錄下 即這兒的demo檔案目錄下(預設) 也可以直接把樣式寫在html頁面中直接傳遞過來
//$html = ob_get_contents();
//$html=$html1.$html;
$filename = "hld";
//save the html page in tmp folder 儲存的html臨時檔案位置 可以是相對路徑也是可以是絕對路徑 下面用相對路徑
file_put_contents("{$filename}.html", $html);
//Clean the output buffer and turn off output buffering
ob_end_clean();
//convert HTML to PDF
shell_exec("wkhtmltopdf -q {$filename}.html {$filename}.pdf");
if(file_exists("{$filename}.pdf")){
header("Content-type:application/pdf");
header("Content-Disposition:attachment;filename={$filename}.pdf");
echo file_get_contents("{$filename}.pdf");
//echo "{$filename}.pdf";
}else{
exit;
}
?>
點選頁面中的下載下傳按鈕,
是不是彈出一個下載下傳提示,打開下載下傳的pdf,是不是和網頁上的樣式一模一樣呢,
再打開Php檔案中的檔案儲存位置,看看是不是多了兩個臨時檔案呢?
這兩個臨時檔案在哪兒,你的css就得在哪兒,或者你直接使用相對路徑,引用其他檔案中的css樣式也可以的,最簡單的就是把css樣式直接寫在要轉成pdf的html頁面中。
如果存在樣式沒有,那就是你的樣式路徑沒有寫對,在檢查一下就可以了!
四,解決分頁問題
wkhtmltopdf 很好用,但也有些不盡人意。就是當一個html頁面很長我需要在指定的地方分頁那怎麼辦呢? wkhtmltopdf 開發者在開發的時候并不是沒有考慮到這一點,
wkhtmltopdf 有個很好的方法,就是在那個div的樣式後添加一個:page-break-inside:avoid;就ok了。
例如
div{ width:800px; min-height:1362px;margin:auto;page-break-inside:avoid;}