You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FPDF生成汽修发票:解决同行显示及PHPMailer发送/打印问题

Solution for Your FPDF Invoicing Issues

Hey there! Let's work through your FPDF and invoicing challenges step by step.

1. Align Work Items and Amounts on the Same Row

The issue you're facing comes from using MultiCell for both work descriptions and amounts—MultiCell automatically moves to the next line after rendering content, which breaks horizontal alignment. Here's how to fix it by manually controlling the PDF's cursor position:

Key Logic:

  • For each work/amount pair, first record the current vertical position (Y coordinate) before rendering the work description.
  • After rendering the work with MultiCell, jump back to the original vertical position and move the horizontal cursor (X coordinate) to the start of the amount column.
  • Render the amount using MultiCell (or Cell if your amounts are short) to match the height of the work description.

Updated Code Snippet:

// Work Section Header
$pdf->SetFont('Arial','',13);
$pdf->Cell(149,5,'Work Carried Out',1,0,'C');
$pdf->Cell(40,5,'Amount',1,1,'C'); // Use 1 here to move to next line after header

// Set consistent row height and widths
$rowHeight = 10;
$workColWidth = 149;
$amountColWidth = 40;
$pdf->SetFont('Arial','',12);

// First Work/Amount Pair
$currentY = $pdf->GetY(); // Save current vertical position
$pdf->MultiCell($workColWidth, $rowHeight, $work1, 1, 'C'); // Render work
$pdf->SetXY($workColWidth + 1, $currentY); // Jump back to original Y, move X to amount column
$pdf->MultiCell($amountColWidth, $rowHeight, $amount1, 1, 'C'); // Render amount

// Second Work/Amount Pair
$currentY = $pdf->GetY();
$pdf->MultiCell($workColWidth, $rowHeight, $work2, 1, 'C');
$pdf->SetXY($workColWidth + 1, $currentY);
$pdf->MultiCell($amountColWidth, $rowHeight, $amount2, 1, 'C');

// Third Work/Amount Pair
$currentY = $pdf->GetY();
$pdf->MultiCell($workColWidth, $rowHeight, $work3, 1, 'C');
$pdf->SetXY($workColWidth + 1, $currentY);
$pdf->MultiCell($amountColWidth, $rowHeight, $amount3, 1, 'C');

This ensures both columns stay aligned vertically, even if the work description wraps across multiple lines.


2. Add Print, Email Functionality & Optimize Storage

Direct PDF Printing

To let users print the PDF directly, use FPDF's Output() method with the 'I' parameter—this sends the PDF to the browser for inline viewing, where users can use their browser's print function:

// Replace your existing $pdf->Output(); line with this
$invoiceFilename = 'invoice_' . $invoiceId . '.pdf'; // Use a unique ID for the filename
$pdf->Output('I', $invoiceFilename);

Send PDF as Attachment via PHPMailer

Avoid saving PDFs to disk by generating the PDF as a string in memory, then attaching it directly to your email using PHPMailer's addStringAttachment() method. This cuts down on storage usage entirely for email sends.

Example Code:

// First, generate the PDF as a string (instead of outputting it)
$pdfContent = $pdf->Output('S');

// Initialize PHPMailer (make sure you've installed it via Composer or downloaded the files)
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/PHPMailer/src/Exception.php';
require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';

try {
    $mail = new PHPMailer(true);

    // Configure your SMTP settings
    $mail->isSMTP();
    $mail->Host = 'your-smtp-server.com'; // e.g., smtp.gmail.com
    $mail->SMTPAuth = true;
    $mail->Username = 'your-email@example.com';
    $mail->Password = 'your-email-password'; // Use app-specific password if using Gmail
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
    $mail->Port = 465;

    // Set sender and recipient
    $mail->setFrom('invoices@cheshirewestvehicles.com', 'Cheshire West Vehicle Ltd');
    $mail->addAddress($email, $firstname . ' ' . $lastname);

    // Email content
    $mail->isHTML(true);
    $mail->Subject = 'Your Invoice from Cheshire West Vehicle Ltd';
    $mail->Body = "<p>Hi {$firstname},<br><br>Please find your recent vehicle repair invoice attached.</p>";
    $mail->AltBody = "Hi {$firstname},\n\nPlease find your recent vehicle repair invoice attached.";

    // Attach the PDF from memory
    $mail->addStringAttachment($pdfContent, 'invoice_' . $invoiceId . '.pdf', 'base64', 'application/pdf');

    $mail->send();
    echo "Invoice sent to {$email} successfully!";
} catch (Exception $e) {
    echo "Failed to send invoice: {$mail->ErrorInfo}";
}

Storage Optimization

Instead of storing the full PDF file in your SQL database, consider storing only the raw data needed to generate the invoice (customer details, repair items, amounts, dates, etc.). This:

  • Uses far less storage space (text data is much smaller than PDF files)
  • Lets you regenerate the PDF anytime if you need to make changes
  • Eliminates the need to manage stale PDF files

If you must store PDFs, only keep them temporarily (e.g., for 30 days) or delete them after sending/printing, and always use unique filenames to avoid conflicts.


内容的提问来源于stack exchange,提问作者Mattex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:57:03