document generation only works the first time

2019-09-05 23:58发布

问题:

I'm using openxml in my HTML5 mobile app to generate word documents on the mobile device. In general openxml works fine and straight forward, but I'm struggling with an annyoing problem. The document generation only works the first time after I've started the app. This time I can open and view the document. Restart the app means: - Redeploy from development machine - Removing the app from the task pane (pushing aside; I assume the app is removed then?)

The second time I get the message the document is corrupted and I'm unable to view the file

UPDATE: I can't reproduce this behaviour when I'm running the app connected to the remote debugger without having a breakpoint set. Doing it this way I always get a working document.

I doesn't make a difference wether I do any changes on the document or not. Simply open and saving reproduce this error.

After doing some research I've found that structure of the docx.zip file of the working and the corrupt file is the same. They also have the same file length. But in the corrupt docx there are some files I've found some files having a wrong/invalid CRC. See here an example when trying to get a corrupt file out of the zip. Other files are working as expected.

The properties for this file are-> (CRC in a working version is: 44D3906C)

Code for processing the doc-template:

            /*
             * Process the template
             */
             function processTemplate(doc64, callback) 
             {
                "use strict";
                 console.log("PROCESS TEMPLATE");            
                var XAttribute = Ltxml.XAttribute;
                var XCData = Ltxml.XCData;
                var XComment = Ltxml.XComment;
                var XContainer = Ltxml.XContainer;
                var XDeclaration = Ltxml.XDeclaration;
                var XDocument = Ltxml.XDocument;
                var XElement = Ltxml.XElement;
                var XName = Ltxml.XName;
                var XNamespace = Ltxml.XNamespace;
                var XNode = Ltxml.XNode;
                var XObject = Ltxml.XObject;
                var XProcessingInstruction = Ltxml.XProcessingInstruction;
                var XText = Ltxml.XText;
                var XEntity = Ltxml.XEntity;
                var cast = Ltxml.cast;
                var castInt = Ltxml.castInt;

                var W = openXml.W;
                var NN = openXml.NoNamespace;
                var wNs = openXml.wNs;

                var doc = new openXml.OpenXmlPackage(doc64);

                 // add a paragraph to the beginning of the document.
                 var body = doc.mainDocumentPart().getXDocument().root.element(W.body);
                 var tpl_row = ((doc.mainDocumentPart().getXDocument().descendants(W.tbl)).elementAt(1).descendants(W.tr)).elementAt(2);
                 var newrow = new XElement(tpl_row);

                 doc.mainDocumentPart().getXDocument().descendants(W.tbl).elementAt(1).add(newrow);

                 // callback(doc);    
                 var mod_file = null;
                 var newfile;
                 var path;

                 if (doc != null && doc != undefined ) {
                         mod_file = doc.saveToBlob();
                         // Start writing document
                         path = "Templates";
                         newfile = "Templates/Bau.docx";

                         console.log("WRITE TEMPLATE DOCUMENT");
                         fs.root.getFile("Templates/" + "MyGenerated.docx", {create: true, exclusive: false}, 
                         function(fileEntry) 
                         {  
                                fileEntry.createWriter(
                                function(fileWriter)
                                {
                                    fileWriter.onwriteend = function(e) {
                                        console.log("TEMPLATE DOCUMENT WRITTEN:"+e.target.length);
                                    };
                                    fileWriter.onerror = function(e) {
                                        console.log("ERROR writing DOCUMENT:" + e.code + ";" + e.message);
                                    };
                                    var blobreader = new FileReader();
                                    blobreader.onloadend = function() 
                                    {          
                                        fileWriter.write(blobreader.result);                   // reader.result contains the contents of blob as a typed array
                                    };                                                                                              
                                    blobreader.readAsArrayBuffer(mod_file);                         
                                }, 
                                null);                              
                         }, null);                   
                 };

Any ideas what I'm doing wrong?

回答1:

Thanks for posting about the error. There were some issues with jszip.js that I encountered when I was developing the Open XML SDK for JavaScript.

At the following link, there is a sample javascript app that demonstrates generating a document.

Open XML SDK for JavaScript Demo

In that app you can save multiple DOCXs, one after another, and they are not corrupted.

In order to work on this issue, I need to be able to re-produce locally. Maybe you can take that little working web app and replace parts with your parts until it is generating invalid files?

Cheers, Eric

P.S. I am traveling and have intermittent access to internet. If you can continue the thread on OpenXmlDeveloper.org, then it will help me to answer quicker. :-)



回答2:

What made it work for me, was changing the way of adding images (Parts) to the document. I was using the type "binary" for adding images to document. I changed this to "base64"
So I changed the source from:

mydoc.addPart( "/word/"+reltarget, openXml.contentTypes.png, "binary", fotodata );  // add Image Part to doc

to:

mydoc.addPart( "/word/"+reltarget, openXml.contentTypes.png, "base64", window.btoa(fotodata) );                 // add Image Part to doc