728x90
서버에서 받아온 바이너리 파일을 다시 파일 데이터로 변환하는 방법입니다. 일전에 파일을 바이너리 타입으로 변환해 DB에 저장한 상태라고 가정하겠습니다. 추가적으로, 복수의 파일을 다운로드할 경우에는 zip 형태의 파일로 저장하게끔 하는 요청사항이 있다고 간주해보겠습니다.
const result = (await axios.get(url)).data;
const blobData = result.blob;
const extension = result.type;
let fileType = getFileType(extension);
File 타입 지정
- 바이너리 데이터를 다시 파일로 변환하기 위해서는 파일의 확장자에 따라 다른 파일 타입을 지정해주어야 한다. 저는 주로 MS Office에서 다뤄지는 확장자들(특히 파워포인트와 엑셀)로 구성된 파일들을 다루었으므로 더 다양한 타입은 추가적으로 알아보시기를 바랍니다.
- 일반 텍스트 파일인 경우: 'text/plain'
- 파워포인트 파일(확장자가 ppt인 경우): 'application/vnd.ms-powerpoint'
- 파워포인트 파일(확장자가 pptx인 경우): 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
- 엑셀 파일(확장자가 xlx 또는 xlxs인 경우): 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
function getfileType(extension) {
let type = "";
if (extension === "text" || extension === "txt") {
type = 'text/plain';
} else if (extension === "ppt") {
type = 'application/vnd.ms-powerpoint'
} else if ( extension === "pptx") {
type = 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
} else if (extension.indexOf("xlx") !== -1 || extension === "xlxs") {
type = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
}
return type;
}
Base64 인코딩이 되어있는 경우 디코딩
Base64 (en-US) 인코딩된 문자열 데이터를 디코딩해주는 함수로, 파일 저장시 Base64로 인코딩한 경우에 사용합니다.
atob()를 통해 base64 디코딩한 문자열을 인자로 삼아 Uint8Array 객체를 생성합니다. 이 때 문자열은 모두 아스키코드로 되어있다고 간주하기 때문에(이전 글 참고) 배열 요소를 모두 ‘ASCII 코드 → 문자’로 바꾸어 줍니다.
const arr = Uint8Array.from(atob(blobData), c => c.charCodeAt(0))
이제 유니코드 형태가 된 문자 배열을 인자로 blob을 생성합니다. 아래와 같은 형태로 생성할 수 있습니다.
const blob = new Blob([arr], { type: fileType });
다운로드하는 경우
여기서는 다운로드 되는 파일명에 다운로드하는 일자를 넣겠습니다.
let today = new Date();
let todayStr = today.getFullYear() + today.getMonth() + today.getDate();
변환된 blob 객체를 인자로 삼아 이를 가르키는 url을 만들어 이를 다운로드하는 HTML <a>를 생성합니다.
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName + '_' + todayStr;
a.click();
a.remove();
window.URL.revokeObjectURL(url);
Zip 파일로 생성하는 경우
zip파일을 생성하기 위해서는 javascript 기반의 zip 라이브러리인 JSZip을 사용합니다.
let zip = new JSZip();
for (let i = 0; i < files.length; i++) {
const utf8Encode = new TextEncoder();
let uint8Array = utf8Encode.encode(files[i].blob);
zip.file(files[i].name, uint8Array);
}
zip.generateAsync({type: 'blob'}).then(
function(blob) {
const zipName = todayStr + '.zip';
saveToFile_Chrome(zipName, blob);
}
)
function saveToFile_Chrome(fileName, data) {
const blob = new Blob([data], { type: 'application/octet-stream' });
const objURL = window.URL.createObjectURL(blob);
if (window.__Xr_objURL_forCreatingFile__) {
window.URL.revokeObjectURL(window.__Xr_objURL_forCreatingFile__);
}
window.__Xr_objURL_forCreatingFile__ = objURL;
const a = document.createElement('a');
a.download = fileName;
a.href = objURL;
a.click();
}
- window.URL.revokeObjectURL: 앞서 URL.createObjectURL()를 통해 생성한 객체 URL을 해제합니다.
- zip 파일로 다운로드할 때에는 파일 타입은 'application/octet-stream'여야 합니다.
반응형
'Frontend > Javascript' 카테고리의 다른 글
JavaScript) async 함수가 비동기적으로 값을 반환하도록 하기 (0) | 2023.05.11 |
---|---|
Javascript) File 변환 - 1. File을 바이너리 타입으로 변환하기(+ Base64란?) (0) | 2023.03.19 |
Javascript) 배열(Array)의 중복 제거 (0) | 2022.11.18 |
Javascript) JqGrid custom edittype 사용하기 (0) | 2022.10.20 |
Javascript) draggable한 element를 드래그 시 화면 일부가 하얗게 변하는 현상 해결방법(Chrome 버전 106) (0) | 2022.10.13 |