-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Modify existing document (Template Processor vs PHPWord) #902
Comments
Did you manage to find a solution for this? |
unfortunately not... do you have the same issue? |
Well, I'm trying to find a way to create a Word document with some variables that I can modify from PHP. However, the template processor doesn't fit what I need because I need the values to show when an user open the document. For example:
So I was trying to find a way to work with variables with Word (and I found DocProperty, but that's more of a workaround), but I don't think PhpWord supports DocProperty handling. So now I'm looking for possible solutions. PS: The variables I need might include a complete table, so it's just not a single value. |
Ja that's basically the same I want to do but for some reason it seems to
be impossible or I didn't get the idea (-: if you find something just post
it here would be nice to solve that some how ;-)
Christopher Francisco <[email protected]> schrieb am Fr. 16. Dez.
2016 um 16:45:
… Well, I'm trying to find a way to create a Word document with some
variables that I can modify from PHP.
However, the template processor doesn't fit what I need because I need the
values to show when an user open the document. For example:
1. The document says the total price is $200.00
2. The customer changes a certain section in the document using Word
3. We re-evaluate and decide the prices is no longer $200.00, but
$190.00, that value is changed from PHP.
So I was trying to find a way to work with variables with Word (and I
found DocProperty, but that's more of a workaround), but I don't think
PhpWord supports DocProperty handling.
So now I'm looking for possible solutions.
PS: The variables I need might include a complete table, so it's just not
a single value.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#902 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AIInNjJhSmHgpDK2sfvXZYUPA2-MgdQgks5rIrIRgaJpZM4KIgWP>
.
|
sure, I will |
@jojomartius well, so far no luck, the document loses the formatting :/ |
Ping? |
up |
Ping! |
@chris-fa A way I would do it is using excel with locked cells except where data can be changed, then just read the fields. In LibreOffice, there is a form template, which can be used in design mode to fill in text fields, which you can then read back with phpword. Other than that, there is free format searching , for example: Or combine what you have been doing. Make a template where the value is still But your application actually could benefit from a paid library. |
Anyone |
For those that ends up here too, I post my solution for a my problem. It differs a bit, but it's closely related. My challenge was to load a template, replace some variables and then add HTML at the end. PhpWord offers the HTML class for this. And here it begins: The At the end I came around with using the setComplexBlock of the
After doing variables magic with the
Here is a sample code for doing the HTML insertion in a loaded template use \PhpOffice\PhpWord\TemplateProcessor,
\PhpOffice\PhpWord\Shared\Html,
\PhpOffice\PhpWord\PhpWord;
$doc = new TemplateProcessor($pathToTemplateFile);
// do some variable magic
$doc->setValue('key', $value);
// create temporary section
$section = (new PhpWord())->addSection();
// add html
Html::addHtml($section, $html, false, false);
// get elements in section
$containers = $section->getElements();
// clone the html block in the template
$doc->cloneBlock('htmlblock', count($containers), true, true);
// replace the variables with the elements
for($i = 0; $i < count($containers); $i++) {
// be aware of using setComplexBlock
// and the $i+1 as the cloned elements start with #1
$doc->setComplexBlock('html#' . ($i+1), $containers[$i]);
}
// save final document
$doc->saveAs($pathToOutputFile); As a caveat lists an tables won't work very well. If I find a solution I'll post it here. |
Hello, We've arrived to the same conclusion. It works on my side. But the titles or links included in the template are just displayed like simple text. Do you see the same ? I don't understand why |
Yes, a very clear idea: Remember: The HTML-Converter works on a document, not on a template. And for a document it adds the formatting of titles, tables and lists to the document as a stylesheet (in German its "Formatvorlage") in a special section. My above code won't add this formattings to the template, as the TemplateProcessor has no method for this. A workaround in theory: |
I'll ended up rewriting the Lists: // this is the block setting
for($i = 0; $i < count($containers); $i++) {
$doc->setComplexBlock('html#' . ($i+1), $containers[$i]);
}
//-- here is our new function
$doc->repairListItems("2", "3");
// save final document
$doc->saveAs($pathToOutputFile); I added the function public function repairListItems($numIdBullets, $numIdNumbers, $bullets = false) {
// TODO: insert a possibiltiy to divide ordered and unordered lists
// for the moment we use either numbers or bullets for all list
$replace = $numIdNumbers;
if($bullets) $replace = $numIdBullets;
$this->tempDocumentMainPart = str_replace('<w:numId w:val=""', '<w:numId w:val="' . $replace . '"', $this->tempDocumentMainPart);
} The caveeat here as you see in my inline comment: We can give the whole document either bullet lists or numbered lists. Maybe someone has an idea, to find a workaround by rewriting the list-conversion in the In addition I commented out some lines in the protected static function parseList($node, $element, &$styles, &$data)
{
$isOrderedList = $node->nodeName === 'ol';
if (isset($data['listdepth'])) {
$data['listdepth']++;
} else {
$data['listdepth'] = 0;
$styles['list'] = $isOrderedList ? 'ordered' : 'unordered'; //'listStyle_' . self::$listIndex++;
//$element->getPhpWord()->addNumberingStyle($styles['list'], self::getListStyle($isOrderedList));
}
if ($node->parentNode->nodeName === 'li') {
return $element->getParent();
}
} |
And now my magic to make tables partly work: I'll ended up rewriting the I added default values to the converted tables, that it fit my needs, at least with LibreOffice. I altered the protected static function parseTable($node, $element, &$styles)
{
// add standard styles
$default = [
'unit' => 'auto',
'width' => '1',
'borderColor' => '000000',
'borderSize' => '1',
'cellSpacing' => '57'
];
foreach($default as $key => $value) {
if(empty($styles['table'][$key])) $styles['table'][$key] = $value;
}
// this code remains:
$elementStyles = self::parseInlineStyle($node, $styles['table']);
$newElement = $element->addTable($elementStyles);
return $newElement;
} The same I did with the // add standard styles
$default = [
'valign' => 'top'
];
foreach($default as $key => $value) {
if(empty($styles['cell'][$key])) $styles['cell'][$key] = $value;
} The resulting tables are not the best, but worked for me. |
Ho, very good job ! 👍 But, I'm not sure that it's only about HTML-Converter and "styling". I also notice the same with links (and there is for example the issue 471 about that. More of all, this sample doesn't work with the link item. |
This works perfecly for me, thanks! 👍 |
g4rf / that works great in MS Word and Libre! unfortunately, unorded list will be shown as ordered lists :-( |
@strtob Thanks a lot. Yes, you are right. As mentioned here and in the inline documentation, there is at the moment no possibility to differentiate between an unordered or an ordered list. You can have all lists ordered or all lists unordered.
|
crazy, I've found out if you made a unsorted list (in my case with ckeditor 4) which result in |
Aloha,
just a simple one (i guess). I have an existing document, contains a table, an image, and some style. I can open it like this
Than the document looks exactly the same, but i can't go through and add stuff like sections etc.
Or i do the same with the template processor like this
Here I am able to go through the whole document with ->getSections(), ->getElements and stuff and add or replace something, but the Look and feel is completely lost.
Pretty sure, that i just missed something quite basic. I just wanted to open an existing documents, replace / add some text (no variables) and save it again. Shouldn't that be possible?
Looking forward to get a better understanding for what i'm doing here.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: