Skip to content

Add ability to save edited Html/Pdf #1499

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jun 28, 2020
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions docs/topics/reading-and-writing-to-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ $sty = $writer->generateStyles(false); // do not write <style> and </style>
$newstyle = <<<EOF
<style type='text/css'>
$sty
html {
body {
background-color: yellow;
}
</style>
Expand All @@ -703,16 +703,22 @@ echo $writer->generateSheetData();
echo $writer->generateHTMLFooter();
```

#### Writing UTF-8 HTML files
#### Editing HTML during save via a callback

A HTML file can be marked as UTF-8 by writing a BOM file header. This
can be enabled by using the following code:
You can also add a callback function to edit the generated html
before saving. For example, you could change the gridlines
from a thin solid black line:

```php
``` php
function changeGridlines(string $html): string
{
return str_replace('{border: 1px solid black;}',
'{border: 2px dashed red;}',
$html);
}
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->setUseBOM(true);

$writer->save("05featuredemo.htm");
$writer->setEditHtmlCallback('changeGridlines');
$writer->save($filename);
```

#### Decimal and thousands separators
Expand Down Expand Up @@ -841,6 +847,12 @@ $writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.pdf");
```

#### Editing Pdf during save via a callback

You can also add a callback function to edit the html used to
generate the Pdf before saving.
[See under Html](#editing-html-during-save-via-a-callback).

#### Decimal and thousands separators

See section `\PhpOffice\PhpSpreadsheet\Writer\Csv` how to control the
Expand Down
20 changes: 20 additions & 0 deletions samples/Basic/17b_Html.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

use PhpOffice\PhpSpreadsheet\Writer\Html;

require __DIR__ . '/../Header.php';
$spreadsheet = require __DIR__ . '/../templates/sampleSpreadsheet.php';

$filename = $helper->getFilename(__FILE__, 'html');
$writer = new Html($spreadsheet);

function changeGridlines(string $html): string
{
return str_replace('{border: 1px solid black;}', '{border: 2px dashed red;}', $html);
}

$callStartTime = microtime(true);
$writer->setEmbedImages(true);
$writer->setEditHtmlCallback('changeGridlines');
$writer->save($filename);
$helper->logWrite($writer, $filename, $callStartTime);
25 changes: 25 additions & 0 deletions samples/Pdf/21a_Pdf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

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

require __DIR__ . '/../Header.php';
$spreadsheet = require __DIR__ . '/../templates/sampleSpreadsheet.php';

$helper->log('Hide grid lines');
$spreadsheet->getActiveSheet()->setShowGridLines(false);

$helper->log('Set orientation to landscape');
$spreadsheet->getActiveSheet()->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
$spreadsheet->setActiveSheetIndex(0)->setPrintGridlines(true);

function changeGridlines(string $html): string
{
return str_replace('{border: 1px solid black;}', '{border: 2px dashed red;}', $html);
}

$helper->log('Write to Mpdf');
$writer = new Mpdf($spreadsheet);
$filename = $helper->getFileName('21a_Pdf_mpdf.xlsx', 'pdf');
$writer->setEditHtmlCallback('changeGridlines');
$writer->save($filename);
51 changes: 51 additions & 0 deletions samples/Pdf/21b_Pdf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf;

function replaceBody(string $html): string
{
$lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
$bodystring = '@<body>.*</body>@ms';
$bodyrepl = <<<EOF
<body>
<h1>Serif</h1>
<p style='font-family: serif; font-size: 12pt;'>$lorem</p>
<h1>Sans-Serif</h1>
<p style='font-family: sans-serif; font-size: 12pt;'>$lorem</p>
<h1>Monospace</h1>
<p style='font-family: monospace; font-size: 12pt;'>$lorem</p>
</body>
EOF;

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

require __DIR__ . '/../Header.php';
$spreadsheet = require __DIR__ . '/../templates/sampleSpreadsheet.php';

$helper->log('Hide grid lines');
$spreadsheet->getActiveSheet()->setShowGridLines(false);

$helper->log('Set orientation to landscape');
$spreadsheet->getActiveSheet()->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);

$helper->log('Write to Dompdf');
$writer = new Dompdf($spreadsheet);
$filename = $helper->getFileName('21b_Pdf_dompdf.xlsx', 'pdf');
$writer->setEditHtmlCallback('replaceBody');
$writer->save($filename);

$helper->log('Write to Mpdf');
$writer = new Mpdf($spreadsheet);
$filename = $helper->getFileName('21b_Pdf_mpdf.xlsx', 'pdf');
$writer->setEditHtmlCallback('replaceBody');
$writer->save($filename);

$helper->log('Write to Tcpdf');
$writer = new Tcpdf($spreadsheet);
$filename = $helper->getFileName('21b_Pdf_tcpdf.xlsx', 'pdf');
$writer->setEditHtmlCallback('replaceBody');
$writer->save($filename);
16 changes: 16 additions & 0 deletions src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ class Html extends BaseWriter
*/
private $generateSheetNavigationBlock = true;

/**
* Callback for editing generated html.
*
* @var null|callable
*/
protected $editHtmlCallback;

/**
* Create a new HTML.
*/
Expand Down Expand Up @@ -190,13 +197,22 @@ public function generateHtmlAll()

// Write footer
$html .= $this->generateHTMLFooter();
$callback = $this->editHtmlCallback;
if ($callback) {
$html = $callback($html);
}

Calculation::setArrayReturnType($saveArrayReturnType);
Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);

return $html;
}

public function setEditHtmlCallback(?callable $cbk): void
{
$this->editHtmlCallback = $cbk;
}

const VALIGN_ARR = [
Alignment::VERTICAL_BOTTOM => 'bottom',
Alignment::VERTICAL_TOP => 'top',
Expand Down
53 changes: 53 additions & 0 deletions tests/PhpSpreadsheetTests/Writer/Html/CallbackTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace PhpOffice\PhpSpreadsheetTests\Writer\Html;

use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use PhpOffice\PhpSpreadsheetTests\Functional;

class CallbackTest extends Functional\AbstractFunctional
{
public function yellowBody(string $html): string
{
$newstyle = <<<EOF
<style type='text/css'>
body {
background-color: yellow;
}
</style>

EOF;

return preg_replace('@</head>@', "$newstyle</head>", $html);
}

public function testSetAndReset(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', '1');

$writer = new Html($spreadsheet);
$html1 = $writer->generateHTMLall();
$writer->setEditHtmlCallback([$this, 'yellowBody']);
$html2 = $writer->generateHTMLall();
$writer->setEditHtmlCallback(null);
$html3 = $writer->generateHTMLall();

self::assertFalse(strpos($html1, 'background-color: yellow'));
self::assertNotFalse(strpos($html2, 'background-color: yellow'));
self::assertFalse(strpos($html3, 'background-color: yellow'));
self::assertEquals($html3, $html1);

$writer->setEditHtmlCallback([$this, 'yellowBody']);
$oufil = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test');
$writer->save($oufil);
$html4 = file_get_contents($oufil);
unlink($oufil);
self::assertNotFalse(strpos($html4, 'background-color: yellow'));

$this->writeAndReload($spreadsheet, 'Html');
}
}