将 pdf 从 Django 后端传递到 Angular 前端

时间:2021-05-31 14:20:21

标签: django angular pdf django-rest-framework httpresponse

我一直无法为类似问题制定任何解决方案适用于我的案例。 我想使用 django 从文件系统加载 pdf 并通过对 Angular 的 API 调用将其返回,以便可以显示它。我的 Django 代码差不多:

class LoadPdfViewSet(views.APIView):
    def get(self, request):
        # some code here here
        response = FileResponse(open(path_to_pdf, 'rb').read())
        response.headers = {   
            'Content-Type': 'application/pdf',
            'Content-Disposition': 'attachment;filename="report.pdf"',
        }
        response.as_attachment = True
        return response

在 Angular 方面,我有一个服务可以做到这一点:

export class LoadPdfService {
    constructor(
        private http: HttpClient
    ) {}

    getPdf(): Observable<Blob> {
        const params = new HttpParams({
            fromObject: { 
                responsetype: 'arraybuffer' 
                // other stuff here
            }
        })
        return self.http.get<Blob>(loadpdf_api_url, {params}).pipe(catchError(self.myErrorHandler))
    }
}

以及一个尝试像这样打开 pdf 的组件:

export class MyComponent {
    constructor(
        public loadPdfService: LoadPdfService
    ) {}

    download_pdf() {
        let call = self.loadPdfService.getPdf();
        call.subscribe( (response:Blob) => {
            if (window.navigator && window.navigator.msSaveOrOpenBlob) { // for IE
                window.navigator.msSaveOrOpenBlob(blob, "report.pdf");
            } else {
                let pdfUrl = URL.createObjectURL(blob)
                window.open(pdfUrl, '_blank')
                URL.revokeObjectURL(pdfUrl);    
            }            
        }
    }
}

但没有任何反应。我还尝试在 django 端使用不同的响应和直通渲染器,以及 Observable<Response>.then() 回调如

response.arrayBuffer().then(buffer => new Blob([buffer], {type: 'application/pdf'}))

在 Angular 一侧。有时我设法打开新窗口/选项卡,但无法显示 pdf。

1 个答案:

答案 0 :(得分:0)

我终于明白了。在python部分,可以毫无问题地删除read()。问题在于服务响应类型和响应映射:

getPdf(): Observable<Blob> {
    const options = {
        params: new HttpParams({
            fromObject: {
                // my own parameters here
            }
        }),
        responseType: 'blob' as 'json'
    };

    return this.http.get(this.url, options).pipe(
        map(response => response as Blob),
        catchError(this.myErrorHandler))
}