Files
fdesk/app/common/utils/pdf/controller/DocumentController.php
T

138 lines
5.2 KiB
PHP
Raw Normal View History

2025-09-05 09:26:29 +08:00
<?php
namespace app\common\utils\pdf\controller;
use support\Request;
use support\Response;
use app\common\utils\pdf\service\document\ReimbursementDocumentService;
use app\common\utils\pdf\service\PdfGeneratorService; // 用于通用 HTML 生成
use Exception;
class DocumentController
{
protected $noNeedLogin = ['downloadReimbursementPdf', 'viewReimbursementPdf'];
protected $noNeedHeaderData = ['downloadReimbursementPdf', 'viewReimbursementPdf'];
/**
* 下载报销单 PDF
* 访问路由: GET /document/reimbursement/{id}
* 示例: /document/reimbursement/123
*/
public function downloadReimbursementPdf(Request $request, int $id)
{
try {
$service = new ReimbursementDocumentService();
$pdfData = $service->generatePdfById($id);
$filename = 'reimbursement_' . $id . '_' . date('Ymd_His') . '.pdf';
return response($pdfData, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]);
} catch (Exception $e) {
// 记录日志
// \support\Log::error("Failed to generate reimbursement PDF: " . $e->getMessage());
return json(['code' => 1, 'msg' => 'Failed to generate PDF: ' . $e->getMessage()]);
}
}
/**
* 在浏览器中查看报销单 PDF
* 访问路由: GET /document/reimbursement/view/{id}
* 示例: /document/reimbursement/view/123
*/
public function viewReimbursementPdf(Request $request, int $id)
{
try {
$service = new ReimbursementDocumentService();
$pdfData = $service->generatePdfById($id);
return response($pdfData, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="reimbursement_view_' . $id . '.pdf"', // 'inline' 关键
]);
} catch (Exception $e) {
return json(['code' => 1, 'msg' => 'Failed to view PDF: ' . $e->getMessage()]);
}
}
/**
* 保存报销单 PDF 到服务器
* 访问路由: POST /document/reimbursement/save
* 参数: id (POST)
*/
public function saveReimbursementPdf(Request $request)
{
$id = $request->post('id');
if (!$id || !is_numeric($id)) {
return json(['code' => 1, 'msg' => 'Invalid ID']);
}
try {
// 指定保存路径
$savePath = runtime_path() . '/generated_pdfs/reimbursements/';
$service = new ReimbursementDocumentService();
$service->savePdfToFile((int)$id, $savePath);
return json(['code' => 0, 'msg' => 'PDF saved successfully', 'path' => $savePath]);
} catch (Exception $e) {
return json(['code' => 1, 'msg' => 'Failed to save PDF: ' . $e->getMessage()]);
}
}
/**
* 通用 HTML 到 PDF 生成接口 (示例)
* 访问路由: POST /document/generate-from-html
* 参数: html_content (POST)
*/
public function generateFromHtml(Request $request)
{
$htmlContent = $request->post('html_content');
if (!$htmlContent) {
return json(['code' => 1, 'msg' => 'HTML content is required']);
}
try {
$generator = new PdfGeneratorService();
// 这里直接传入 HTML,不需要模板。可以创建一个简单的 'html_wrapper' 模板来应用样式。
// 或者直接处理 HTML 字符串。
// 为简化,我们假设传入的 HTML 已经包含所需样式。
// 注意:TCPDF 对复杂 CSS 支持有限,内联样式通常更可靠。
// 创建一个临时数据结构
$tempData = ['content' => $htmlContent];
// 创建一个简单的模板 app/view/pdf/html_wrapper.php
/* 内容示例: <?php echo $data['content']; ?> */
// 但更简单的是直接使用 TCPDF 的 writeHTMLCell 或类似方法处理原始 HTML 片段
// 这里我们直接调用 TCPDF (绕过服务的模板机制)
$pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator('Your System');
$pdf->SetTitle('Generated from HTML');
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->setFontSubsetting(true);
$pdf->SetFont('dejavusans', '', 10, '', true);
$pdf->AddPage();
// 直接写入 HTML
$pdf->writeHTML($htmlContent, true, false, true, false, '');
$pdf->endPage();
$pdfData = $pdf->Output('', 'S');
$filename = 'custom_html_' . date('Ymd_His') . '.pdf';
return response($pdfData, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]);
} catch (Exception $e) {
return json(['code' => 1, 'msg' => 'Failed to generate PDF from HTML: ' . $e->getMessage()]);
}
}
}