Skip to content

Commit f5c96be

Browse files
authored
Merge pull request #2012 from dbarzin/develop
Add support for charts in template processor
2 parents 4e87e72 + dc9b1ed commit f5c96be

File tree

7 files changed

+111
-16
lines changed

7 files changed

+111
-16
lines changed

docs/templates-processing.rst

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,28 @@ See ``Sample_40_TemplateSetComplexValue.php`` for examples.
249249
$table->addCell(150)->addText('Cell B2');
250250
$table->addCell(150)->addText('Cell B3');
251251
$templateProcessor->setComplexBlock('table', $table);
252-
252+
253+
setChartValue
254+
"""""""""""""
255+
Replace a variable by a chart.
256+
257+
.. code-block:: php
258+
259+
$categories = array('A', 'B', 'C', 'D', 'E');
260+
$series1 = array(1, 3, 2, 5, 4);
261+
$chart = new Chart('doughnut', $categories, $series1);
262+
$templateProcessor->setChartValue('myChart', $chart);
263+
253264
save
254-
"""""""""
265+
""""
255266
Saves the loaded template within the current directory. Returns the file path.
256267

257268
.. code-block:: php
258269
259270
$filepath = $templateProcessor->save();
260271
261272
saveAs
262-
"""""""""
273+
""""""
263274
Saves a copy of the loaded template in the indicated path.
264275

265276
.. code-block:: php
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
use PhpOffice\PhpWord\Element\Chart;
3+
use PhpOffice\PhpWord\Shared\Converter;
4+
5+
include_once 'Sample_Header.php';
6+
7+
// Template processor instance creation
8+
echo date('H:i:s'), ' Creating new TemplateProcessor instance...', EOL;
9+
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('resources/Sample_41_TemplateSetChart.docx');
10+
11+
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
12+
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
13+
$threeSeries = array('bar', 'line');
14+
15+
$categories = array('A', 'B', 'C', 'D', 'E');
16+
$series1 = array(1, 3, 2, 5, 4);
17+
$series2 = array(3, 1, 7, 2, 6);
18+
$series3 = array(8, 3, 2, 5, 4);
19+
20+
$i = 0;
21+
foreach ($chartTypes as $chartType) {
22+
$chart = new Chart($chartType, $categories, $series1);
23+
24+
if (in_array($chartType, $twoSeries)) {
25+
$chart->addSeries($categories, $series2);
26+
}
27+
if (in_array($chartType, $threeSeries)) {
28+
$chart->addSeries($categories, $series3);
29+
}
30+
31+
$chart->getStyle()
32+
->setWidth(Converter::inchToEmu(3))
33+
->setHeight(Converter::inchToEmu(3));
34+
35+
$templateProcessor->setChart("chart{$i}", $chart);
36+
$i++;
37+
}
38+
39+
echo date('H:i:s'), ' Saving the result document...', EOL;
40+
$templateProcessor->saveAs('results/Sample_41_TemplateSetChart.docx');
41+
42+
echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_41_TemplateSetChart.docx');
43+
if (!CLI) {
44+
include_once 'Sample_Footer.php';
45+
}
Binary file not shown.

src/PhpWord/TemplateProcessor.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,46 @@ public function setValues(array $values)
355355
}
356356
}
357357

358+
/**
359+
* @param string $search
360+
* @param \PhpOffice\PhpWord\Element\AbstractElement $complexType
361+
*/
362+
public function setChart($search, \PhpOffice\PhpWord\Element\AbstractElement $chart)
363+
{
364+
$elementName = substr(get_class($chart), strrpos(get_class($chart), '\\') + 1);
365+
$objectClass = 'PhpOffice\\PhpWord\\Writer\\Word2007\\Element\\' . $elementName;
366+
367+
// Get the next relation id
368+
$rId = $this->getNextRelationsIndex($this->getMainPartName());
369+
$chart->setRelationId($rId);
370+
371+
// Define the chart filename
372+
$filename = "charts/chart{$rId}.xml";
373+
374+
// Get the part writer
375+
$writerPart = new \PhpOffice\PhpWord\Writer\Word2007\Part\Chart();
376+
$writerPart->setElement($chart);
377+
378+
// ContentTypes.xml
379+
$this->zipClass->addFromString("word/{$filename}", $writerPart->write());
380+
381+
// add chart to content type
382+
$xmlRelationsType = "<Override PartName=\"/word/{$filename}\" ContentType=\"application/vnd.openxmlformats-officedocument.drawingml.chart+xml\"/>";
383+
$this->tempDocumentContentTypes = str_replace('</Types>', $xmlRelationsType, $this->tempDocumentContentTypes) . '</Types>';
384+
385+
// Add the chart to relations
386+
$xmlChartRelation = "<Relationship Id=\"rId{$rId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart\" Target=\"charts/chart{$rId}.xml\"/>";
387+
$this->tempDocumentRelations[$this->getMainPartName()] = str_replace('</Relationships>', $xmlChartRelation, $this->tempDocumentRelations[$this->getMainPartName()]) . '</Relationships>';
388+
389+
// Write the chart
390+
$xmlWriter = new XMLWriter();
391+
$elementWriter = new $objectClass($xmlWriter, $chart, true);
392+
$elementWriter->write();
393+
394+
// Place it in the template
395+
$this->replaceXmlBlock($search, '<w:p>' . $xmlWriter->getData() . '</w:p>', 'w:p');
396+
}
397+
358398
private function getImageArgs($varNameWithArgs)
359399
{
360400
$varElements = explode(':', $varNameWithArgs);

src/PhpWord/Writer/Word2007/Part/Chart.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ private function writeSeries(XMLWriter $xmlWriter, $scatter = false)
219219
$colors = $style->getColors();
220220

221221
$index = 0;
222+
$colorIndex = 0;
222223
foreach ($series as $seriesItem) {
223224
$categories = $seriesItem['categories'];
224225
$values = $seriesItem['values'];
@@ -265,23 +266,21 @@ private function writeSeries(XMLWriter $xmlWriter, $scatter = false)
265266
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
266267
$this->writeSeriesItem($xmlWriter, 'val', $values);
267268

268-
// setting the chart colors was taken from https://github.com/PHPOffice/PHPWord/issues/494
269-
if (is_array($colors) && count($colors)) {
270-
// This is a workaround to make each series in a stack chart use a different color
271-
if ($this->options['type'] == 'bar' && stristr($this->options['grouping'], 'stacked')) {
272-
array_shift($colors);
273-
}
274-
$colorIndex = 0;
275-
foreach ($colors as $color) {
269+
// check that there are colors
270+
if (is_array($colors) && count($colors) > 0) {
271+
// assign a color to each value
272+
$valueIndex = 0;
273+
for ($i = 0; $i < count($values); $i++) {
274+
// check that there are still enought colors
276275
$xmlWriter->startElement('c:dPt');
277-
$xmlWriter->writeElementBlock('c:idx', 'val', $colorIndex);
276+
$xmlWriter->writeElementBlock('c:idx', 'val', $valueIndex);
278277
$xmlWriter->startElement('c:spPr');
279278
$xmlWriter->startElement('a:solidFill');
280-
$xmlWriter->writeElementBlock('a:srgbClr', 'val', $color);
279+
$xmlWriter->writeElementBlock('a:srgbClr', 'val', $colors[$colorIndex++ % count($colors)]);
281280
$xmlWriter->endElement(); // a:solidFill
282281
$xmlWriter->endElement(); // c:spPr
283282
$xmlWriter->endElement(); // c:dPt
284-
$colorIndex++;
283+
$valueIndex++;
285284
}
286285
}
287286
}

tests/PhpWord/TemplateProcessorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ public function testSetImageValue()
401401
return $imagePath;
402402
},
403403
'documentContent' => array('path' => $imagePath, 'width' => 500, 'height' => 500),
404-
'footerValue' => array('path' => $imagePath, 'width' => 100, 'height' => 50, 'ratio' => false),
404+
'footerValue' => array('path' => $imagePath, 'width' => 100, 'height' => 50, 'ratio' => false),
405405
);
406406
$templateProcessor->setImageValue(array_keys($variablesReplace), $variablesReplace);
407407

tests/PhpWord/Writer/Word2007/Element/ChartTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public function testChartElements()
113113
for ($idxp1 = 1; $idxp1 < $numColor; ++$idxp1) {
114114
$idx = $idxp1; // stacked bar chart is shifted
115115
$element = $path . "/c:ser/c:dPt[$idxp1]/c:spPr/a:solidFill/a:srgbClr";
116-
self::assertEquals($colorArray[$idx], $doc->getElementAttribute($element, 'val'), "bar chart idx=$idx");
116+
self::assertEquals($colorArray[$idx - 1], $doc->getElementAttribute($element, 'val'), "bar chart idx=$idx");
117117
}
118118
}
119119

0 commit comments

Comments
 (0)