Forum


Replies: 8   Views: 3839
Replacevariablebytext very slow
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by bbreukelen  · 23-06-2016 - 08:34

I have a word template with 418 variables that I am replacing for numbers.
When calling the replaceVariableByText method it takes 3-4 seconds to complete on a single page document.
I have multiple pages to process which leads to a total processing time of 15 seconds which is too long.

I tried disabling preprocessing like this:

new CreateDocxFromTemplate($file, ['preprocessed' => true]);

This reduced the time to a few milliseconds but only a handfull of variables get replaced.
Manually calling processTemplate fixes that issue but now the same time is spent:

$docx->processTemplate(['document' => array_keys($repV)]);

So the processTemplate be it manually or automatically triggered is very slow and consumes 100% cpu while it runs.

Any ideas how to improve this?

Thanks

Posted by bbreukelen  · 23-06-2016 - 09:28

Thanks for the reply.
I am using the trial license on version 6.0. I want to overcome issues like these before purchasing a license.

I am already processing each page individually and planning to use the merge function so this is a 1 page document.
I don't understand the raw option.
Is there a way to save the docx output after doing a processTemplate so I can store it and set preProcessed to true?

Posted by admin  · 23-06-2016 - 09:42

Hello,

There's no method or class to use the preprocess method standalone, but we can create a small class to acomplish it. This is a class to clean templates and save them, so they can be reused setting preProcessed as true. After you have purchased a license, please write to contact[at]phpdocx.com and we'll send you this class.

About raw option, please check its description on

http://www.phpdocx.com/api-documentation/templates/replace-variable-text-Word-document

The best and faster approach in your case would be use the custom class to generate preprocessed DOCX and then use replaceVariableByText setting raw as true.

Regards.

Posted by bbreukelen  · 23-06-2016 - 12:30

Great, I will reach out to you once I have purchased the license.

On a side-note, are you aware of any external tools or features in Word that cleanup the docx before saving similar to what the processing doesn? The docx is completely filles with proofing tags, ids and other useless elements causing the document to process slowly.

Posted by admin  · 23-06-2016 - 13:21

Hello,

There isn't an external app that clean that extra tags as phpdocx does (at least we don't know any).

Regards.

Posted by AndrewCooper  · 28-06-2016 - 11:29

bbreukelen ,

Be aware that the merge functionality is rather slow as well. It might not allieviate your problem. I'd be interested in hearing whether it did or not since we'll be using the same functionality here at some point. In our application we had originally generated each section of the document (around 10 or 11 sections) as separate documents and then merged them into a single document. The process was taking 3 - 3.5 seconds, which isn't too long unless you are generating numerous documents at a time (which we are). 

The point being, depending on the number of pages you have and are spitting out as individual documents, the time savings might or might not be that great. We solved the issue by dividing our document more logically so that we only split it into 3 or so separate documents and then merged those. That dropped our time to about 0.5 seconds.You'll likely have to do some trial and error to find the sweet spot between number of documents to merge and number of variables to replace per document.

Also note that my numbers are on a development box which is not an impressive machine performance-wise.  The performance on the production box is likely better but the load there is significantly more as well.

Andrew

Posted by bbreukelen  · 01-07-2016 - 15:42

I tried using the custom class for preprocessing my templates but it gave XML Dom errors and created corrupt files so I decided to just do a normal createFromTemplate, process it and then do a createDocx as I figures it probably saves the cleaned template.

Below is my code to handle caching. Note that in the folder where you keep the templates, a folder called "cache" must be created with write-access to the user running the process. Don't forget to remove the cached version of the template after making changes to the initial one. The cached files will be created at first run so the first run takes longer.

This saves quite a bit of time when replacing lots of variables.

class myProcessingClass {

   private function loadTemplate($File) { // tFile is the template file

        if (!is_readable($tFile)) { return null; }
        $tFilePath = pathinfo($tFile);
        $tFileCache = $tFilePath['dirname'] . '/cache/' . $tFilePath['filename'] . '.' . $tFilePath['extension'];
        if (! file_exists($tFileCache)) {
            $ret = $this->makeTemplateCache($tFile, $tFileCache);
            if (! $ret) { return null; }
        }

        try {
            return new CreateDocxFromTemplate($tFileCache, ['preprocessed' => true]);
        } catch (Exception $e) {
            return null;
        }
    }

    private function makeTemplateCache($tFile, $tFileCache) {
        try {
            $docx = new CreateDocxFromTemplate($tFile);
            $docx->processTemplate();
            $docx->createDocx(str_replace(".docx", "", $tFileCache));

            if (! file_exists($tFileCache)) { return false; }
            return true;

        } catch (Exception $e) {
            return false;
        }
    }

}