programing

AngularJS $http-post - 이진 파일을 Excel 파일로 변환하여 다운로드

i4 2023. 4. 1. 08:27
반응형

AngularJS $http-post - 이진 파일을 Excel 파일로 변환하여 다운로드

저는 Angular JS에서 $http post를 통해 Excel 워크북을 다운로드하는 애플리케이션을 만들었습니다.

아래 코드는 JSON 형식으로 정보를 전달하고 각진 $http 포스트를 통해 서버 REST 웹 서비스(java)로 전송합니다.웹 서비스는 JSON의 정보를 사용하여 Excel 워크북을 생성합니다.$http post의 성공 본문 내의 응답에서는 해당 데이터 변수 내의 바이너리 데이터를 취득하고 있습니다만, 그것을 변환하여 엑셀 파일로 다운로드하는 방법을 모릅니다.

이 바이너리를 엑셀 파일로 변환하여 다운로드 할 수 있는 방법을 가르쳐 주실 수 있습니까?

제 코드는 다음과 같습니다.

$http({
        url: 'myweb.com/myrestService',
        method: "POST",
        data: json, //this is your json data string
        headers: {
           'Content-type': 'application/json'
        }
    }).success(function (data, status, headers, config) {

        // Here i'm getting excel sheet binary datas in 'data' 

    }).error(function (data, status, headers, config) {

    });

IE8/9 때문에 사용할 수 없다는 것을 방금 알았습니다만, 어쨌든 제출을 푸시하겠습니다.어쩌면 그것이 유용하다고 생각할지도 모른다

할 수 .blob 「 」에해 주세요.responseType 도 ★★★★★★★★★★★★★★★★★ 。success★★★★★★ 。

$http({
    url: 'your/webservice',
    method: "POST",
    data: json, //this is your json data string
    headers: {
       'Content-type': 'application/json'
    },
    responseType: 'arraybuffer'
}).success(function (data, status, headers, config) {
    var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
    var objectUrl = URL.createObjectURL(blob);
    window.open(objectUrl);
}).error(function (data, status, headers, config) {
    //upload failed
});

다음과 같은 문제가 몇 가지 있습니다.

  1. IE 8 및 9는 지원되지 않습니다.
  2. " " " 가 .objectUrl이 도 있는 것
  3. 이상한 파일 이름을 생성합니다.

성공했어!

블롭이것을 테스트한 PHP의 서버측 코드는 다음과 같습니다.Java ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」

$file = "file.xlsx";
header('Content-disposition: attachment; filename='.$file);
header('Content-Length: ' . filesize($file));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
echo json_encode(readfile($file));

2016.04.01 편집

브라우저는 이러한 방식으로 데이터를 저장하는 것을 더 어렵게 만들고 있습니다.하나의 좋은 옵션은 filesaver.js를 사용하는 것입니다.크로스 브라우저 실장을 제공합니다.saveAs 이 해 줄 거예요.success상기의 약속.

방법은 다음과 같습니다.

  1. IE8/IE9은 잊어버리세요.노력할 가치도 없고 돈도 갚지 않습니다.
  2. 올바른 HTTP 헤더를 사용해야 합니다. Accept를 사용하여 'application/vnd.openxml formats-officedocument.spreadsheetml'을 사용합니다.sheet' 및 responseType을 'arraybuffer'(ArrayBuffer, 단 소문자로 설정)로 설정해야 합니다.
  3. HTML5 saveAs는 실제 데이터를 원하는 형식으로 저장하는 데 사용됩니다.이 경우 유형을 추가하지 않아도 계속 작동합니다.
$http({
    url: 'your/webservice',
    method: 'POST',
    responseType: 'arraybuffer',
    data: json, //this is your json data string
    headers: {
        'Content-type': 'application/json',
        'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    }
}).success(function(data){
    var blob = new Blob([data], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    });
    saveAs(blob, 'File_Name_With_Some_Unique_Id_Time' + '.xlsx');
}).error(function(){
    //Some error log
});

팁! "와 "를 혼용하지 말고 항상 "를 사용해야 합니다. 프로페셔널 환경에서는 js 검증(예: jshint)을 통과해야 합니다. ==가 아닌 ===를 사용하는 경우에도 마찬가지입니다. 그러나 이는 다른 주제입니다.

save excel을 다른 서비스에 넣기 때문에, 당신은 깨끗한 구조를 가지고 있고, 포스트도 적절한 서비스를 받을 수 있습니다.내 예제가 제대로 작동하지 않으면 JS 바이올린을 만들어 줄 수 있어요.그리고 당신이 완전한 예시로 사용하는 json 데이터도 필요합니다.

해피 코딩..에두아르도

서버 응답을 어레이 버퍼로 다운로드합니다. 「BLOB」가 을합니다(BLOB:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

var httpPromise = this.$http.post(server, postData, { responseType: 'arraybuffer' });
httpPromise.then(response => this.save(new Blob([response.data],
    { type: response.headers('Content-Type') }), fileName));

BLOB를 사용자의 디바이스에 저장합니다.

save(blob, fileName) {
    if (window.navigator.msSaveOrOpenBlob) { // For IE:
        navigator.msSaveBlob(blob, fileName);
    } else { // For other browsers:
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = fileName;
        link.click();
        window.URL.revokeObjectURL(link.href);
    }
}

나에게 효과가 있었다-

$scope.downloadFile = function () {
        Resource.downloadFile().then(function (response) {
            var blob = new Blob([response.data], { type: "application/pdf" });
            var objectUrl = URL.createObjectURL(blob);
            window.open(objectUrl);
        },
        function (error) {
            debugger;
        });
    };

리소스 팩토리에서 다음과 같은 호출을 받습니다.

  downloadFile: function () {
           var downloadRequst = {
                method: 'GET',
                url: 'http://localhost/api/downloadFile?fileId=dfckn4niudsifdh.pdf',
                headers: {
                    'Content-Type': "application/pdf",
                    'Accept': "application/pdf"
                },
                responseType: 'arraybuffer'
            }

            return $http(downloadRequst);
        }

API가 헤더 콘텐츠 유형도 설정했는지 확인하십시오.

        response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");

Javascript에서 브라우저로 다운로드 창을 띄울 수 있는 방법은 없습니다.유일한 방법은 브라우저에 파일을 스트리밍하는 URL로 브라우저를 리디렉션하는 것입니다.

REST 서비스를 수정할 수 있는 경우 POST 요청이 바이너리 파일이 아닌 해당 파일에 대한 URL로 응답하도록 변경하여 해결할 수 있습니다.그러면 바이너리 데이터 대신 Javascript로 URL을 얻을 수 있고 브라우저를 해당 URL로 리디렉션할 수 있습니다. 그러면 원래 페이지를 떠나지 않고 다운로드가 요구됩니다.

5번 답변은 나에게 효과가 있었다. 비슷한 문제에 직면한 개발자에게 제안하라.

//////////////////////////////////////////////////////////
//Server side 
//////////////////////////////////////////////////////////
imports ***
public class AgentExcelBuilder extends AbstractExcelView {

protected void buildExcelDocument(Map<String, Object> model,
            HSSFWorkbook workbook, HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        //poi code goes here ....

        response.setHeader("Cache-Control","must-revalidate");
        response.setHeader("Pragma", "public");
        response.setHeader("Content-Transfer-Encoding","binary");
        response.setHeader("Content-disposition", "attachment; filename=test.xls");

        OutputStream output = response.getOutputStream();

        workbook.write(output);
        System.out.println(workbook.getActiveSheetIndex());
        System.out.println(workbook.getNumberOfSheets());
        System.out.println(workbook.getNumberOfNames());
        output.flush();
        output.close(); 
}//method buildExcelDocument ENDS

//service.js at angular JS code
function getAgentInfoExcel(workgroup,callback){
        $http({
            url: CONTEXT_PATH+'/rest/getADInfoExcel',
            method: "POST",
            data: workgroup, //this is your json data string
            headers: {
               'Content-type': 'application/json'
            },
            responseType: 'arraybuffer'
        }).success(function (data, status, headers, config) {
            var blob = new Blob([data], {type: "application/vnd.ms-excel"});
            var objectUrl = URL.createObjectURL(blob);
            window.open(objectUrl);
        }).error(function (data, status, headers, config) {
            console.log('Failed to download Excel')
        });
    }
////////////////////////////////in .html 

<div class="form-group">`enter code here`
                                <a href="javascript:void(0)" class="fa fa-file-excel-o"
                                    ng-click="exportToExcel();"> Agent Export</a>
                            </div>

하다 $http를 사용할 필요도 없고, 추가 라이브러리도 필요하지 않으며, 어떤 브라우저에서도 작동해야 합니다.

페이지에 보이지 않는 폼을 배치하기만 하면 됩니다.

<form name="downloadForm" action="/MyApp/MyFiles/Download" method="post" target="_self">
    <input type="hidden" name="value1" value="{{ctrl.value1}}" />
    <input type="hidden" name="value2" value="{{ctrl.value2}}" />
</form>

그리고 이 코드를 각도 컨트롤러에 넣으세요.

ctrl.value1 = 'some value 1';  
ctrl.value2 = 'some value 2';  
$timeout(function () {
    $window.document.forms['downloadForm'].submit();
});

이app/ / MyApp / MyFiles / Download 。
Internet Explorer 10 서 internet internet internet internet 。

오브젝트를할 수는, 옵션이 .HTML 의 경우는, HTML 의 경우는, 2 개의 옵션이 있습니다.

중 합니다.1 . 오브젝트를 문자열화하여 폼필드 중 하나에 문자열로 입력합니다.

<input type="hidden" name="myObjJson" value="{{ctrl.myObj | json:0}}" />


2. HTML JSON 폼을 검토해 주십시오.https://www.w3.org/TR/html-json-forms/

나는 당신을 위해 이것을 해줄 서비스를 만들었다.

을 통과하다$http오브젝트 및 추가 파라미터를 추가합니다.

1) 'type' .검색할 파일 형식을 지정합니다.은 다음과 같습니다.'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
2) "fileName" 파라미터.이것은 필수이며 확장자를 포함해야 합니다.

예를 들어:

httpDownloader({
  method : 'POST',
  url : '--- enter the url that returns a file here ---',
  data : ifYouHaveDataEnterItHere,
  type : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // this is the default
  fileName : 'YourFileName.xlsx'
}).then(res => {}).catch(e => {});

그것만 있으면 돼팝업 없이 파일이 사용자의 장치에 다운로드됩니다.

여기 git repo: https://github.com/stephengardner/ngHttpDownloader

나도 같은 문제에 직면해 있었다.제가 어떻게 해결해서 여러분들이 원하는 걸 다 이루었는지 알려드릴게요.

요건:

  1. 파일(또는 생성된 메모리 스트림)에 대한 버튼(또는 링크)이 있어야 합니다.
  2. 버튼을 클릭하여 파일을 다운로드해야 합니다.

(Asp.net Web API를 사용하고 있는) 서비스에서는 컨트롤러가 "HttpResponseMessage"를 반환하고 있습니다.응답에 "Stream Content"를 추가합니다.내용 필드에서 헤더를 "application/octet-stream"으로 설정하고 데이터를 첨부 파일로 추가합니다."myAwesomeFile.xlsx"라는 이름도 붙였습니다.

response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(memStream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "myAwesomeFile.xlsx" };

자, 요령이 있습니다.;)

기본 URL을 "apiRoot"라는 Angular Value의 변수에 읽은 텍스트 파일에 저장합니다.이를 선언하고 다음과 같이 모듈의 "실행" 기능에 설정합니다.

app.value('apiRoot', { url: '' });
app.run(function ($http, apiRoot) {
    $http.get('/api.txt').success(function (data) {
        apiRoot.url = data;
    });
});

이렇게 하면 서버의 텍스트 파일에 URL을 설정할 수 있고 업로드 시 "블로우"를 걱정할 필요가 없습니다.(보안상의 이유로 나중에 언제든지 변경할 수 있습니다.이것에 의해, 개발의 불편이 해소됩니다).

이제 마법은 다음과 같습니다.

서비스 엔드포인트에 직접 접속하는 URL과 타겟이 "_blank"인 링크를 만드는 것 뿐입니다.

<a ng-href="{{vm.getFileHref(FileId)}}" target="_blank" class="btn btn-default">&nbsp;Excel File</a>

시크릿 소스는 href를 설정하는 기능입니다.준비됐어?

vm.getFileHref = function (Id) {
    return apiRoot.url + "/datafiles/excel/" + Id;
}

그래, 그거야.;)

다운로드해야 할 파일이 있는 많은 레코드에 대해 반복하는 경우에도 Id를 함수에 공급하기만 하면 해당 함수는 파일을 전달하는 서비스 엔드포인트에 URL을 생성합니다.

이게 도움이 됐으면 좋겠네요!

언급URL : https://stackoverflow.com/questions/22447952/angularjs-http-post-convert-binary-to-excel-file-and-download

반응형