I'm using PHPWord to create reports that make use of a .docx
template.
This library allows me to clone a block and clone table rows. However the examples are separate from each other. I need to combine both approaches because my template table looks like this:
${block_group}
+--------+----------------------------------------------------------------+
| Group: | ${group} |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| ${name} | ${address} |
+---------------------+---------------------------------------------------+
${/block_group}
group
- (clone block)group
/block
can have multiple table rows - (clone table rows)So far this is what my code looks like:
# Create the template processor
$templateProcessor = new TemplateProcessor('/path/to/template/Template.docx');
# Block cloning
$replacements = array(
array('group' => 'Group 1'),
array('group' => 'Group 2')
);
$templateProcessor->cloneBlock('block_group', 0, true, false, $replacements);
As you can see, $replacements
only took care of the ${group}
placeholder because that's the only thing I'm worried about for the clone block
step. I now have two tables, the ${group}
placeholders are properly set, so on to the ${name}
and ${address}
placeholders.
Now that I need to clone table rows for each group, I'm stuck, I don't know how to even begin coding it.
This is how the file that I get when I run my current code looks like:
+--------+----------------------------------------------------------------+
| Group: | Group 1 |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| ${name} | ${address} |
+---------------------+---------------------------------------------------+
+--------+----------------------------------------------------------------+
| Group: | Group 2 |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| ${name} | ${address} |
+---------------------+---------------------------------------------------+
After countless attempts I finally figured a way to do this (not really sure if it's the best approach, but it works).
Assuming my data looks like this:
$data = array(
'Group 1' => array(
array(
'name' => 'John Smith',
'address' => '123 Main Rd.'
),
array(
'name' => 'Jane Doe',
'address' => '456 Second St.'
)
),
'Group 2' => array(
array(
'name' => 'Noah Ford',
'address' => '987 Rich Blvd.'
),
array(
'name' => 'Oliver Brown',
'address' => '654 Third St.'
)
)
);
The first step is to clone the block
:
# Block cloning
$replacements = array();
$i = 0;
foreach($data as $group_name => $group) {
$replacements[] = array(
'group' => $group_name,
'name' => '${name_'.$i.'}',
'address' => '${address_'.$i.'}'
);
$i++;
}
$templateProcessor->cloneBlock('block_group', count($replacements), true, false, $replacements);
The main idea here is to not put any row data yet but instead change the placeholder identifiers to include the group index.
After this code, the document should look like this:
+--------+----------------------------------------------------------------+
| Group: | Group 1 |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| ${name_0} | ${address_0} |
+---------------------+---------------------------------------------------+
+--------+----------------------------------------------------------------+
| Group: | Group 2 |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| ${name_1} | ${address_1} |
+---------------------+---------------------------------------------------+
The final step is to clone the table rows according to your data.
# Table row cloning
$i = 0;
foreach($data as $group) {
$values = array();
foreach($group as $row) {
$values[] = array(
"name_{$i}" => $row['name'],
"address_{$i}" => $row['address']
);
}
$templateProcessor->cloneRowAndSetValues("name_{$i}", $values);
$i++;
}
After this code, the document should look like this:
+--------+----------------------------------------------------------------+
| Group: | Group 1 |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| John Smith | 123 Main Rd. |
+---------------------+---------------------------------------------------+
| Jane Doe | 456 Second St. |
+---------------------+---------------------------------------------------+
+--------+----------------------------------------------------------------+
| Group: | Group 2 |
+--------+------------+---------------------------------------------------+
| Name | Address |
+---------------------+---------------------------------------------------+
| Noah Ford | 987 Rich Blvd. |
+---------------------+---------------------------------------------------+
| Oliver Brown | 654 Third St. |
+---------------------+---------------------------------------------------+