2017-05-04 3 views
0

Entwickeln Sie ein Word-Add-in, die Sie eine docx-Datei auswählen können und es wird in das neue leere Dokument eingefügt - eine templateHandler Art von.Word Addin funktioniert nicht auf Word online

Jede docx-Datei hat eine Fußzeile, die mehrere RTF - contentControlers enthält. Bevor ein Dokument geladen wird (insertFileFromBase64), befindet sich ein thisDocument.body.clear() im Code.

In lokalem wordclient gibt es kein Problem, die verschiedene Dokumente zu laden, aber in Wort Online bekomme ich einen Fehler in Bezug auf body.clear(): Die Aktion nicht mit Word Online

EDIT unterstützt wird: Der Code wird angepasst, damit Kopf- und Fußzeile von docx-Datei getrennt und mit insertOoxml eingefügt werden. Sie werden beim Öffnen des Add-Ins geladen. body.clear() ist kein Problem mehr.

In der Fußzeile gibt es auch Einträge mit den contenControllern. Sie gehen zu Exits in der Online-Version.

EDIT: Sie sind jetzt sichtbar, da die Fußzeile separat von der docx geladen wird. Nur ein großes Problem mit Addin ist jetzt - dass Sie nur in einer Zeile im Dokument bearbeiten können, wenn Sie das Addin öffnen. Wenn Sie auf Text klicken, wird er unsichtbar. Wenn Sie in eine andere docx-Datei wechseln, indem Sie eine aus dem Add-In laden, wird der Text im Hauptteil unsichtbar.

Ich verwende office.js 1.1 Die Office365, die ich ausgeführt habe, ist ein evaluationversion für Entwickler: V 1609 (Build 7369,2127)

Dies ist der Inhalt von main.js:

console.log("mains.js is present! "); 

(function() { 
"use strict"; 

// Initialize 
Office.initialize = function (reason) { 
    $(document).ready(function() { 
     app.initialize(); 
     // Use this to check whether the new API is supported in the Word client. 
     if (Office.context.requirements.isSetSupported("WordApi", "1.1")) { 

      console.log('Den här koden är optimerad för Word 2016.'); 

      // Load the doc names from the service into the UI. 
      getDocNames(); 
      console.log("Getting Documents"); 



      addFooter(); 
      //console.log("Adding Footer"); 

      addHeader(); 
      //console.log("Adding Header"); 

      //getDataFromSelection(); 
      //getAllContentControls(); 

      // Setup the event handlers for UI. 
      $('#selectDocument').change(selectDocumentHandler); 
      $('#changeContent').click(contentControlHandler); //TODO:validateFields 
      $('#clearContent').click(clearContent); 
      $('#get-data-from-selection').click(getDataFromSelection); 

     } 
     else { 
      console.log('Du måste använda Word 2016 för att det här ska fungera.'); 
     } 
    }); 
}; 
function clearContent() { 
    $('input[type=text]').val(''); 
} 

     // Function for getting header and footer 

function getHeaderFooter(fileName) { 

    var myOOXMLRequest = new XMLHttpRequest(); 

    var myXML; 

    myOOXMLRequest.open('GET', fileName, false); 

    myOOXMLRequest.send(); 

    if (myOOXMLRequest.status === 200) { 

     myXML = myOOXMLRequest.responseText; 
     return myXML; 
    } 
Office.context.document.setSelectedDataAsync(myXML, { coercionType: 'ooxml' }); 
    //return ""; 
} 

/* Word JS functions */ 

function addHeader() { 
    // Run a batch operation against the Word object model. 
    Word.run(function (context) { 

     // Create a proxy sectionsCollection object. 
     var sections = context.document.sections; 
     //mySections.body.clear(); 
     // Queue a commmand to load the sections. 
     context.load(sections, 'body/style'); 

     return context.sync().then(function() { 

      var header = sections.items[0].getHeader("primary"); 
      //header.clear(); 
      var templateHeader = getHeaderFooter('/xml/simrisHeader.xml'); 

      header.insertOoxml(templateHeader, Word.InsertLocation.replace); 

      return context.sync().then(function() { 
       console.log("Added a header to the first section."); 
      }); 
     }); 
    }) 
     .catch(function (error) { 
      console.log('Error: ' + JSON.stringify(error)); 
      if (error instanceof OfficeExtension.Error) { 
       console.log('Debug info: ' + JSON.stringify(error.debugInfo)); 
      } 
     }); 
} 

function addFooter() { 
    Word.run(function (context) { 

     var sections = context.document.sections; 
     //context.document.clear(); 
     context.load(sections, 'body/style'); 
     return context.sync().then(function() { 

      var footer = sections.items[0].getFooter("primary"); 
      //context.footer.clear(); 

      var templateFooter = getHeaderFooter('/xml/simrisFooter.xml'); 

      footer.insertOoxml(templateFooter, Word.InsertLocation.replace); 
      // var contentControls = footer.contentControls; 
      //getAllContentControls(); 

      return context.sync().then(function() { 
       console.log("Added a footer to the first section."); 
      }); 
     }) 
      .catch(function (error) { 
       console.log('Error: ' + JSON.stringify(error)); 
       if (error instanceof OfficeExtension.Error) { 
        console.log('Debug info: ' + JSON.stringify(error.debugInfo)) 
       } 
      }); 

    }); 
} 

    function displayContents(myBase64) { 
     Word.run(function (context) { 

      var thisDocument = context.document; 

      thisDocument.body.clear(); 

      var mySelection = thisDocument.getSelection(); 

      mySelection.insertFileFromBase64(myBase64, "replace"); 

      return context.sync() 
       .then(function() 
        getAllContentControls();   
       }); 
     }) 
      .catch(function (error) { 
       app.showNotification('Error: ' + JSON.stringify(error)); 
       if (error instanceof OfficeExtension.Error) { 
        app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo)); 
       } 
      }); 
    } 

// Using the Word JS API. Gets all of the content controls that are in the loaded document. 
function getAllContentControls() { 
    Word.run(function (context) { 

     var thisDocument = context.document; 

     var contentControls = thisDocument.contentControls; 

     contentControls.load('tag, title'); 

     return context.sync(contentControls).then(function() { 

      var uniqueFields = removeDuplicateContentControls(contentControls); 

      // Create HTML inputfields based on the content controls. 
      createFields(uniqueFields); 

     }) 
    }) 
     .catch(function (error) { 
      app.showNotification('Error: ' + JSON.stringify(error)); 
      if (error instanceof OfficeExtension.Error) { 
       app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo)); 
      } 
     }); 
} 

// Using the Word JS API. Set the values from the INPUT elements into the associated 
// content controls to make the doc. 
function contentControlHandler() { 

    var entryFields = document.getElementById("entryFields").querySelectorAll("input"); 

    // Loading the contentcontrols again. 
    Word.run(function (context) { 

     // Create a proxy object for the document. 
     var thisDocument = context.document; 

     // Create a proxy object for the contentcontrol collection in the document. 
     var contentControls = thisDocument.contentControls; 

     // Queue a command to load the contentcontrols collection with the tag and title properties. 
     contentControls.load('tag, title'); 

     return context.sync() 
      .then(function() { 

       var i, j; 

       // Map each input element to the associated content control. 
       for (i = 0; i < entryFields.length; i++) { 
        for (j = 0; j < contentControls.items.length; j++) { 
         // Matching content control tag with the tag set as the id on each input element. 
         if (contentControls.items[j].tag === entryFields[i].id && entryFields[i].value != 0) { 
          contentControls.items[j].insertText(entryFields[i].value.trim(), Word.InsertLocation.replace) 
         } 
        } 
       } 
      }) 
      .then(context.sync); 

    }) 
     .catch(function (error) { 
      app.showNotification('Error: ' + JSON.stringify(error)); //console.log 
      if (error instanceof OfficeExtension.Error) { 
       app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo)); //console.log 
      } 
     }); 
} 

// Handles the doc selection in the add-in UI. Results in a call to the service to get 
// a docx file that contains a doc. The doc gets displayed in the Word UI. 
function selectDocumentHandler() { 

    // Form the URL to get the docx file. Need to remove the host information by slicing 
    // off the host information beginning at ?_host_Info. 
    var fileName = this.value; 
    var currentUrl = location.href.slice(0, location.href.indexOf('?')); 
    var getFileUrl = currentUrl + 'getfile?filename=' + fileName; 

    // Call the helper to get the selected file then insert the file into Word. 
    httpGetAsync(getFileUrl, function (response) { 
     displayContents(response); 
    }); 
} 

/* UI functions */ 

function getDocNames() { 

    // Form the URL to get the docx file list. Need to remove the host information by slicing 
    // off the host information beginning at ?_host_Info. 
    var currentUrl = location.href.slice(0, location.href.indexOf('?')); 
    var getFileNamesUrl = currentUrl + 'getfilenames'; 

    // Call the helper to get the file list and then create the dropdown listbox from the results. 
    httpGetAsync(getFileNamesUrl, function (rawResponse) { 

     // Helper that processes the response so that we have an array of filenames. 
     var response = processResponse(rawResponse); 

     // Get a handle on the empty drop down list box. 
     var select = document.getElementById("selectDocument"); 

     // Populate the drop down listbox.  
     for (var i = 0; i < response.length; i++) { 
      var opt = response[i]; 
      var el = document.createElement("option"); 
      el.text = opt; 
      el.value = opt; 
      select.appendChild(el); 
     }; 

     //$(".ms-Dropdown").Dropdown(); 
    }); 
} 

// Creates HTML inputfields 
function createFields(uniqueFields) { 

    // Get the DIV where we will add out INPUT-controls. 
    var entryFields = document.getElementById("entryFields"); 

    // Clear the contents in case it has already been populated with INPUT controls. 
    while (entryFields.hasChildNodes()) { 
     entryFields.removeChild(entryFields.lastChild); 
    } 

    // Create a unique INPUT element for each unique contentcontrol-tag. 
    for (var i = 0; i < uniqueFields.length; i++) { 

     var newLabel = document.createElement("label"); 
     newLabel.appendChild(document.createTextNode(uniqueFields[i].title + ': ')); 
     document.getElementById('entryFields').appendChild(newLabel); 

     var input = document.createElement("input"); 

     newLabel.className = 'ms-label'; 

     input.type = "text"; 

     input.id = uniqueFields[i].tag; 

     input.className = 'ms-TextField-field'; 

     entryFields.appendChild(input); //, input.value 

     entryFields.appendChild(document.createElement("br")); 

    } 

} 

// Get data from AAD and displays user information 
function getDataFromSelection() { 
    var baseEndpoint = 'https://graph.microsoft.com'; 
    var authContext = new AuthenticationContext(config); 

    Office.context.document.getSelectedDataAsync(Office.CoercionType.Text, 
     function (result) { 
      if (result.status === Office.AsyncResultStatus.Succeeded) { 

       authContext.acquireToken(baseEndpoint, function (error, token) { 
        if (error || !token) { 
         app.showNotification("Ingen token: ", "Du får logga in igen."); // + error 
        } 
        var email = authContext._user.userName; 
        var url = "https://graph.microsoft.com/v1.0/" + config.tenant + "https://stackoverflow.com/users/" + email; 

        var html = "<ul>"; 
        $.ajax({ 
         beforeSend: function (request) { 
          request.setRequestHeader("Accept", "application/json"); 
         }, 
         type: "GET", 
         url: url, 
         dataType: "json", 
         headers: { 
          'Authorization': 'Bearer ' + token, 
         }, 
         success: function (response) { 
          console.log('Hämtar inehåll och populerar Kontroller!'); 
          //utilize your callback function 
          postDataToContentControlers(response); 
         } 
        }).done(function (response) { 
         html += getPropertyHtml("Namn", response.displayName); 
         html += getPropertyHtml("Titel", response.jobTitle); 
         html += getPropertyHtml("Avdelning", response.officeLocation); 
         html += getPropertyHtml("Telefon jobb", response.businessPhones); 
         $("#results").html(html); 
        }).fail(function (response) { 
         app.showNotification('Inloggningen slutade att fungera!', 'Du får logga ut och prova att logga in igen'); //response.responseText 
        }); 
       }); 
      } else { 
       app.showNotification('Error:', 'Något gick fel. Du får logga in igen.'); //result.error.message 
      } 
     } 
    ); 
} 

function getPropertyHtml(key, value) { 
    return "<li><strong>" + key + "</strong> : " + value + "</li>"; 
} 

function postDataToContentControlers(response) { 
    // Loading the contentcontrols again. 
    Word.run(function (context) { 

     // Create a proxy object for the document. 
     var thisDocument = context.document; 

     // Create a proxy object for the contentcontrol collection in the document. 
     var contentControls = thisDocument.contentControls; 

     // Queue a command to load the contentcontrols collection with the tag and title properties. 
     contentControls.load('tag, title'); 

     return context.sync() 
      .then(function() { 

       var i, j; 

       var responseArrayKey = Object.keys(response).map(function (v) { return v }); 

       // Map each data element to the associated content control. 
       for (i = 0; i < responseArrayKey.length; i++) { 

        for (j = 0; j < contentControls.items.length; j++) { 

         console.log("responseArrayKey: ", responseArrayKey); 
         // Matching content control tag with the index of each responseArray. 
         if (contentControls.items[j].tag === responseArrayKey[i]) { 

          var responseArrayValue = Object.keys(response).map(function (k) { return response[k] }); 

          contentControls.items[j].insertText(responseArrayValue[i], Word.InsertLocation.replace) 

         } 
        } 
       } 
      }) 
      .then(context.sync); 
    }) 
     .catch(function (error) { 
      app.showNotification('Error: ' + JSON.stringify(error)); //console.log 
      if (error instanceof OfficeExtension.Error) { 
       app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo)); //console.log 
      } 
     }); 
} 

/* Helper functions */ 

// Helper that deduplicates the set of contentcontrols. 
function removeDuplicateContentControls(contentControls) { 

    var i, 
     len = contentControls.items.length, 
     uniqueFields = [], 
     currentContentControl = {}; 

    for (i = 0; i < len; i++) { 
     currentContentControl[contentControls.items[i].tag] = contentControls.items[i].title; 
    } 

    for (i in currentContentControl) { 

     var obj = { 
      tag: i, 
      title: currentContentControl[i] 
     }; 

     uniqueFields.push(obj); 
    } 

    return uniqueFields; 
} 

// Helper for calls to the service. 
function httpGetAsync(theUrl, callback) { 
    var request = new XMLHttpRequest(); 
    request.open("GET", theUrl, false); 
    request.onreadystatechange = function() { 
     if (request.readyState === 4 && request.status === 200) 
      callback(request.responseText); 
    } 
    request.send(null); 
} 

    // Function for getting the HeaderTemplate 

    function getHeaderTemplate(fileName) { 

    var myOOXMLRequest = new XMLHttpRequest(); 

    var myXML; 

    myOOXMLRequest.open('GET', fileName, false); 

    myOOXMLRequest.send(); 

    if (myOOXMLRequest.status === 200) { 

     myXML = myOOXMLRequest.responseText; 
     return myXML; 
    } 

    return ""; 
} 

// Helper that processes file names into an array. 
function processResponse(rawResponse) { 

    // Remove quotes. 
    rawResponse = rawResponse.replace(/"/g, ""); 

    // Remove opening brackets. 
    rawResponse = rawResponse.replace("[", ""); 

    // Remove closing brackets. 
    rawResponse = rawResponse.replace("]", ""); 

    // Return an array of file names. 
    return rawResponse.split(','); 
} 

// Helper function for treating errors 
function errorHandler(error) { 
    showNotification(error, JSON.stringify(error.debugInfo)); 
    console.log("Error: " + error); 
    if (error instanceof OfficeExtension.Error) { 
     console.log("Debug info: " + JSON.stringify(error.debugInfo)); 
    } 
} 

function validateFields() { 
    //TODO: validating fields 
    console.log('Validating fields'); 
} 

})(); 

Inhalt von index.html

Inhalt des manifest

die Dokumentation Erste mit NodeJS behandelt

Hoffe jemand hat eine Antwort auf das Problem. Danke =)

+1

Können Sie den von Ihnen verwendeten Code angeben? –

+0

Ich habe es mit etwas Code bearbeitet, nur im selben Moment, in dem Sie geantwortet haben. Nun Ich habe in einigen mehr =) – MangeD66

Antwort

0

Ich bin ein Ingenieur von MS arbeiten an Word Rich APIs.

Und ich habe Ihren Skriptcode in displayContents versucht. Wie Sie oben gesagt haben, würde das Skript hier body.clear() aufrufen, bevor die Datei geladen wird (Aufruf von insertFileFromBase64). Die Operation body.clear() ist in Word online nicht erlaubt.

Ich denke, dass es einige Inhalte geben kann, die online nicht unterstützt werden, wie Feldbereich, Inhaltskontrolle für Tabellenzeilen.

Wenn Sie die von Ihnen verwendete docx-Datei bereitstellen können, wäre es besser für uns, diese Meinung zu bestätigen und die Ursache zu finden.

+0

[link] (https://mdproduktion.se/codeandstuff/mainTemplate.docx) – MangeD66

+0

Klick den Link oben =) – MangeD66

0

Vielen Dank für die Bereitstellung der docx-Datei.

Das 'Tab' vor dem Inhaltssteuerelement im Textkörper wird nicht unterstützt und die Inhaltssteuerung wird nicht unterstützt. Daher ist body.clear() nicht erlaubt, da innen etwas nicht unterstützt wird.

Ich empfehle Ihnen, die 'Tab' im lokalen Wordclient zu löschen und die docx-Datei online zu laden. Body.clear() würde auf diese Weise gut funktionieren.

PS: Mit Paragraph-Center kann das Inhaltskontrollzentrum ausgerichtet werden.

+0

Dank @Jiajia Seine Arbeit besser, aber ich habe tatsächlich die Vorlage ein ändern Bit - immer noch das ContentControl direkt unter der Überschrift. Jetzt mache ich InsertOoxml für die Kopf- und Fußzeile. Ich werde den Code später anpassen, damit Sie sehen können. Der Fehler, den ich jetzt bekomme, ist: Debug-Info: {"code": "NotAllowed", "message": "Die Aktion wird nicht mit Word Online unterstützt. Überprüfen Sie OfficeExtension.Error.debugInfo für weitere Informationen.", "ErrorLocation": „Body.insertOoxml. Dies ist, wenn i anklicken Another docx-Datei auszuwählen. – MangeD66

+0

Und wenn es um die doc-Dateien. es gibt 5 verschiedene Dateien, die jetzt nur noch die Content an der Spitze haben, knapp Header. hat jeden anderen Text natürlich. Vorher, wenn ich imagelogo und Text in der Spitze hatte, wäre es normalerweise nicht in Word online sichtbar. Gleich wie Fußzeile, und die contentControls würde nicht auftauchen oder die InputFields befüllen. – MangeD66

+0

Jetzt weiß ich, dass die Fußzeile oder die header.xml:.. s filecontent das Problem verursacht die 7 contentControls in der Fußzeile oder Bild und Text in dem Kopf ich extrahieren Sie die XML-Daten mit Word-Add-in-Get-Set-EditOpen-XML-Master-Addin von dev Büro. Vielleicht muss ich die Dateien ein wenig pollen? Wie ich weiß? Ich habe nur den Inhalt der XML-Dateien ersetzt h xml Beispiele von Dev Office, die funktionieren sollten - und sie tun. Die einzige Sache, die nicht funktioniert, ist, wenn Sie den Text in der 1 contentController ändern möchten, die ich verlassen habe. Wenn ich auf die Schaltfläche anklicken es nur eine savingproccess des Dokuments beginnt ... – MangeD66

Verwandte Themen