Umwandlung byte-array Ausgabe in Blob-Datei korrumpiert
Ich bin mit dem Office-Javascript-API zum schreiben eines Add-in für Word verwenden Eckige.
Ich abrufen möchten, das Word-Dokument über die API, dann wandeln Sie es in eine Datei und laden Sie Sie per POST an einen server.
Den code, den ich verwende, ist fast identisch mit der Dokumentation von code, die Microsoft bietet für diesen Anwendungsfall: https://dev.office.com/reference/add-ins/shared/document.getfileasync#example---get-a-document-in-office-open-xml-compressed-format
Den server-Endpunkt erfordert uploads Gepostet werden, die durch eine multipart-form, so erstelle ich ein FormData Objekt, auf dem ich Anhängen der Datei (blob) sowie einige Metadaten, die beim erstellen der $http-Aufruf.
Die Datei wird auf den server übertragen, aber wenn ich es öffne, es ist beschädigt und kann nicht mehr geöffnet werden Word.
Laut der Dokumentation, die Office.Kontext.Dokument.getFileAsync Funktion liefert ein byte-array. Jedoch, die daraus resultierenden fileContent-variable ist ein string. Wenn ich console.melden Sie diese Zeichenfolge, es scheint, werden die komprimierten Daten, wie es sein sollte.
Meine Vermutung ist, die ich brauche, um einige der Vorverarbeitung, bevor Sie die Zeichenfolge in ein Blob. Aber die Vorverarbeitung? Base64-Codierung durch atob nicht zu sein scheinen etwas zu tun.
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}`);
}
}
);
};
Du musst angemeldet sein, um einen Kommentar abzugeben.
Landete ich dadurch mit string fileContent:
Ich dann gehen, um den Blob bauen mit diesen bytes:
Wenn ich dann senden Sie diese über eine POST-Anforderung, die Datei ist nicht entstellt und kann geöffnet werden korrekt von Word.
Ich noch das Gefühl hat, dies kann erreicht werden mit weniger Aufwand /weniger Schritte. Wenn jemand eine bessere Lösung, ich wäre sehr interessiert zu erfahren.
Sollten Sie die byte-array und werfen es in den blob-Konstruktor, drehen ein binary-blob-Zeichenfolge in javascript-eine schlechte Idee kann dazu führen, dass "out of range" Fehler oder falsche Codierung
nur etwas tun, zusammen mit diesem
wenn der chunk ist eine Instanz einer typisierte arrays oder eine Instanz der blob/file. in diesem Fall können Sie nur:
... Und bitte... nicht base64-codieren (~3x größer + langsamer)
thx für deine Antwort,
Uint8Array
war die Lösung. Nur eine kleine Verbesserung zu vermeiden, erstellen Sie die Zeichenfolge: