在 PHP 中使用 ABCpdf

我使用的 PHP 的版本為 5.3.6,ABCpdf 的版本為 7.0,.NET 的環境要 2.0 以上。開始時曾測過 ABCpdf 6.0 的版本,無法由 PHP 透過DOTNET() 來啟始 ABCpdf,改裝 ABCpdf 7.0 的版本就成功了。

因為我不曉得如何處理 byte array, 只好先寫入 file, 再讀出來寫出去client端。簡短的範例程式如下,說明請參考註解。

<?php
// 啟如 ABCpdf, 這一串參數可由 Windows 的 regedit 找到
$theDoc = new DOTNET("ABCpdf, Version=7.0.4.2, Culture=neutral, PublicKeyToken=a7a0b3f5184f2169", "WebSupergoo.ABCpdf7.Doc");
// 設定紙張為台灣人習慣的 A4
$theDoc->MediaBox->String="A4";
// 設定只有使用的中文字內嵌,且不垂直排列
$theDoc->Font = $theDoc->EmbedFont("新細明體","Unicode",False,True );
$theDoc->FontSize = 30;
$theDoc->AddText("Hi,您好!!");
// 不知如何處理 byte array, 只好先寫入暫存檔, 再讀出來了。
$tmpfname = tempnam("c:\\temp", "FOO");
$theDoc->Save($tmpfname);
$fp = fopen($tmpfname, 'rb');
ob_clean();
// 設定 header
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="MyPDF.PDF"');
header("Content-Length: ".filesize($tmpfname));
// 寫出資料
fpassthru($fp);
fclose($fp);
// 將暫存檔刪除
unlink($tmpfname);
Exit ;

2013-12-18 補充

不用存暫存檔的作法如下

<?php
$theDoc = new DOTNET("ABCpdf, Version=7.0.4.2, Culture=neutral, PublicKeyToken=a7a0b3f5184f2169", "WebSupergoo.ABCpdf7.Doc");
$theDoc->AddHtml("Hello");
$binData = $theDoc->GetData();
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="Pdftest.pdf"');
header("Content-Length: ".count($binData));
foreach($binData as $c) {
    echo chr($c);
}
exit;

如果網頁的編碼是 UTF-8,在 initiate ABCpdf 時,指定 codepage 為 CP_UTF8 即可。

$theDoc = new DOTNET("ABCpdf, Version=7.0.4.2, Culture=neutral, PublicKeyToken=a7a0b3f5184f2169", "WebSupergoo.ABCpdf7.Doc",  CP_UTF8);
$theDoc->Font = $theDoc->EmbedFont("新細明體", "Unicode", False, True );
$theDoc->AddText("Hi,水牛伯,游錫堃,您好!!");

ABCpdf 7 同時也支援 ASP 的 COM,在 PHP 中,可以直接使用 COM() 來啟始 ABCpdf。另外,可以在 EmbedFont() 中,指定字型的檔名,例如 barcode 的字型檔 'C39HrP36DlTt.ttf'。

$act='';  // 'download': 下載檔案
$theDoc = new COM("ABCpdf7.Doc", null, CP_UTF8);
$theDoc->Font = $theDoc->EmbedFont('DFKai-sb', "Unicode", false, true ); 
$theDoc->FontSize = 30;
$theDoc->AddHtml("Hello,堃碁好<br><br>條碼字型<br>");
$theDoc->Font = $theDoc->EmbedFont(__DIR__."/C39HrP36DlTt.ttf", 'Latin', false, true);
$theDoc->AddHtml("*C39HrP36DlTt*");

$binData = $theDoc->GetData();
header('Content-type: application/pdf');
if ($act=='download') {
   header('Content-Disposition: attachment; filename="Pdftest.pdf"');
} else {
   header('Content-Disposition: inline; filename="'.$pdfname.'"');
}
header("Content-Length: ".count($binData));

foreach($binData as $c) {
    echo chr($c);
}
exit;