0

サーバーで生成されたスプレッドシートをダウンロードしようとしています。

私のアプリケーションは、フロントエンドで Angular を使用し、バックエンドで Java を使用しています。

ファイルを生成して返すリクエストを受け取るバックエンドのメソッドは次のとおりです。

@RequestMapping(value = "download", method = RequestMethod.GET, produces = "application/xls")
public ResponseEntity<InputStreamResource> download() throws IOException {
    ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
    HSSFWorkbook workbook = new HSSFWorkbook();
    HSSFSheet worksheet = workbook.createSheet("POI Worksheet");

    HSSFRow row1 = worksheet.createRow((short) 0);

    HSSFCell cellA1 = row1.createCell((short) 0);
    cellA1.setCellValue("Hello!");
    HSSFCellStyle cellStyle = workbook.createCellStyle();
    cellStyle.setFillForegroundColor(HSSFColor.GOLD.index);
    cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    cellA1.setCellStyle(cellStyle);

    workbook.write(fileOut);
    fileOut.close();

    byte[] file = fileOut.toByteArray();

    return ResponseEntity
            .ok()
            .contentLength(file.length)
            .contentType(MediaType.parseMediaType("application/octet-stream"))
            .body(new InputStreamResource(new ByteArrayInputStream(file)));
}

フロントエンドでは、ユーザーが [ダウンロード] ボタンをクリックすると、次の関数が実行されます。

$scope.exportFile = function() {
    $http.get('http://127.0.0.1:8000/api/excel/download')
        .success(function (data, status, headers, config) {
            var anchor = angular.element('<a/>');
            anchor.attr({
                href: 'data:application/octet-stream;charset=utf-8,' + encodeURI(data),
                target: '_blank',
                download: 'spreadsheet.xls'
            })[0].click();
        })
        .error(function (data, status, headers, config) {
            // handle error
        });
};

返されたスプレッドシートには判読できない文字が含まれています。

http://127.0.0.1:8000/api/excel/downloadに直接アクセスすると、スプレッドシートは .xls 拡張子なしで (拡張子なしで) ダウンロードされます。拡張子 .xls を追加してファイルの名前を変更してから開くと、ファイルの内容を確認できます。したがって、Javaでファイルを生成するのではなく、Angularがバックエンドで行う呼び出しに問題があると思います。

誰かがこの状況を経験したことがありますか、または共有する例がありますか? 私は何を間違っていますか?

4

1 に答える 1

0

ヘッダーはContent-Dispositionトリックを行う必要があります。したがって、次のようなものになります。

HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("Attachment", "spreadsheet.xls");
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(file.length);

return new ResponseEntity<InputStreamResource>(
           new InputStreamResource(new ByteArrayInputStream(file)),
           headers, HttpStatus.OK);
于 2016-03-09T15:57:14.400 に答える