Files
fdesk/app/common/utils/pdf/service/PdfHelper.php
T
2025-09-08 11:34:19 +08:00

80 lines
3.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// app/service/pdf/PdfHelper.php
namespace app\common\utils\pdf\service;
class PdfHelper
{
/** 从文件加载 HTML(支持占位符 {{key}} 简单替换) */
public static function loadTemplate(string $file, array $vars = []): string
{
if (!is_file($file)) {
throw new \RuntimeException("Template not found: {$file}");
}
$html = file_get_contents($file);
if ($vars) {
$search = [];
$replace = [];
foreach ($vars as $k => $v) {
$search[] = '{{' . $k . '}}';
$replace[] = htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
$html = str_replace($search, $replace, $html);
}
return $html;
}
/**
* 把 HTML 里的相对资源路径(img/link/script href/src)改成绝对路径
* 仅处理以 ./ ../ 或非 http(s) 的相对量;base 传 public/assets/pdf 等目录
*/
public static function absolutizeAssetUrls(string $html, string $baseDir): string
{
$baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR);
// img src
$html = preg_replace_callback('#(<img[^>]+src=["\'])([^"\']+)(["\'])#i', function($m) use ($baseDir){
$u = $m[2];
if (preg_match('#^https?://#i', $u) || strpos($u, 'data:') === 0) return $m[0];
$abs = realpath($baseDir . DIRECTORY_SEPARATOR . ltrim($u, '/')) ?: ($baseDir . '/' . ltrim($u, '/'));
return $m[1] . $abs . $m[3];
}, $html);
// link href(如果你在 HTML 里写了 <link>,通常建议走 css_files 方式,这里也兼容)
$html = preg_replace_callback('#(<link[^>]+href=["\'])([^"\']+)(["\'])#i', function($m) use ($baseDir){
$u = $m[2];
if (preg_match('#^https?://#i', $u)) return $m[0];
$abs = realpath($baseDir . DIRECTORY_SEPARATOR . ltrim($u, '/')) ?: ($baseDir . '/' . ltrim($u, '/'));
return $m[1] . $abs . $m[3];
}, $html);
return $html;
}
/**
* 渲染一个原生 PHP 模板为字符串
* @param string $file 模板路径(如 resource/templates/stock-order.php)
* @param array $vars 将在模板中以变量名存在(如 $data)
* @return string 完整 HTML
*/
public static function render(string $file, array $vars = []): string
{
if (!is_file($file)) {
throw new \RuntimeException("Template not found: {$file}");
}
// 将键名导出为同名变量,例如 'data' => [...] 变为 $data
extract($vars, EXTR_OVERWRITE);
// 开启缓冲,将 include 的输出抓取为字符串
ob_start();
ob_implicit_flush(false);
try {
/** @noinspection PhpIncludeInspection */
include $file;
} catch (\Throwable $e) {
// 清理缓冲并抛出更清晰的异常
ob_end_clean();
throw $e;
}
return ob_get_clean();
}
}