Я недавно обновил свой Laravel проект с 5.6 до Laravel 6.2, я также обновил пакет dompdf с 0.8.3 до 0.8.5. Теперь мои PDF-файлы отображаются неправильно, они были правильно отображены в предыдущей версии Laravel и dompdf. Я сделал обновление до Laravel 5.8, прежде чем перейти к 6, но я не тестировал PDF. Я использую HTML таблицы для своего форматирования и встроенные CSS.
. В PDF таблицы обрезаются, правая часть убегает со страницы. Письма отображаются правильно.
Я попытался понизить версию dompdf с 0.8.5 до 0.8.3, но проблема остается. Я не совсем уверен, что мне нужно изменить, чтобы заставить его отображаться правильно. У меня есть пара других PDF-файлов, и все они делают то же самое, даже те, которые настроены на портрет. Приведенный ниже код установлен в альбомную ориентацию, но он игнорирует это и выполняет рендеринг в портретной ориентации.
Заранее благодарим за чтение этого супердлинного поста, любая помощь или конструктивная критика приветствуются!
Вот код контроллера:
/**
* email rental agreement (formats the email as the rental agreement and attaches a pdf)
*
* @param Request $request
* @param RentalAgreement $rentalAgreement
* @return \Illuminate\Http\Response
*/
public function email(Request $request, RentalAgreement $rentalAgreement)
{
$email_message = $request->email_message;
$email_subject = $request->email_subject;
$email_header = $headers = 'Content-Type: text/html; charset=UTF-8';
$address = $rentalAgreement->customer()->getDefaultAddress()->get()->first();
$array = $rentalAgreement->createEmailItems();
$rental = $array['rental'];
$details = $array['details'];
$company_phone = $array['company_phone'];
$contact_phone = $array['contact_phone'];
$emails = array_column(CustomerContactEmail::select('email')->whereIn('id', $request->email)
->get()->toArray(), 'email');
if (count((array)$emails) > 0) {
Mail::to($emails)->cc($rental->company_email)
->send(new RentalAgreementMail($address, $company_phone, $contact_phone, $rental, $details,
$email_message, $email_subject), $email_header);
$alert = 'Email sent.';
} else {
$alert = 'Unable to send email. Rental Agreement Contact has no email addresses. '
.'Assign email for contact to send email.';
}
return redirect()->action('RentalAgreementController@edit', ['rentalAgreement' => $rentalAgreement,
'customer' => $rentalAgreement->customer])
->with('alert', $alert);
}
Код почты:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use PDF;
class RentalAgreementMail extends Mailable
{
use Queueable, SerializesModels;
public $address;
public $company_phone;
public $contact_phone;
public $details;
public $email_message;
public $email_subject;
public $rental;
protected $pdf_file;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($address, $company_phone, $contact_phone, $rental, $details, $email_message, $email_subject)
{
$this->address = $address;
$this->company_phone = $company_phone;
$this->contact_phone = $contact_phone;
$this->rental = $rental;
$this->details = $details;
$this->email_message = $email_message;
$this->email_subject = '=?utf-8?B?'.base64_encode($email_subject).'?=';
$this->pdf_file = PDF::loadView('emails.rental_agreement', ['address' => $address,
'company_phone' => $company_phone,
'contact_phone' => $contact_phone,
'rental' => $rental, 'details' => $details])
->setPaper('letter', 'landscape')->stream();
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$title = $this->rental->customer_name.' '.$this->rental->type_name;
$title .= ' '.$this->rental->job_name;
$title .= !empty($this->rental->effective_date) ? ' '.$this->rental->effective_date->format('m-d-Y') : '';
return $this->from($this->rental->company_email, $this->rental->company_name)
->subject($this->email_subject)->view('emails.rental_agreement')
->attachData($this->pdf_file, $title.'.pdf', [
'mime' => 'application/pdf',
]);
}
}
Код HTML (проблема в теге 3-й таблицы):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=1'>
<title>{{ $rental->customer_name.' '.$rental->type_name }}</title>
</head>
<body>
@if (isset($email_message))
{!! nl2br(htmlspecialchars($email_message)) !!}
@endif
<table style='width: 100%; border-collapse: separate; border-spacing: 1px; margin: 0 0 5px 0;'>
<tbody>
<tr style='padding: 0;'>
<td style='width: 70%; padding: 0; margin: 0;'>
@if (!empty($rental->logo_path))
<!--img src="{{ asset($rental->logo_path) }}" height=125 style='margin: 0; padding: 0; display: block;' alt='logo' title='logo'/-->
@endif
</td>
<td colspan=2 style='width: 30%; padding: 0; text-align: center;'>
<h2 style='color: #4D6F6F; padding-top: 20px;'>{{ $rental->type_name }}</h2>
</td>
</tr>
<tr style='padding: 3px;'>
<td style='width: 70%; padding: 1px;'>{{ $rental->company_address }}</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>Job:</td>
<td style='width: 15%; padding: 1px;'>{{ $rental->job_name }}</td>
</tr>
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>{{ $rental->company_city.', '.$rental->company_state.' '.$rental->company_zip }}</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>Effective:</td>
<td style='width: 15%; padding: 1px;'>
{{ !empty($rental->effective_date) ? $rental->effective_date->format('m/d/Y') : '' }}
</td>
</tr>
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>{{ $company_phone }}</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>End:</td>
<td style='width: 15%; padding: 1px;'>
{{ !empty($rental->end_date) ? $rental->end_date->format('m/d/Y') : '' }}
</td>
</tr>
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>{{ $rental->company_email }}</td>
<td style='width: 15%; padding: 1px;'></td>
<td style='width: 15%; padding: 1px;'></td>
</tr>
</tbody>
</table>
<table style='border-collapse: separate; border-spacing: 1px; margin: 10px 0; padding-top: 15px; margin: auto; width: 97%;'>
<tbody>
<tr style='padding: 1px;'>
<td style='width: 70%; font-weight: bold; padding: 1px;'>
<h3 style='margin: 0; font-weight: bold;'>To: {{ $rental->customer_name }}</h3>
</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>
{{ empty($rental->po_number) ? '' : 'PO #:' }}
</td>
<td style='width: 15%; padding: 1px;'>
{{ empty($rental->po_number) ? '' : $rental->po_number }}
</td>
</tr>
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>
{{ $rental->contact_name.' '.$contact_phone }}
</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>Account #:</td>
<td style='width: 15%; padding: 1px;'>{{ $rental->customer_account_number }}</td>
</tr>
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>{{ isset($address) ? $address->address : '' }}</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>{{ empty($rental->ship_name) ? '' : 'Ship:' }}</td>
<td style='width: 15%; padding: 1px;'>
{{ empty($rental->ship_name) ? '' : $rental->ship_name }}
</td>
</tr>
@if (!empty($address) && !empty($address->address2))
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>{{ $address->address2 }}</td>
<td style='width: 15%; padding: 1px;'></td>
<td style='width: 15%; padding: 1px;'></td>
</tr>
@endif
<tr style='padding: 1px;'>
<td style='width: 70%; padding: 1px;'>
{{ isset($address) ? ($address->city.', '.$address->state.' '.$address->zip) : '' }}
</td>
<td style='width: 15%; font-weight: bold; padding: 1px;'>Term:</td>
<td style='width: 15%; padding: 1px;'>{{ $rental->net_term }}</td>
</tr>
</tbody>
</table>
<table style='width: 100%; border-collapse: collapse; border-spacing: 1px; margin: 15px 0 0 0; border-bottom: 2pt solid #4D6F6F;'>
<thead style='border-bottom: 2pt solid #4D6F6F;'>
<tr style='padding: 1px; font-size: .90em; color: #005187;'>
<th style='width: 5%; padding: 3px; text-align: center;'>#</th>
<th style='width: 5%; padding: 3px; text-align: center;'>Qty</th>
<th style='width: 75%; padding: 3px; text-align: center;'>
<table style='width: 100%; border-collapse: collapse; border-spacing: 1px; margin: 0 0 0 0;'>
<thead>
<tr>
<th style='width: 50%; padding: 3px;'>Description</th>
<th colspan=2 style='width: 30%; padding: 3px; text-align: center;'>Duration</th>
<th style='width: 20%; padding: 3px; text-align: center;'>Price</th>
</tr>
</thead>
</table>
</th>
<th style='width: 15%; padding: 3px; text-align: center;'>Total</th>
</tr>
</thead>
<tbody>
@foreach ($details as $detail)
<tr style='padding: 1px; font-size: .90em;'>
<td style='width: 5%; border-bottom: 1pt solid #4D6F6F; padding: 3px; text-align: center; vertical-align: top;'>
{{ number_format($detail->line_number, 0, '.', ',') }}
</td>
<td style='width: 5%; border-bottom: 1pt solid #4D6F6F; padding: 3px; text-align: center; vertical-align: top;'>
{{ number_format($detail->quantity, 0, '.', ',') }}
</td>
<td style='width: 75%; border-bottom: 1pt solid #4D6F6F; padding: 3px; vertical-align: top;'>
<table style='width: 100%; border-collapse: collapse; border-spacing: 1px; margin: 0 0 0 0;'>
<tbody>
<tr style='padding: 1px;'>
<td style='width: 50%; padding: 3px;'>{{ $detail->item_description }}</td>
<td style='width: 15%; padding: 3px; text-align: center; vertical-align: top;'>
{{ !empty($detail->billing_start_date) ? $detail->billing_start_date->format('m/d/Y') : '' }}
</td>
<td style='width: 15%; padding: 3px; text-align: center; vertical-align: top;'>
{{ !empty($detail->billing_end_date) ? $detail->billing_end_date->format('m/d/Y') : '' }}
</td>
<td style='width: 20%; padding: 3px; text-align: right; vertical-align: top;'>
{{ number_format($detail->item_price, 2, '.', ',') }}
</td>
</tr>
@if (count($detail->itemTypeAccessories) > 0)
<tr style='padding: 1px; color: #005187;'>
<td style='width: 50%; border-bottom: 1pt solid #C0CAD3; padding: 3px; vertical-align: top; font-weight: bold;'>
Accessories
</td>
<td colspan=3 style='width: 50%; padding: 3px;'></td>
</tr>
<tr style='padding: 1px;'>
<td style='width: 50%; padding: 3px; vertical-align: top;'>
{{ implode(', ', $detail->itemTypeAccessories->map(function ($item, $key) { return $item->name;})->toArray()) }}
</td>
<td colspan=2 style='width: 30%; padding: 3px;'></td>
<td style='width: 20%; padding: 3px; text-align: right; vertical-align: top;'>
<?php $accessory_price = 0; ?>
@foreach($detail->itemTypeAccessories as $accessory)
<?php $accessory_price += $accessory->pivot->price; ?>
@endforeach
{{ number_format($accessory_price, 2, '.', ',') }}
</td>
</tr>
@endif
@if (count($detail->itemTypeServices) > 0)
<tr style='padding: 1px; color: #005187;'>
<td style='width: 50%; border-bottom: 1pt solid #C0CAD3; padding: 3px; vertical-align: top; font-weight: bold;'>
Services
</td>
<td colspan=3 style='width: 50%; padding: 3px;'></td>
</tr>
@foreach ($detail->itemTypeServices as $service)
<tr style='padding: 1px;'>
<td style='width: 50%; padding: 3px; vertical-align: top;'>
{{ $service->name }}
</td>
<td style='width: 15%; padding: 3px; text-align: center; vertical-align: top;'>
{{ empty($service->pivot->delivery_date) ? '' : ' '.$service->pivot->delivery_date->format('m/d/Y') }}
</td>
<td style='width: 15%; padding: 3px; text-align: center; vertical-align: top;'>
{{ empty($service->pivot->pickup_date) ? '' : $service->pivot->pickup_date->format('m/d/Y') }}
</td>
<td style='width: 20%; padding: 3px; text-align: right; vertical-align: top;'>
{{ number_format((float)$service->pivot->delivery_price + (float)$service->pivot->pickup_price, 2, '.', ',') }}
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
</td>
<td style='width: 15%; border-bottom: 1pt solid #4D6F6F; padding: 3px; text-align: right; vertical-align: top;'>
{{ number_format($detail->subtotal, 2, '.', ',') }}
</td>
</tr>
@endforeach
</tbody>
</table>
<table style='width: 100%; border-collapse: collapse; border-spacing: 1px; margin: 0;'>
<tbody>
<tr style='padding: 1px; font-size: .90em; font-weight: bold;'>
<th style='width: 5%; padding: 3px;'> </th>
<th style='width: 5%; padding: 3px;'> </th>
<th style='width: 75%; padding: 3px;'> </th>
<th style='width: 15%; padding: 3px;'> </th>
</tr>
<tr style='padding: 1px; font-size: .90em; font-weight: bold;'>
<td colspan=2 style='width: 10%; padding: 3px;'></td>
<td style='width: 75%; padding: 3px; text-align: right;'>Subtotal </td>
<td style='width: 15%; padding: 3px; text-align: right;'>
{{ number_format($rental->subtotal, 2, '.', ',') }}
</td>
</tr>
<tr style='padding: 1px; font-size: .90em; font-weight: bold;'>
<td colspan=2 style='width: 10%; padding: 3px;'></td>
<td style='width: 75%; padding: 3px; text-align: right;'>Tax </td>
<td style='width: 15%; padding: 3px; text-align: right;'>
{{ number_format($rental->tax_amount, 2, '.', ',') }}
</td>
</tr>
<tr style='padding: 1px; font-size: .90em; font-weight: bold;'>
<td colspan=2 style='width: 10%; padding: 3px;'></td>
<td style='width: 75%; padding: 3px; text-align: right;'>
Total
</td>
<td style='width: 15%; border-top: 2pt solid #4D6F6F; padding: 3px; text-align: right;'>
{{ number_format($rental->total, 2, '.', ',') }}
</td>
</tr>
</tbody>
</table>
<?php $terms_count = 0; ?>
@if (!empty($rental->purchase_order_terms))
<p style='font-size: .90em; font-weight: bold;'>PO Terms:</p>
<p style='font-size: .90em;'>{!! nl2br(e($rental->purchase_order_terms)) !!}</p>
<?php $terms_count += 1;?>
@endif
@if (!empty($rental->customer_terms_conditions))
@if ($terms_count == 0)
<p style='font-size: .90em; font-weight: bold;'>
@else
<p style='font-size: .90em; font-weight: bold; border-top: 1pt solid #4D6F6F;'>
@endif
Customer Terms:</p>
<p style='font-size: .90em;'>{!! nl2br(e($rental->customer_terms_conditions)) !!}</p>
<?php $terms_count += 1;?>
@endif
@if (!empty($rental->rental_agreement_terms))
@if ($terms_count == 0)
<p style='font-size: .90em; font-weight: bold;'>
@else
<p style='font-size: .90em; font-weight: bold; border-top: 1pt solid #4D6F6F;'>
@endif
Rental Terms:</p>
<p style='font-size: .90em;'>{!! nl2br(e($rental->rental_agreement_terms)) !!}</p>
<?php $terms_count += 1;?>
@endif
@if (!empty($rental->notes))
@if ($terms_count == 0)
<p style='font-size: .90em; font-weight: bold;'>
@else
<p style='font-size: .90em; font-weight: bold; border-top: 1pt solid #4D6F6F;'>
@endif
Notes:</p>
<p style='font-size: .90em;'>{!! nl2br(e($rental->notes)) !!}</p>
<?php $terms_count += 1;?>
@endif
<table style='width: 97%; border-collapse: separate; border-spacing: 1px; margin: 15px 0; margin: auto;'>
<tbody>
<tr rowspan=2 style='padding: 3px;'>
<td colspan=3 style='width: 60%; font-weight: bold; padding: 3px;'></td>
</tr>
<tr style='padding: 3px;'>
<td style='width: 10%; font-weight: bold; padding: 3px; text-align: right;'>
Customer Signature:
</td>
<td style='width: 40%; font-weight: bold; padding: 3px; border-bottom: 1pt solid #4D6F6F;'></td>
<td style='width: 10%; font-weight: bold; padding: 3px;'></td>
</tr>
<tr style='padding: 3px;'>
<td colspan=3 style='width: 60%; font-weight: bold; padding: 3px; text-align: center;'></td>
</tr>
<tr style='padding: 3px;'>
<td colspan=3 style='width: 60%; font-weight: bold; padding: 3px; text-align: center;'></td>
</tr>
<tr style='padding: 3px;'>
<td colspan=3 style='width: 60%; font-weight: bold; padding: 3px; text-align: center;'></td>
</tr>
<tr style='padding: 3px;'>
<td colspan=3 style='width: 60%; font-weight: bold; padding: 3px; text-align: center;'>
We appreciate your business.
</td>
</tr>
</tbody>
</table>
</body>
</html>
Здесь это электронная почта: ![enter image description here](https://i.stack.imgur.com/LvlsE.jpg)
Вот PDF: ![enter image description here](https://i.stack.imgur.com/tdwXQ.jpg)