Skip to content

Commit

Permalink
Minor Changes to Writer/Mpdf and Writer/Html (#3645)
Browse files Browse the repository at this point in the history
* Minor Changes to Writer/Mpdf and Writer/Html

Changed a sample to illustrate how to add header/footer in Mpdf using setHtmlEditCallback. This uses custom Html tags, and, like body, it appears that these must be defined in the first writeHtml. Adjust writeMpdf to permit this by using a new constant `SIMULATED_BODY_START`, defined as an Html comment, as a delimiter.

Sample 21c_Pdf, to which the header/footer code is added, had been introduced with PR #2434 to ensure that the body tag was always in the first chunk. However, PR #3016 accidentally invalidated that test by reducing the number of style lines so that the sample now included the body tag in its first 1000 records rather than afterwards. This change puts it past record 1000 again.

Inspecting the results of all the Html/Pdf samples after this change, it turns out that sample 25_In_memory_image was accidentally broken by PR #3535 - the combination of `max-width:100%` (already present before that change) with `position:absolute` (introduced with that change) made the memory drawing disappear from the rendered html when the image occurs in a column after the last column with data in it. It appears that there is no need for max-width (drawings which are not memory drawings do not use it), so it is dropped. The sample is changed to add a second page with a memory drawing, one page with the memory drawing after the last data column, and one with it before. The Html results now reflect the Xlsx result, as they should.

* Minor Performance Improvements

Anonymous function.
  • Loading branch information
oleibman authored Jul 24, 2023
1 parent fb7b2ed commit 8a61429
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 17 deletions.
37 changes: 35 additions & 2 deletions samples/Basic/25_In_memory_image.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
use PhpOffice\PhpSpreadsheet\Writer\BaseWriter;

require __DIR__ . '/../Header.php';

// Create new Spreadsheet object
$helper->log('Create new Spreadsheet object');
$spreadsheet = new Spreadsheet();
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->setTitle('SheetWithData');
$sheet1->getCell('G1')->setValue('X');
$sheet1->getCell('E5')->setValue('Y');
$sheet1->getCell('A8')->setValue('Z');

// Set document properties
$helper->log('Set document properties');
Expand Down Expand Up @@ -38,8 +44,35 @@
$drawing->setRenderingFunction(MemoryDrawing::RENDERING_JPEG);
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
$drawing->setHeight(36);
$drawing->setWorksheet($spreadsheet->getActiveSheet());
$drawing->setWorksheet($sheet1);
$drawing->setCoordinates('C5');

$helper->log('Create new sheet');
$sheet2 = $spreadsheet->createSheet();
$sheet2->setTitle('SheetWithoutData');

// Add a drawing to the new worksheet
$helper->log('Add a drawing to the new worksheet');
$drawing = new MemoryDrawing();
$drawing->setName('Sample image');
$drawing->setDescription('Sample image');
$drawing->setImageResource($gdImage);
$drawing->setRenderingFunction(MemoryDrawing::RENDERING_JPEG);
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
$drawing->setHeight(36);
$drawing->setWorksheet($sheet2);
$drawing->setCoordinates('C5');

// Save
$helper->write($spreadsheet, __FILE__, ['Xlsx', 'Html']);
$helper->write(
$spreadsheet,
__FILE__,
['Xlsx', 'Html'],
false,
function (BaseWriter $writer): void {
if (method_exists($writer, 'writeAllSheets')) {
$writer->writeAllSheets();
}
}
);
$spreadsheet->disconnectWorksheets();
48 changes: 47 additions & 1 deletion samples/Pdf/21c_Pdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,52 @@

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf;

require __DIR__ . '/../Header.php';

// Issue 2432 - styles were too large to fit in first Mpdf chunk, causing problems.

function addHeadersFootersMpdf2000(string $html): string
{
$pagerepl = <<<EOF
@page page0 {
odd-header-name: html_myHeader1;
odd-footer-name: html_myFooter2;
EOF;
$html = preg_replace('/@page page0 {/', $pagerepl, $html);
$bodystring = '/<body>/';
$simulatedBodyStart = Mpdf::SIMULATED_BODY_START;
$bodyrepl = <<<EOF
<body>
<htmlpageheader name="myHeader1" style="display:none">
<div style="text-align: right; border-bottom: 1px solid #000000; font-weight: bold; font-size: 10pt;">
My document header
</div>
</htmlpageheader>
<htmlpagefooter name="myFooter2" style="display:none">
<table width="100%">
<tr>
<td width="33%">My document</td>
<td width="33%" align="center">Page {PAGENO} of {nbpg}</td>
<td width="33%" style="text-align: right;">{DATE Y-m-j}</td>
</tr>
</table>
</htmlpagefooter>
$simulatedBodyStart
EOF;

return preg_replace($bodystring, $bodyrepl, $html);
}

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$counter = 0;
$helper->log('Populate spreadsheet');
for ($row = 1; $row < 501; ++$row) {
for ($row = 1; $row < 1001; ++$row) {
$sheet->getCell("A$row")->setValue(++$counter);
// Add many styles by using slight variations of font color for each.
$sheet->getCell("A$row")->getStyle()->getFont()->getColor()->setRgb(sprintf('%06x', $counter));
Expand All @@ -21,4 +58,13 @@
$helper->log('Write to Mpdf');
IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
$helper->write($spreadsheet, __FILE__, ['Pdf']);
$helper->write(
$spreadsheet,
__FILE__,
['Pdf'],
false,
function (Mpdf $writer): void {
$writer->setEditHtmlCallback('addHeadersFootersMpdf2000');
}
);
$spreadsheet->disconnectWorksheets();
17 changes: 8 additions & 9 deletions src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,8 @@ public function generateSheetData()
$html .= $startTag;

// Write row if there are HTML table cells in it
if (!isset($this->isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) {
$mpdfInvisible = $this->isMPdf && $sheet->getRowDimension($row)->getVisible() === false;
if (!$mpdfInvisible && !isset($this->isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) {
// Start a new rowData
$rowData = [];
// Loop through columns
Expand Down Expand Up @@ -732,9 +733,14 @@ private function writeImageInCell(Worksheet $worksheet, $coordinates)

// Because of the nature of tables, width is more important than height.
// max-width: 100% ensures that image doesnt overflow containing cell
// However, PR #3535 broke test
// 25_In_memory_image, apparently because
// of the use of max-with. In addition,
// non-memory-drawings don't use max-width.
// Its use here is suspect and is being eliminated.
// width: X sets width of supplied image.
// As a result, images bigger than cell will be contained and images smaller will not get stretched
$html .= '<img alt="' . $filedesc . '" src="' . $dataUri . '" style="max-width:100%;width:' . $drawing->getWidth() . 'px;left: ' .
$html .= '<img alt="' . $filedesc . '" src="' . $dataUri . '" style="width:' . $drawing->getWidth() . 'px;left: ' .
$drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px;position: absolute; z-index: 1;" />';
}
}
Expand Down Expand Up @@ -1498,10 +1504,6 @@ private function generateRow(Worksheet $worksheet, array $values, $row, $cellTyp
// Sheet index
$sheetIndex = $worksheet->getParentOrThrow()->getIndex($worksheet);
$html = $this->generateRowStart($worksheet, $sheetIndex, $row);
$generateDiv = $this->isMPdf && $worksheet->getRowDimension($row + 1)->getVisible() === false;
if ($generateDiv) {
$html .= '<div style="visibility:hidden; display:none;">' . PHP_EOL;
}

// Write cells
$colNum = 0;
Expand Down Expand Up @@ -1546,9 +1548,6 @@ private function generateRow(Worksheet $worksheet, array $values, $row, $cellTyp
}

// Write row end
if ($generateDiv) {
$html .= '</div>' . PHP_EOL;
}
$html .= ' </tr>' . PHP_EOL;

// Return
Expand Down
18 changes: 13 additions & 5 deletions src/PhpSpreadsheet/Writer/Pdf/Mpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Pdf;

use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use PhpOffice\PhpSpreadsheet\Writer\Pdf;

class Mpdf extends Pdf
{
public const SIMULATED_BODY_START = '<!-- simulated body start -->';
private const BODY_TAG = '<body>';

/** @var bool */
protected $isMPdf = true;

Expand Down Expand Up @@ -61,16 +63,22 @@ public function save($filename, int $flags = 0): void
$pdf->SetCreator($this->spreadsheet->getProperties()->getCreator());

$html = $this->generateHTMLAll();
$bodyLocation = strpos($html, Html::BODY_LINE);
$bodyLocation = strpos($html, self::SIMULATED_BODY_START);
if ($bodyLocation === false) {
$bodyLocation = strpos($html, self::BODY_TAG);
if ($bodyLocation !== false) {
$bodyLocation += strlen(self::BODY_TAG);
}
}
// Make sure first data presented to Mpdf includes body tag
// (and any htmlpageheader/htmlpagefooter tags)
// so that Mpdf doesn't parse it as content. Issue 2432.
if ($bodyLocation !== false) {
$bodyLocation += strlen(Html::BODY_LINE);
$pdf->WriteHTML(substr($html, 0, $bodyLocation));
$html = substr($html, $bodyLocation);
}
foreach (\array_chunk(\explode(PHP_EOL, $html), 1000) as $lines) {
$pdf->WriteHTML(\implode(PHP_EOL, $lines));
foreach (explode("\n", $html) as $line) {
$pdf->WriteHTML("$line\n");
}

// Write to file
Expand Down

0 comments on commit 8a61429

Please sign in to comment.