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 /* 内容示例: */ // 但更简单的是直接使用 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()]); } } }