Forum


Replies: 7   Views: 316
Can't pass 'pstyle' from one wordfragment to another

Posted by Siegfried  · 09-08-2019 - 13:43

Hello supportteam,
how can I pass the pStyle Option from one WordFragment to another?

here is a simplified sample of my code:

$docx = new CreateDocxFromTemplate($this->templateName);
$wfMain = new WordFragment($docx);
$wfMain->addText('Title:', array('pStyle' => 'Heading1'));
$wfMain->addText('SubTitle:', array('pStyle' => 'Heading2'));
$wfMain->addText('SubSubTitle:', array('pStyle' => 'Heading3'));


$individualparts = array();

$text1 = new WordFragment($docx);
$text1->addText('Hello world 1', array('pStyle' => 'Heading3', 'caps' => 'true'));
$text2 = new WordFragment($docx);
$text2->addText('Hello world 2', array('pStyle' => 'Heading1'));
// ... and more individual parts like charts (all should be WordFragments with individual styles from the word-template)

$individualparts[4] = $text1;
$individualparts[2] = $text2;
ksort($individualparts, SORT_NUMERIC); // sorting the individual parts


$wfMain->addText('$individualparts'); // here I lost the pStyle from $text1 and $text2
// $wfMain->addText('$individualparts', array('pStyle' => 'Heading2')); // this works but unfortunately for all $individualparts


$docx->replacevariableByWordfragment(array('placeholder' => $wfMain), array('type' => 'block'));
$docx->createDocx('Bericht');

I lost pStyle from $text1 and $text2 bu  interestingly the 'caps' - option works ... why not pStyle?
Any help for me please?

Best regards Siegfried

Posted by admin  · 09-08-2019 - 16:06

Hello,

If the first parameter of addText is an array:

$individualparts = array();
...
$individualparts[4] = $text1;
...
$wfMain->addText($individualparts);

The method gets the inline contents of the WordFragments, so paragraph tags are removed (pStyle are applied to paragraph tags). If you set a pStyle in the second parameter, then it applies to the whole paragraph and character styles (like caps) are inherited to child contents. MS Word doesn't allow applying custom paragraph styles to run-of-text contents (only to paragraph tags), you need to use character styles to keep them when using an array and addText. You can use the rStyle option to apply a character style.

This sample uses character styles:

$text = array();
$text[] =
    array(
        'text' => 'Text MyStyle',
        'rStyle' => 'MyStyle1'
);
$text[] =
    array(
        'text' => ' text MyStyle2.',
        'rStyle' => 'MyStyle2'
);

$docx->addText($text);

You can use importStyles and createCharacterStyle to import and generate character styles.

Regards.

Posted by Siegfried  · 12-08-2019 - 09:27

Thank you admin for your reply,

but how do i know if a importet style like

$docx->importStyles($this->templateName, 'merge', array('Heading3'));

is actually a paragraph-style oder a character-style?

How can I import a style like 'Heading3' (see above), and use it as a character-style like:

$wordfragment = new WordFragment($docx);
$text = array();
$text[] = array(
  'text' => 'Sample Text',
  'rStyle' => 'Heading3',
);
$wordfragment->addText($text);

I don't want to create a new Style from scratch, I like to use a pre-defined style from a word-template, so the user can change this style without changing the code...

 

... ok, I see it in the parseStyle-document if it is a pStyle or a rStyle...

So ... is it right, that if I would import some styles, only could use pStyles as pStyles and rStyles as rStyles... in my example I have to create a rStyle in my word-template which afterwards could be reused as a rStyle?

Posted by admin  · 12-08-2019 - 09:52

Hello,

A paragraph style can't be used as character style. They have their own tags and styles, some are the same but others are different; for example a character style can't have an outline level tag as paragraph styles.

If you can't generate the styles from scratch, you'd need to use importStyles that supports character styles too, but these character styles can only be applied to run-of-text contents.

Regards.

Posted by Siegfried  · 12-08-2019 - 11:13

Thank you ... now it works what I want. :)

Posted by Siegfried  · 03-09-2019 - 11:24

Hello supportteam,

unfortunately my problem was not solved. I've tryed a lot but without success.

I need to create (more than one) wordfragments and place all into a parent wordfragment, which belongs to a document. Each of these sub-wordfragments should be a own paragraph on which I can use paragraph-styles.

Here is a sample-code which will illustrate my problem:

$docx = new CreateDocxFromTemplate(TEMPLATEPATH . 'Test1.docx');


$text1 = new WordFragment($docx);                                       
$text1->addText('Text one');
$text2 = new WordFragment($docx);                                       
$text2->addText('Text two');
$text3 = new WordFragment($docx);                                       
$text3->addText('Text three');


$text4_1 = new WordFragment($docx);
$text4_1->addText('Text 4_1, ');
$text4_2 = new WordFragment($docx);
$text4_2->addText(
                                        array(
                                                array(
                                                       'text'  =>   'Text 4_2 ',
                                                       'b'     =>   'on'
                                                )
                                        )
                                );

$text4_collect[1] = $text4_1;
$text4_collOpt[1] = array(      'pStyle' =>   'H2Interessenvertretung');
$text4_collect[2] = $text4_2;
$text4_collOpt[2] = array(      'pStyle' =>   'H2Selbstbestimmung');

$text4 = new WordFragment($docx);                                       
$text4->addText(array($text4_collect[1]), $text4_collOpt[1]);
$text4->addBreak(array('type' => 'line')); // how to get a hard line-break?
$text4->addText(array($text4_collect[2]), $text4_collOpt[2]);




$singleparts[1] = $text1;
$spOptions[1] = array('pStyle' => 'Titel2');
$singleparts[2] = $text2;
$spOptions[2] = array('pStyle' => 'Titel3');
$singleparts[3] = $text3;
$spOptions[3] = array(  'pStyle'        =>   'H2Selbstbestimmung',
                        'border'        =>   'single',
                        'borderWidth'   =>   '24',
                        'borderColor'   =>   'FF0000');
$singleparts[4] = $text4;


ksort($singleparts, SORT_NUMERIC);

$wf_top = new WordFragment($docx);
foreach($singleparts as $idx => $sp) {
        $wf_top->addText(array($sp), $spOptions[$idx]);
}

$docx->replaceVariableByWordFragment(array('content' => $wf_top), array('type' => 'block'));

$docx->createDocx('test_template');

text1 to text3 works fine as paragraphs but text4 should be a collection of wordfragments (each of them should be a paragraph which I can separatly format like a paragraph (borders and so on ...)).
Is there a way to do it?

Btw. is there a way to get a 'hard' line-break? Because addBreak(array('type' => 'line')); always makes a 'soft' line-break.

I am grateful for any help!!!

By the way, I've a premium license

Posted by admin  · 04-09-2019 - 06:42

Edited by admin · 04-09-2019 - 07:01

Hello,

The problem with your code is the same than the explained in our first reply:

If the first parameter of addText is an array (...) The method gets the inline contents of the WordFragments, so paragraph tags are removed

To accomplish that task you need to add the WordML of the WordFragments to avoid removing block tags such as paragraphs:

$text1 = new WordFragment($docx);                                       
$text1->addText('Text one', array('pStyle' => 'Titel2'));
$text2 = new WordFragment($docx);                                       
$text2->addText('Text two', array('pStyle' => 'Titel3'));
$text3 = new WordFragment($docx);                                       
$text3->addText('Text three', array('pStyle' => 'H2Selbstbestimmung', 'border' => 'single', 'borderWidth' => '24', 'borderColor' => 'FF0000'));

$text4_1 = new WordFragment($docx);
$text4_1->addText('Text 4_1, ');
$text4_2 = new WordFragment($docx);
$text4_2->addText(
    array(
        array(
           'text'  =>   'Text 4_2 ',
           'b'     =>   'on',
        )
    )
);

$text4_collect[1] = $text4_1;
$text4_collOpt[1] = array('pStyle' => 'H2Interessenvertretung');
$text4_collect[2] = $text4_2;
$text4_collOpt[2] = array('pStyle' => 'H2Selbstbestimmung');

$text4 = new WordFragment($docx);                                       
$text4->addText(array($text4_collect[1]), $text4_collOpt[1]);
$text4->addText('');
$text4->addText(array($text4_collect[2]), $text4_collOpt[2]);

$singleparts[1] = $text1;
$singleparts[2] = $text2;
$singleparts[3] = $text3;
$singleparts[4] = $text4;

ksort($singleparts, SORT_NUMERIC);

$wf_top = new WordFragment($docx);
foreach($singleparts as $idx => $sp) {
    $wf_top->addWordML((string)$sp);
}

$docx->replaceVariableByWordFragment(array('content' => $wf_top), array('type' => 'block'));

Or use DOCXPath to insert the whole WordFragments:

$text1 = new WordFragment($docx);                                       
$text1->addText('Text one', array('pStyle' => 'Titel2'));
$text2 = new WordFragment($docx);                                       
$text2->addText('Text two', array('pStyle' => 'Titel3'));
$text3 = new WordFragment($docx);                                       
$text3->addText('Text three', array('pStyle' => 'H2Selbstbestimmung', 'border' => 'single', 'borderWidth' => '24', 'borderColor' => 'FF0000'));

$text4_1 = new WordFragment($docx);
$text4_1->addText('Text 4_1, ');
$text4_2 = new WordFragment($docx);
$text4_2->addText(
    array(
        array(
           'text'  =>   'Text 4_2 ',
           'b'     =>   'on',
        )
    )
);

$text4_collect[1] = $text4_1;
$text4_collOpt[1] = array('pStyle' => 'H2Interessenvertretung');
$text4_collect[2] = $text4_2;
$text4_collOpt[2] = array('pStyle' => 'H2Selbstbestimmung');

$text4 = new WordFragment($docx);                                       
$text4->addText(array($text4_collect[1]), $text4_collOpt[1]);
$text4->addText('');
$text4->addText(array($text4_collect[2]), $text4_collOpt[2]);

$singleparts[1] = $text1;
$singleparts[2] = $text2;
$singleparts[3] = $text3;
$singleparts[4] = $text4;

ksort($singleparts, SORT_NUMERIC);
// insert in reverse order to keep the correct order after the chosen placeholder
$singleparts = array_reverse($singleparts);

$referenceNode = array(
    'type' => 'paragraph',
    'occurrence' => 1,
    'contains' => 'content',
);
foreach($singleparts as $idx => $sp) {
    $docx->insertWordFragment($sp, $referenceNode);
}

Or you could replace the placeholder with the first WordFragment adding a new placeholder at the end, then replace this new placeholder with the second WordFragment and so on.

For this kind of support we recommend opening a support ticket (https://www.phpdocx.com/support), so you can attach the template you are using and the dev team can generate a whole sample.

About is there a way to get a 'hard' line-break? Because addBreak(array('type' => 'line')); always makes a 'soft' line-break, hard line breaks are done using paragraphs (https://word.tips.net/T000170_Understanding_Hard_and_Soft_Returns.html), but, as your script does, if you add a WordFragment as an array in addText the paragraph tags are removed from the WordFragment. To add a hard line break you can use addText('').

Regards.

Posted by Siegfried  · 06-09-2019 - 09:52

Dear supportteam,

thank you so much for your support. It works and now I think I understand HOW it works.

Best regards.