2016-09-14 11 views
1

Office Javascript APIを使用して、Angularを使用してWord用アドインを作成しています。バイト配列出力をBlobに変換するファイル

私は、APIを介してWord文書を取得し、それをファイルに変換し、POST経由でサーバにアップロードしたいと考えています。

私が使用していたコードは、Microsoftがこのユースケースのために提供するドキュメントコードとほぼ同じです:https://dev.office.com/reference/add-ins/shared/document.getfileasync#example---get-a-document-in-office-open-xml-compressed-format

サーバーのエンドポイントは、マルチパートフォームをPOSTするためのアップロードが必要ですので、私は上のいるFormDataオブジェクトを作成します私は$ http呼び出しを作成するときに、ファイル(blob)といくつかのメタデータを追加します。

ファイルはサーバーに送信されていますが、ファイルを開くと破損し、Wordで開くことができません。

ドキュメントによれば、Office.context.document.getFileAsync関数はバイト配列を返します。ただし、結果のfileContent変数は文字列です。私はconsole.logにこの文字列を圧縮データと思われるようにする必要があります。

文字列をBlobに変換する前にいくつかの前処理を行う必要があります。しかし、どの前処理ですか? atobによるBase64エンコーディングは何もしていないようです。

   let sendFile = (fileContent) => { 

        let blob = new Blob([fileContent], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }), 
         fd = new FormData(); 

        blob.lastModifiedDate = new Date(); 

        fd.append('file', blob, 'uploaded_file_test403.docx'); 
        fd.append('case_id', caseIdReducer.data()); 

        $http.post('/file/create', fd, { 
         transformRequest: angular.identity, 
         headers: { 'Content-Type': undefined } 
        }) 
        .success(() => { 

         console.log('upload succeeded'); 

        }) 
        .error(() => { 
         console.log('upload failed'); 
        }); 

       }; 


       function onGotAllSlices(docdataSlices) { 

        let docdata = []; 

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

        let fileContent = new String(); 

        for (let j = 0; j < docdata.length; j++) { 
         fileContent += String.fromCharCode(docdata[j]); 
        } 

        // Now all the file content is stored in 'fileContent' variable, 
        // you can do something with it, such as print, fax... 

        sendFile(fileContent); 

       } 

       function 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(); 

           onGotAllSlices(docdataSlices); 

          } else { 
           getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived); 
          } 
         } else { 

          gotAllSlices = false; 
          file.closeAsync(); 
          console.log(`getSliceAsync Error: ${sliceResult.error.message}`); 
         } 
        }); 
       } 

       // User clicks button to start document retrieval from Word and uploading to server process 
       ctrl.handleClick = () => { 

        Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 /*64 KB*/ }, 
         (result) => { 
          if (result.status === 'succeeded') { 

           // If the getFileAsync call succeeded, then 
           // result.value will return a valid File Object. 
           let myFile = result.value, 
            sliceCount = myFile.sliceCount, 
            slicesReceived = 0, gotAllSlices = true, docdataSlices = []; 

           // Get the file slices. 
           getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived); 

          } else { 

           console.log(`Error: ${result.error.message}`); 

          } 
         } 
        ); 
       }; 

答えて

1

私は含むFileContent文字列でこれをやってしまった:

let bytes = new Uint8Array(fileContent.length); 

for (let i = 0; i < bytes.length; i++) { 
    bytes[i] = fileContent.charCodeAt(i); 
} 

私は、これらのバイトでブロブを構築するために進ん:私は、その後、POSTリクエスト経由番目にこれを送信する場合

let blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); 

電子ファイルは変換されず、Wordで正しく開くことができます。

私はまだこれをより簡単で少ないステップで達成できると感じています。誰かがより良い解決策を持っているなら、私は非常に興味があるでしょう。

0

Pff! Fileのインスタンスを取得し、FileReader APIを使用していないと何が問題になりますか?マイクロソフトよ!

あなたはJavaScriptで文字列にバイナリ・ブロブを回して、バイト配列を取得し、ブロブコンストラクタにそれを投げるべきことは、「範囲外」エラーや不正なコード化につながることは悪い考えである

だけチャンクがtyped arraysのインスタンスまたはBLOB /ファイルのインスタンスである場合は、この

var byteArray = new Uint8Array(3) 
byteArray[0] = 97 
byteArray[1] = 98 
byteArray[2] = 99 
new Blob([byteArray]) 

と一緒に何かをします。その場合には、あなたがやるだけのことができます:

blob = new Blob([blob, chunk]) 

そして...ないbase64でエンコードをしてくださいそれ(〜3倍大きい方+遅い)

+0

>> Pff! Fileのインスタンスを取得し、FileReader APIを使用していないと何が問題になりますか?マイクロソフトよ! 私はそれを知っていない...非常に混乱しています。 Uint8Arrayを作成すると、スライスをどこに入力しますか? – Squrler

0

thx、答えはUint8Arrayでした。文字列を作成しないように少し改良しました。

let bytes = new Uint8Array(docdata.length); 
for (var i = 0; i < docdata.length; i++) { 
    bytes[i] = docdata[i]; 
} 
関連する問題