Forum


Replies: 7   Views: 726
Mergedocx fails in specific circumstances with an ole chart
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 mi_ov  · 20-05-2021 - 01:46

Hello, first of all, let me tell you that this library has saved me tons of time.

I have a very particular problem. In a part of my system I need to merge 5 docx files into one.

One of the files is pretty big and has charts and tables inside it.

The files I have are the following:

  1. caratula.docx (the cover page of the document)
  2. resumen.docx (a short version of the document)
  3. anonimo.docx (the main file where's the bulk of information and the tables)
  4. presentacion.docx (presentation letter)
  5. etica.docx (ethics document)

All the files are valid .docx files and can be opened as zip files.

So, I need to combine these 5 files into one. I didn't have issues doing this earlier on, but the users of the system came up with the specific combination I have right now and something is breaking.

If I try:

require_once '../lib/phpdocx/classes/MultiMerge.php';
$merge = new \MultiMerge();
$merge->mergeDocx('../writable/tmp/caratula.docx',
     array(
           '../writable/tmp/resumen.docx',
           '../writable/tmp/anonimo.docx',
           '../writable/tmp/etica.docx',
           '../writable/tmp/presentacion.docx'
     ),
     '../writable/tmp/completo.docx',
     array()
);

I get this error and it points me to line 1009:

Call to a member function getAttribute() on null

1003                     $docXPathRels = new DOMXPath($chartRelsDOM);
1004                     $docXPathRels->registerNamespace('r', 'http://schemas.openxmlformats.org/package/2006/relationships');
1005                     $queryXlsxRels = '//r:Relationship[@Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"]';
1006                     $queryXlsxRelsNode = $docXPathRels->query($queryXlsxRels);
1007 
1008                     $xlsxNode = $queryXlsxRelsNode->item(0);
1009                     $xlsxId = $xlsxNode->getAttribute('Id');
1010                     $xlsxTarget = $xlsxNode->getAttribute('Target');
1011                     //we get the original name of the xlsx file
1012                     $xlsxNameArray = explode('/', $xlsxTarget);
1013                     $xlsxName = array_pop($xlsxNameArray);
1014                     $xlsxNewName = 'spreadsheet' . $value['newId'];
1015                     $xlsxNode->setAttribute('Id', $value['newId']);
1016                     $xlsxNode->setAttribute('Target', '../embeddings/' . $xlsxNewName . '.xlsx');

Now, the strange part is that if I change my code to:

require_once '../lib/phpdocx/classes/MultiMerge.php';
$merge = new \MultiMerge();
$merge->mergeDocx('../writable/tmp/anonimo.docx',
    array(
        '../writable/tmp/caratula.docx',
        '../writable/tmp/resumen.docx',
        '../writable/tmp/etica.docx',
        '../writable/tmp/presentacion.docx'
    ),
    '../writable/tmp/completo.docx',
    array()
);

Which is basically moving the main content-heavy file as the first parameter, it works without any issues, which leads me to believe it's not a file issue, neither a memory or input variables issue, but a difference between the handling ot the first parameter and the files in the second parameter.

It would appear it only fails if I have the anonimo.docx file inside the array of the other documents.

I need the caratula.docx file to appear first, I've tried in every order possible, but it just works if I put the heavy file first. 

I use:

  • Windows 10 x64
  • Apache 2.4.25 
  • PHP 7.4.11 
  • PHP DocX 11.0 Premium

Posted by admin  · 20-05-2021 - 05:19

Hello,

Maybe the DOCX document includes object charts (instead of regular charts)? Please do the following minor change:

  1. Edit MultimeMerge.php (classes folder)
  2. In phpdocx 11, go to line 1005 and replace the following line:
$queryXlsxRels = '//r:Relationship[@Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"]';

by this new line:

$queryXlsxRels = '//r:Relationship[@Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package" or @Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"]';

and try again. Regular charts are supported in the merge method, but object charts support is only included in the current testing branch (the previous change adds support) but it's not available in the stable package (it will be included in the next release of phpdocx; there's no release date).

If you send to contact[at]phpdocx.com the DOCX documents you are merging we'll check them.

Regards.

Posted by mi_ov  · 20-05-2021 - 06:39

Excellent! That did the trick. The only issue I am having now is that when I try to open the file in Word, I get this error:

Word found unreadable content in completo.docx. Do you want to recover the contents of this document? If you trust the source of this document, click Yes.

Even though, when I click on Yes the file opens and appears to be fine. Could this be some other fix?

In my case the change you mentioned was on line 1005. 

I sent you the files so you can test with them.

Posted by admin  · 20-05-2021 - 06:54

Hello,

We have sent the MultiMerge class updated with the same change and supporting also external charts (not embedded charts as regular charts are). Using this updated class the merging with your DOCX will work correctly without that warning; merging OLE charts will be included in the next release of phpdocx (there's no release date).

Regards.

Posted by mi_ov  · 20-05-2021 - 06:59

Perfect, thank you!

Posted by mi_ov  · 20-05-2021 - 16:22

Just out of curiosity, does this functionality also affect the importContents function? I also use it and sometimes import contents from other documents, so in case there's an update for that too, please let me know, in order to avoid random errors because of elements like in this case.

Posted by admin  · 20-05-2021 - 16:50

Hello,

Yes, you are right. The importContents method uses mergeDocx internally, so all improvements added to mergeDocx will be automatically applied to importContents. You don't need to update anything else because importContents call mergeDocx, there's no extra class to be updated.

Regards.

Posted by mi_ov  · 20-05-2021 - 19:12

Excellent! Thank you for the fast reply!