Merge pull request #2012 from dbarzin/develop
Add support for charts in template processor
This commit is contained in:
commit
f5c96beedd
|
|
@ -250,8 +250,19 @@ See ``Sample_40_TemplateSetComplexValue.php`` for examples.
|
||||||
$table->addCell(150)->addText('Cell B3');
|
$table->addCell(150)->addText('Cell B3');
|
||||||
$templateProcessor->setComplexBlock('table', $table);
|
$templateProcessor->setComplexBlock('table', $table);
|
||||||
|
|
||||||
|
setChartValue
|
||||||
|
"""""""""""""
|
||||||
|
Replace a variable by a chart.
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||||
|
$series1 = array(1, 3, 2, 5, 4);
|
||||||
|
$chart = new Chart('doughnut', $categories, $series1);
|
||||||
|
$templateProcessor->setChartValue('myChart', $chart);
|
||||||
|
|
||||||
save
|
save
|
||||||
"""""""""
|
""""
|
||||||
Saves the loaded template within the current directory. Returns the file path.
|
Saves the loaded template within the current directory. Returns the file path.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
@ -259,7 +270,7 @@ Saves the loaded template within the current directory. Returns the file path.
|
||||||
$filepath = $templateProcessor->save();
|
$filepath = $templateProcessor->save();
|
||||||
|
|
||||||
saveAs
|
saveAs
|
||||||
"""""""""
|
""""""
|
||||||
Saves a copy of the loaded template in the indicated path.
|
Saves a copy of the loaded template in the indicated path.
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
use PhpOffice\PhpWord\Element\Chart;
|
||||||
|
use PhpOffice\PhpWord\Shared\Converter;
|
||||||
|
|
||||||
|
include_once 'Sample_Header.php';
|
||||||
|
|
||||||
|
// Template processor instance creation
|
||||||
|
echo date('H:i:s'), ' Creating new TemplateProcessor instance...', EOL;
|
||||||
|
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('resources/Sample_41_TemplateSetChart.docx');
|
||||||
|
|
||||||
|
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
|
||||||
|
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
|
||||||
|
$threeSeries = array('bar', 'line');
|
||||||
|
|
||||||
|
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||||
|
$series1 = array(1, 3, 2, 5, 4);
|
||||||
|
$series2 = array(3, 1, 7, 2, 6);
|
||||||
|
$series3 = array(8, 3, 2, 5, 4);
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach ($chartTypes as $chartType) {
|
||||||
|
$chart = new Chart($chartType, $categories, $series1);
|
||||||
|
|
||||||
|
if (in_array($chartType, $twoSeries)) {
|
||||||
|
$chart->addSeries($categories, $series2);
|
||||||
|
}
|
||||||
|
if (in_array($chartType, $threeSeries)) {
|
||||||
|
$chart->addSeries($categories, $series3);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chart->getStyle()
|
||||||
|
->setWidth(Converter::inchToEmu(3))
|
||||||
|
->setHeight(Converter::inchToEmu(3));
|
||||||
|
|
||||||
|
$templateProcessor->setChart("chart{$i}", $chart);
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo date('H:i:s'), ' Saving the result document...', EOL;
|
||||||
|
$templateProcessor->saveAs('results/Sample_41_TemplateSetChart.docx');
|
||||||
|
|
||||||
|
echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_41_TemplateSetChart.docx');
|
||||||
|
if (!CLI) {
|
||||||
|
include_once 'Sample_Footer.php';
|
||||||
|
}
|
||||||
Binary file not shown.
|
|
@ -355,6 +355,46 @@ class TemplateProcessor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $search
|
||||||
|
* @param \PhpOffice\PhpWord\Element\AbstractElement $complexType
|
||||||
|
*/
|
||||||
|
public function setChart($search, \PhpOffice\PhpWord\Element\AbstractElement $chart)
|
||||||
|
{
|
||||||
|
$elementName = substr(get_class($chart), strrpos(get_class($chart), '\\') + 1);
|
||||||
|
$objectClass = 'PhpOffice\\PhpWord\\Writer\\Word2007\\Element\\' . $elementName;
|
||||||
|
|
||||||
|
// Get the next relation id
|
||||||
|
$rId = $this->getNextRelationsIndex($this->getMainPartName());
|
||||||
|
$chart->setRelationId($rId);
|
||||||
|
|
||||||
|
// Define the chart filename
|
||||||
|
$filename = "charts/chart{$rId}.xml";
|
||||||
|
|
||||||
|
// Get the part writer
|
||||||
|
$writerPart = new \PhpOffice\PhpWord\Writer\Word2007\Part\Chart();
|
||||||
|
$writerPart->setElement($chart);
|
||||||
|
|
||||||
|
// ContentTypes.xml
|
||||||
|
$this->zipClass->addFromString("word/{$filename}", $writerPart->write());
|
||||||
|
|
||||||
|
// add chart to content type
|
||||||
|
$xmlRelationsType = "<Override PartName=\"/word/{$filename}\" ContentType=\"application/vnd.openxmlformats-officedocument.drawingml.chart+xml\"/>";
|
||||||
|
$this->tempDocumentContentTypes = str_replace('</Types>', $xmlRelationsType, $this->tempDocumentContentTypes) . '</Types>';
|
||||||
|
|
||||||
|
// Add the chart to relations
|
||||||
|
$xmlChartRelation = "<Relationship Id=\"rId{$rId}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart\" Target=\"charts/chart{$rId}.xml\"/>";
|
||||||
|
$this->tempDocumentRelations[$this->getMainPartName()] = str_replace('</Relationships>', $xmlChartRelation, $this->tempDocumentRelations[$this->getMainPartName()]) . '</Relationships>';
|
||||||
|
|
||||||
|
// Write the chart
|
||||||
|
$xmlWriter = new XMLWriter();
|
||||||
|
$elementWriter = new $objectClass($xmlWriter, $chart, true);
|
||||||
|
$elementWriter->write();
|
||||||
|
|
||||||
|
// Place it in the template
|
||||||
|
$this->replaceXmlBlock($search, '<w:p>' . $xmlWriter->getData() . '</w:p>', 'w:p');
|
||||||
|
}
|
||||||
|
|
||||||
private function getImageArgs($varNameWithArgs)
|
private function getImageArgs($varNameWithArgs)
|
||||||
{
|
{
|
||||||
$varElements = explode(':', $varNameWithArgs);
|
$varElements = explode(':', $varNameWithArgs);
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,7 @@ class Chart extends AbstractPart
|
||||||
$colors = $style->getColors();
|
$colors = $style->getColors();
|
||||||
|
|
||||||
$index = 0;
|
$index = 0;
|
||||||
|
$colorIndex = 0;
|
||||||
foreach ($series as $seriesItem) {
|
foreach ($series as $seriesItem) {
|
||||||
$categories = $seriesItem['categories'];
|
$categories = $seriesItem['categories'];
|
||||||
$values = $seriesItem['values'];
|
$values = $seriesItem['values'];
|
||||||
|
|
@ -265,23 +266,21 @@ class Chart extends AbstractPart
|
||||||
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
|
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
|
||||||
$this->writeSeriesItem($xmlWriter, 'val', $values);
|
$this->writeSeriesItem($xmlWriter, 'val', $values);
|
||||||
|
|
||||||
// setting the chart colors was taken from https://github.com/PHPOffice/PHPWord/issues/494
|
// check that there are colors
|
||||||
if (is_array($colors) && count($colors)) {
|
if (is_array($colors) && count($colors) > 0) {
|
||||||
// This is a workaround to make each series in a stack chart use a different color
|
// assign a color to each value
|
||||||
if ($this->options['type'] == 'bar' && stristr($this->options['grouping'], 'stacked')) {
|
$valueIndex = 0;
|
||||||
array_shift($colors);
|
for ($i = 0; $i < count($values); $i++) {
|
||||||
}
|
// check that there are still enought colors
|
||||||
$colorIndex = 0;
|
|
||||||
foreach ($colors as $color) {
|
|
||||||
$xmlWriter->startElement('c:dPt');
|
$xmlWriter->startElement('c:dPt');
|
||||||
$xmlWriter->writeElementBlock('c:idx', 'val', $colorIndex);
|
$xmlWriter->writeElementBlock('c:idx', 'val', $valueIndex);
|
||||||
$xmlWriter->startElement('c:spPr');
|
$xmlWriter->startElement('c:spPr');
|
||||||
$xmlWriter->startElement('a:solidFill');
|
$xmlWriter->startElement('a:solidFill');
|
||||||
$xmlWriter->writeElementBlock('a:srgbClr', 'val', $color);
|
$xmlWriter->writeElementBlock('a:srgbClr', 'val', $colors[$colorIndex++ % count($colors)]);
|
||||||
$xmlWriter->endElement(); // a:solidFill
|
$xmlWriter->endElement(); // a:solidFill
|
||||||
$xmlWriter->endElement(); // c:spPr
|
$xmlWriter->endElement(); // c:spPr
|
||||||
$xmlWriter->endElement(); // c:dPt
|
$xmlWriter->endElement(); // c:dPt
|
||||||
$colorIndex++;
|
$valueIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ class ChartTest extends \PHPUnit\Framework\TestCase
|
||||||
for ($idxp1 = 1; $idxp1 < $numColor; ++$idxp1) {
|
for ($idxp1 = 1; $idxp1 < $numColor; ++$idxp1) {
|
||||||
$idx = $idxp1; // stacked bar chart is shifted
|
$idx = $idxp1; // stacked bar chart is shifted
|
||||||
$element = $path . "/c:ser/c:dPt[$idxp1]/c:spPr/a:solidFill/a:srgbClr";
|
$element = $path . "/c:ser/c:dPt[$idxp1]/c:spPr/a:solidFill/a:srgbClr";
|
||||||
self::assertEquals($colorArray[$idx], $doc->getElementAttribute($element, 'val'), "bar chart idx=$idx");
|
self::assertEquals($colorArray[$idx - 1], $doc->getElementAttribute($element, 'val'), "bar chart idx=$idx");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue