Skip to content

Commit

Permalink
feat: Поддержка колонтитулов
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaly.erofeev committed Aug 1, 2022
1 parent 3f48a53 commit 29e5e72
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .phpunit.result.cache
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":1,"defects":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":3,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":3},"times":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":0.0070000000000000001,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testXmlToString":0.0089999999999999993,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetDocx":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetXml":0.0089999999999999993,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testPatchXml":0.0030000000000000001,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRenderXml":0.031,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRender":0.048000000000000001,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testLineBreak":0.0030000000000000001,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testCyrillic":0.0080000000000000002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testForLoop":0.0060000000000000001,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":2.1389999999999998}}
{"version":1,"defects":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":3,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":4,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testSections":3},"times":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":0.008,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testXmlToString":0.005,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetDocx":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetXml":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testPatchXml":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRenderXml":0.014,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRender":0.007,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testLineBreak":0.003,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testCyrillic":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testForLoop":0.006,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":0.788,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testSections":0.009}}
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
"email": "[email protected]"
}],
"config": {
"vendor-dir": "./vendor"
"vendor-dir": "./vendor",
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"require": {
"ext-zip": "*",
Expand Down
46 changes: 46 additions & 0 deletions src/DocxDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class DocxDocument
private $tempDocumentRelations = [];
private $tempDocumentContentTypes = '';
private $tempDocumentNewImages = [];
private $tempDocumentHeaders = [];
private $tempDocumentFooters = [];

/**
* Construct an instance of Document
Expand Down Expand Up @@ -58,6 +60,17 @@ private function extract(): void
$this->zipClass->open($this->path);
$this->zipClass->extractTo($this->tmpDir);

$index = 1;
while (false !== $this->zipClass->locateName($this->getHeaderName($index))) {
$this->tempDocumentHeaders[$index] = $this->readPartWithRels($this->getHeaderName($index));
$index++;
}
$index = 1;
while (false !== $this->zipClass->locateName($this->getFooterName($index))) {
$this->tempDocumentFooters[$index] = $this->readPartWithRels($this->getFooterName($index));
$index++;
}

$this->tempDocumentMainPart = $this->readPartWithRels($this->getMainPartName());

$this->tempDocumentContentTypes = $this->zipClass->getFromName($this->getDocumentContentTypesName());
Expand All @@ -75,6 +88,32 @@ public function getDocumentMainPart(): string
return $this->tempDocumentMainPart;
}

/**
* @return array
*/
public function getHeaders(): array
{
return $this->tempDocumentHeaders;
}

/**
* @return array
*/
public function getFooters(): array
{
return $this->tempDocumentFooters;
}

public function setHeaders(array $headers): void
{
$this->tempDocumentHeaders = $headers;
}

public function setFooters(array $footers): void
{
$this->tempDocumentFooters = $footers;
}

/**
* Get the name of main part document (method from PhpOffice\PhpWord)
*
Expand Down Expand Up @@ -636,6 +675,13 @@ public function save(string $path): void
$this->savePartWithRels($this->getMainPartName());
file_put_contents($this->tmpDir . DIRECTORY_SEPARATOR . $this->getDocumentContentTypesName(), $this->tempDocumentContentTypes);

foreach ($this->tempDocumentHeaders as $index => $xml) {
file_put_contents($this->tmpDir . DIRECTORY_SEPARATOR . $this->getHeaderName($index), $xml);
}
foreach ($this->tempDocumentFooters as $index => $xml) {
file_put_contents($this->tmpDir . DIRECTORY_SEPARATOR . $this->getFooterName($index), $xml);
}

$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootPath),
RecursiveIteratorIterator::LEAVES_ONLY
Expand Down
18 changes: 17 additions & 1 deletion src/PhpDocxTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,6 @@ private function renderXml(string $srcXml, array $context): string
);
$template->addExtension($ext);


$dstXml = $template->render('index', $context);

$dstXml = str_replace(
Expand Down Expand Up @@ -476,6 +475,9 @@ public function render(array $context): void
$xmlSrc = $this->buildXml($context);
$newXml = $this->docx->fixTables($xmlSrc);
$this->updateXml($newXml);

$this->renderHeaders($context);
$this->renderFooters($context);
}

/**
Expand All @@ -490,6 +492,20 @@ public function save(string $path): void
//$this->postProcessing($path);
}

public function renderHeaders(array $context): void
{
$this->docx->setHeaders(array_map(function ($header) use ($context) {
return $this->renderXml($header, $context);
}, $this->docx->getHeaders()));
}

public function renderFooters(array $context): void
{
$this->docx->setFooters(array_map(function ($footer) use ($context) {
return $this->renderXml($footer, $context);
}, $this->docx->getFooters()));
}

/**
* Clean everything after rendering
*/
Expand Down
88 changes: 88 additions & 0 deletions tests/PhpDocxTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class PhpDocxTemplateTest extends TestCase
private const TEMPLATE4 = __DIR__ . "/templates/template4.docx";
private const TEMPLATE5 = __DIR__ . "/templates/template5.docx";
private const TEMPLATE8 = __DIR__ . "/templates/template8.docx";
private const TEMPLATE9 = __DIR__ . "/templates/template9.docx";

public function testXmlToString(): void
{
Expand Down Expand Up @@ -749,4 +750,91 @@ public function testImages(): void

$this->assertNotEmpty($expectedImage, 'Embed image doesn\'t found.');
}

public function testSections(): void
{
$reporter = new PhpDocxTemplate(self::TEMPLATE9);
/* $this->assertEquals(
$reporter->buildXml(["object" => "world"]),
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" .
"<w:document xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" " .
"xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" " .
"xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" " .
"xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" " .
"xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" " .
"xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" " .
"xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" " .
"xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" " .
"xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" " .
"xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" " .
"xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" " .
"xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" " .
"xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" " .
"xmlns:o=\"urn:schemas-microsoft-com:office:office\" " .
"xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" " .
"xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" " .
"xmlns:v=\"urn:schemas-microsoft-com:vml\" " .
"xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" " .
"xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" " .
"xmlns:w10=\"urn:schemas-microsoft-com:office:word\" " .
"xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" " .
"xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" " .
"xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" " .
"xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" " .
"xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" " .
"xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" " .
"xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" " .
"xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" " .
"xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" " .
"mc:Ignorable=\"w14 w15 w16se w16cid wp14\"><w:body><w:p w14:paraId=\"504F2588\" " .
"w14:textId=\"54DF26C8\" w:rsidR=\"0090657C\" w:rsidRPr=\"00FA3F61\" " .
"w:rsidRDefault=\"00FA3F61\" w:rsidP=\"00C13DD6\"><w:pPr><w:rPr><w:lang w:val=\"en-US\"/>" .
"</w:rPr></w:pPr><w:r><w:rPr><w:lang w:val=\"en-US\"/></w:rPr><w:t>Hello world!</w:t>" .
"</w:r><w:bookmarkStart w:id=\"0\" w:name=\"_GoBack\"/><w:bookmarkEnd w:id=\"0\"/></w:p>" .
"<w:sectPr w:rsidR=\"0090657C\" w:rsidRPr=\"00FA3F61\"><w:pgSz w:w=\"11906\" w:h=\"16838\"/>" .
"<w:pgMar w:top=\"1134\" w:right=\"850\" w:bottom=\"1134\" w:left=\"1701\" w:header=\"708\" " .
"w:footer=\"708\" w:gutter=\"0\"/><w:cols w:space=\"708\"/><w:docGrid w:linePitch=\"360\"/>" .
"</w:sectPr></w:body></w:document>\n"
);*/
$docName = './doc9.docx';
$reporter->render(["object" => "test", "section" => [["id" => "test section"]]]);
$reporter->save($docName);
// $reporter->close();

$expectedDocumentZip = new ZipArchive();
$expectedDocumentZip->open($docName);
$header = $expectedDocumentZip->getFromName('word/header2.xml');
$this->assertEquals('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . PHP_EOL .
'<w:hdr xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" ' .
'xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1=' .
'"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http:' .
'//schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://sche' .
'mas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.micro' .
'soft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/' .
'office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/dra' .
'wing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5' .
'/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex' .
'" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="h' .
'ttp://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.micros' .
'oft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office"' .
' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m' .
'="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-mic' .
'rosoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessi' .
'ngDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDr' .
'awing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openx' .
'mlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/offi' .
'ce/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" ' .
'xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="' .
'http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.mi' .
'crosoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/offi' .
'ce/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word' .
'/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordproce' .
'ssingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk' .
'" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://s' .
'chemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se' .
' w16cid w16 w16cex w16sdtdh wp14"><w:p w14:paraId="41482033" w14:textId="76B90B7C" w:r' .
'sidR="0023643A" w:rsidRPr="008D02AA" w:rsidRDefault="0023643A" w:rsidP="008D02AA"><w:r' .
' w:rsidRPr="008D02AA"><w:t xml:space="preserve">Opa </w:t></w:r><w:r w:rsidR="00AB4EBE' .
'" w:rsidRPr="00AB4EBE"><w:t>test section</w:t></w:r></w:p></w:hdr>', $header);
}
}
Binary file modified tests/templates/image.docx
Binary file not shown.
Binary file added tests/templates/template9.docx
Binary file not shown.

0 comments on commit 29e5e72

Please sign in to comment.