7.
產生PDF及拉動排序
一、 超簡易匯出PDF
- https://www.addtoany.com/
- 點擊「Get the button code for」選擇「Any site」,然後點擊Choose Services…設定需要的服務,其中有PDF功能的為printfriendly,點擊「Get Button Code」複製語法,並貼到樣板檔即可。
二、 用TCPDF自己刻PDF
- 完整手冊:https://tcpdf.org/docs/srcdoc/TCPDF/class-TCPDF/
- 函數查詢:https://www.rubydoc.info/gems/rfpdf/1.17.4/TCPDF
- 另有基於TCPDF的html2pdf專案,對中文支援不佳(無法自動換行),故不推薦使用。
- 建立空白PDF文件,其中 TCPDF的建構方法中,使用參數說明如下:
include_once "header.php";
require_once(TADTOOLS_PATH.'/tcpdf/tcpdf.php');
$pdf = new TCPDF("P", "mm", "A4", true, 'UTF-8', false);
//PDF內容設定
$pdf->Output('snews.pdf', 'D');
- (1)
$orientation頁面方向,預設為P(直式),橫向為L,空值則自動判斷
- (2)
$unit度量單位,pt、mm(預設)、cm、in
- (3)
$format紙張大小,預設為 A4(210 x 297mm)
- (4)
$unicode是否使用unicode,預設為true
- (5)
$encoding文件編碼,預設為 UTF-8
- (6)
$diskcache使用磁碟快取,true 會減少記憶體用量,但效能會變差,預設為false
- (7)
$pdfa使用PDF/A模式(長期保存的電子文件格式),預設為false。
- Output的參數:
$name檔名;
$dest輸出模式:
I: 在瀏覽器中呈現 (預設,測試期間建議用此值);
D: 強制下載;
F: 存在主機空間裡;
S: 以文字方式傳回文件;
FI: 等同F+I :
FD: 等同F+D;
E: 以郵件附件方式傳回文件。
三、 常用基本架構
$pdf->setPrintHeader(false); //不要頁首
$pdf->setPrintFooter(false); //不要頁尾
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); //設定自動分頁
$pdf->setFontSubsetting(true); //產生字型子集(有用到的字才放到文件中)
$pdf->SetFont('droidsansfallback', '', 12, '', true); //設定字型
$pdf->SetMargins(15, 15); //設定頁面邊界,
$pdf->AddPage(); //新增頁面,一定要有,否則內容出不來
- SetFont 的參數:
- (1)
$family字型(droidsansfallback 是自加的,msungstdlight細明體是內建)
- (2)
$style樣式:B粗、I斜、U底線、D刪除線、O上方線
- (3)
$size字型大小(預設為12pt)
- (4)
$fontfile字型檔
- (5)
$subset使用文字子集
四、 文字流
$pdf->Text( $x, $y, $txt, $fstroke = false, $fclip = false, $ffill = true, $border = 0, $ln = 0, $align = '', $fill = false, $link = '', $stretch = 0, $ignore_min_height = false, $calign = 'T', $valign = 'M', $rtloff = false );
- Text的參數:
- (1)
$x、$y左上角起始位置;常搭配GetX()、SetX()或GetY()、SetY()使用。
- (2)
$txt是呈現內容;$fstroke則是外框寬度;$fclip是否使用裁剪模式;$ffill是否填色;
- (3)
$border:0(無邊框,預設)、1(加框)、L(左)、T(上)、R(右)、B(下),亦可用陣列來設定樣式,如:
array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
- (4)
$ln下一個元件的位置:0(預設)右邊;1下行最左邊;2目前元件下方
- (5)
$align對齊方向:L、C、R、J。
- (6)
$fill 儲存格背景是否填色(1)或透明(0)。
- (7)
$link 可加上連結
- (8)
$stretch延伸:0不延伸;1字大於格寬才縮放文字;2一律縮放文字到格寬;3字大於格寬才縮放字距;4一律縮放字距到格寬
- (9)
$ignore_min_height是否自動忽略最小高度
- (10)
$calign儲存格中的垂直對齊:T頂部、A字體頂部、L字體基線、 D字體底部、B底部
- (11)
$valign 文字本身的垂直對齊:T頂部、M中間、B底部
- (12)
$rtloff 是否使用頁面左上角作為原點(x和:y初始位置)。
五、 將HTML轉為PDF
- 務必先將網頁內容整理好,如:利用
strip_word_html()來過濾。
function strip_word_html($text, $allowed_tags = '<a><b><blockquote><br><dd><del><div><dl><dt><em><h1><h2><h3><h4><h5><h6><hr><i><img><li><ol><p><pre><small><strong><sub><sup><table><tcpdf><td><th><thead><tr><tt><u><ul>')
{
mb_regex_encoding('UTF-8');
//replace MS special characters first
$search = array('/‘/u', '/’/u', '/“/u', '/”/u', '/—/u');
$replace = array('\'', '\'', '"', '"', '-');
$text = preg_replace($search, $replace, $text);
if (mb_stripos($text, '/*') !== false) {
$text = mb_eregi_replace('#/\*.*?\*/#s', '', $text, 'm');
}
$text = preg_replace(array('/<([0-9]+)/'), array('< $1'), $text);
$text = strip_tags($text, $allowed_tags);
$text = preg_replace(array('/^\s\s+/', '/\s\s+$/', '/\s\s+/u'), array('', '', ' '), $text);
$search = array('#<(strong|b)[^>]*>(.*?)</(strong|b)>#isu', '#<(em|i)[^>]*>(.*?)</(em|i)>#isu', '#<u[^>]*>(.*?)</u>#isu');
$replace = array('<b>$2</b>', '<i>$2</i>', '<u>$1</u>');
$text = preg_replace($search, $replace, $text);
$num_matches = preg_match_all("/\<!--/u", $text, $matches);
if ($num_matches) {
$text = preg_replace('/\<!--(.)*--\>/isu', '', $text);
}
$text = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $text);
return $text;
}
- 若PHP有裝Tidy延伸套件,強烈建議進行tidy格式化:
$html = new Tidy();
$tidy_options = array('clean' => true, 'indent' => true);
$html->parseString($snews['content'], $tidy_options, 'utf8');
$html->cleanRepair();
- writeHTML的參數如下(注意有支援的網頁標籤限制):
$pdf->writeHTML($html, $ln=1, $fill=0, $reseth=true, $cell =true, $align='');
- (1)
$html內容(屬性一定要用雙引號)
- (2)
$reseth若true會重設最後一格的高度
- (3)
$cell自動增加內距
- HTML的表格可利用
cellpadding來增加儲存格內距,用border來設定邊框。
- 左右合併
colspan,上下合併rowspan
- 以網頁方式插入圖片:有支援http://網址/圖檔的方式,但若網址是localhost,圖片路徑需改用相對路徑。
<img src="images/xx.png" border="0">
六、 用Cell取代表格
$pdf->Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = nil, $stretch = 0, $ignore_min_height = false, $calign = 'T', $valign = 'M')
- 無須自己定義x,y位置,較
Text()簡易故最常用,想像任何一段文字都放在一個可以指定寬高的格子中,但注意文字不會隨著格子寬度自動換行,文字可設定隨格子自動放大縮小。
七、 用MultiCell 讓文字可在表格中換行
- 若需要讓文字可以自動換行,請使用MultiCell(),一樣需指定格子寬高。可視需求,和Cell()一起搭配使用
$pdf->MultiCell( $w, $h, $txt, $border = 0, $align = 'J', $fill = false, $ln = 1, $x = '', $y = '', $reseth = true, $stretch = 0, $ishtml = false, $autopadding = true, $maxh = 0, $valign = 'T', $fitcell = false );
- (1)
$reseth若true會重設最後一格的高度
- (2)
$maxh高度上限(需>$h)
- (3)
$fitcell自動縮放字大小到格內
- 若某個格子內容為HTML語法,亦可用
writeHTMLCell()來繪製之
$pdf->writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=false, $reseth=true, $align='', $autopadding=true);
八、 設定文字陰影
$pdf->setTextShadow(array('enabled'=>true, 'depth_w'=>0.3, 'depth_h'=>0.3, 'color'=>array(196,196,196), 'opacity'=>1, 'blend_mode'=>'Normal'));
九、 插入圖片
- 以物件方式插入圖片:
Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array())
- (1)
$file:檔名或圖檔路徑
- (2)
$x、$y:以左上角為起點的x,y座標位置
- (3)
$w、$h:寬度、高度,若設0會自動偵測
- (4)
$type:圖檔格式(大小寫不拘),支援GIF, JPEG, PNG, BMP, XBM, XPM等格式
- (5)
$link:連結網址,或用AddLink()來新增連結
- (6)
$resize:若為true,會縮放原圖到$w 及 $h 指定的大小。
- (7)
$dpi:縮放時用的解析度
- (8)
$palign:水平對齊方向,L(左)、C(中)、R(右)
- (9)
$ismask:若為true,則視該圖為遮罩
- (10)
$imgmask:由此函數傳回圖片物件,或設為 false
- (11)
$fitbox:若不為false,則縮放圖片至外層容器中,亦可用字元來指定縮放方式,如水平方向縮放 (L = 左, C = 中, R = 右) 或上下縮放(T =上, M =中, B =下)
- (12)
$hidden:若為true,則不顯示圖片。
- (13)
$fitonpage:如果為true,圖片大小調整為不超過頁面尺寸。
- (14)
$alt:若為true,圖片將不會直接秀出,而是傳回圖片的ID。
- (15)
$altimgs:交替顯示圖像的ID的數組。每個的替代圖像必須是一個數組,它有兩個值:一個整數,表示圖像ID(對圖像的方法的返回值)和一個布爾值,表示如果圖像是默認的打印。
十、 拉動排序
- 此功能不限用在表格,用在div、ol、ul都可以。
- 這是利用jquery ui 的
sortable功能來做的,需用 get_jquery(true); 來載入jquery ui
- 在每筆可以被拉動資料放上拉動圖示(需引入
tad_function.php語系才能顯示)
<img src="<{$xoops_url}>/modules/tadtools/treeTable/images/updown_s.png" style="cursor: s-resize;margin:0px 4px;" alt="<{$smarty.const._TAD_SORTABLE}>" title="<{$smarty.const._TAD_SORTABLE}>">
- 若不是上下排,亦可用CSS來改變圖示:
style="cursor: move;"
- 替每筆資料設個id,其格式為「變數_編號」
<div class="col-sm-4" id="sn_<{$snews.sn}>">
- 需要有個父元件將所有需要排序的內容包起來,記得設一個id
<div class="row" id="sort">
- 找個適當的地方放一個資訊框,排序完會在該元件裡顯示通知
<div id="save_msg"></div>
- 加入js語法,其中挑選器務必等於父元件的id值
<script type="text/javascript">
$(document).ready(function(){
$('#sort').sortable({ opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable('serialize');
$.post('save_sort.php', order, function(theResponse){
$('#save_msg').html(theResponse);
});
}
});
});
</script>
- 生出
save_sort.php ,用來儲存排序。
<?php
include_once "../../mainfile.php";
include_once "function.php";
$sort = 1;
foreach ($_POST['sn'] as $sn) {
$sql = "update " . $xoopsDB->prefix("snews") . " set `sort`='{$sort}' where `sn`='{$sn}'";
$xoopsDB->queryF($sql) or die(_TAD_SORT_FAIL . " (" . date("Y-m-d H:i:s") . ")" . $sql);
$sort++;
}
echo _TAD_SORTED . "(" . date("Y-m-d H:i:s") . ")";
- 最後記得去修改程式,讓呈現可以依據排序來顯示。
- 本週範例