Сохранение файла .docx или .ppt локально с использованием getFileAsync (fileType, options, callback) - PullRequest
0 голосов
/ 18 января 2019

Я создаю надстройку с помощью Common API for Office и пытаюсь реализовать функцию сохранения в надстройке. По сути, это означает, что я должен иметь возможность получить текущий документ (.docx или .ppt). Я попытался использовать getFileAsync(fileType, options, callback) с параметром 'filetype', установленным на Office.FileType.Compressed, но при загрузке файла я не могу открыть его как файл .docx или .ppt. Я использовал следующий код:

public getDocumentAsCompressed() {
    Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 /*64 KB*/ }, result => {
    if (result.status.toString() === 'succeeded') {
      // If the getFileAsync call succeeded, then
      // result.value will return a valid File Object.
      const myFile = result.value;
      const sliceCount = myFile.sliceCount;
      const slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
      console.log('File size:' + myFile.size + ' #Slices: ' + sliceCount);

      // Get the file slices.
      this.getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
    } else {
      console.log('Error:', result.error.message);
    }
  });
}

public getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
  file.getSliceAsync(nextSlice, sliceResult => {
  if (sliceResult.status === 'succeeded') {
    if (!gotAllSlices) { // Failed to get all slices, no need to continue.
      return;
    }

    // Got one slice, store it in a temporary array.
    // (Or you can do something else, such as
    // send it to a third-party server.)
    docdataSlices[sliceResult.value.index] = sliceResult.value.data;
    if (++slicesReceived === sliceCount) {
      // All slices have been received.
      file.closeAsync();
      this.onGotAllSlices(docdataSlices);
    } else {
      this.getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
    }
  } else {
    gotAllSlices = false;
    file.closeAsync();
    console.log('getSliceAsync Error:', sliceResult.error.message);
  }
  });
}

public onGotAllSlices(docdataSlices) {
    const blob = new Blob(docdataSlices);
    if (window.navigator.msSaveOrOpenBlob) {
      window.navigator.msSaveOrOpenBlob(blob, 'WordDownloadTest.docx');
    } else {
      const a = document.createElement('a'),
      url = URL.createObjectURL(blob);
      a.href = url;
      a.download = 'WordDownloadTest.docx';
      document.body.appendChild(a);
      a.click();
      setTimeout(function() {
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      }, 0);
    }
}

Как мне проанализировать результат, полученный в onGotAllSlices(docDataSlices), в действительный документ .docx или .ppt?

1 Ответ

0 голосов
/ 18 января 2019

Мне удалось исправить проблему сразу после публикации вопроса. Исправление состояло в том, чтобы создать новый UInt8Array, а затем создать новый BLOB-объект из этого UInt8Array. По сути, это означает, что последний метод становится:

public onGotAllSlices(docdataSlices) {
    let docdata = [];
    for (let i = 0; i < docdataSlices.length; i++) {
      docdata = docdata.concat(docdataSlices[i]);
    }

    const byteArray = new Uint8Array(docdata);

    const blob = new Blob([byteArray]);

    const a = document.createElement('a');
    url = URL.createObjectURL(blob);
    a.href = url;
    a.download = 'WordTest.docx';
    document.body.appendChild(a);
    a.click();
    setTimeout(function() {
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    }, 0);
}
...